Esempio n. 1
0
        private unsafe void FillCountOfResultsAndIndexEtag(QueryResultServerSide <Document> resultToFill, QueryMetadata query, DocumentsOperationContext context)
        {
            var collection = query.CollectionName;
            var buffer     = stackalloc long[3];

            // If the query has include or load, it's too difficult to check the etags for just the included collections,
            // it's easier to just show etag for all docs instead.
            if (collection == Constants.Documents.Collections.AllDocumentsCollection ||
                query.HasIncludeOrLoad)
            {
                var numberOfDocuments = Database.DocumentsStorage.GetNumberOfDocuments(context);
                buffer[0] = DocumentsStorage.ReadLastDocumentEtag(context.Transaction.InnerTransaction);
                buffer[1] = DocumentsStorage.ReadLastTombstoneEtag(context.Transaction.InnerTransaction);
                buffer[2] = numberOfDocuments;
                resultToFill.TotalResults = (int)numberOfDocuments;
            }
            else
            {
                var collectionStats = Database.DocumentsStorage.GetCollection(collection, context);

                buffer[0] = Database.DocumentsStorage.GetLastDocumentEtag(context, collection);
                buffer[1] = Database.DocumentsStorage.GetLastTombstoneEtag(context, collection);
                buffer[2] = collectionStats.Count;
                resultToFill.TotalResults = (int)collectionStats.Count;
            }

            resultToFill.ResultEtag = (long)Hashing.XXHash64.Calculate((byte *)buffer, sizeof(long) * 3);
            resultToFill.NodeTag    = Database.ServerStore.NodeTag;
        }
 private static void FillDocumentsInfo(DatabaseStatusReport prevDatabaseReport, DocumentDatabase dbInstance, DatabaseStatusReport report,
                                       DocumentsOperationContext context, DocumentsStorage documentsStorage)
 {
     if (prevDatabaseReport?.LastTransactionId != null && prevDatabaseReport.LastTransactionId == dbInstance.LastTransactionId)
     {
         report.LastEtag             = prevDatabaseReport.LastEtag;
         report.LastTombstoneEtag    = prevDatabaseReport.LastTombstoneEtag;
         report.NumberOfConflicts    = prevDatabaseReport.NumberOfConflicts;
         report.NumberOfDocuments    = prevDatabaseReport.NumberOfDocuments;
         report.DatabaseChangeVector = prevDatabaseReport.DatabaseChangeVector;
     }
     else
     {
         using (var tx = context.OpenReadTransaction())
         {
             report.LastEtag             = DocumentsStorage.ReadLastEtag(tx.InnerTransaction);
             report.LastTombstoneEtag    = DocumentsStorage.ReadLastTombstoneEtag(tx.InnerTransaction);
             report.NumberOfConflicts    = documentsStorage.ConflictsStorage.ConflictsCount;
             report.NumberOfDocuments    = documentsStorage.GetNumberOfDocuments(context);
             report.DatabaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(context);
         }
     }
 }
Esempio n. 3
0
        private unsafe void FillCountOfResultsAndIndexEtag(QueryResultServerSide resultToFill, string collection, DocumentsOperationContext context)
        {
            var buffer = stackalloc long[3];

            if (collection == Constants.Documents.Collections.AllDocumentsCollection)
            {
                var numberOfDocuments = Database.DocumentsStorage.GetNumberOfDocuments(context);
                buffer[0] = DocumentsStorage.ReadLastDocumentEtag(context.Transaction.InnerTransaction);
                buffer[1] = DocumentsStorage.ReadLastTombstoneEtag(context.Transaction.InnerTransaction);
                buffer[2] = numberOfDocuments;
                resultToFill.TotalResults = (int)numberOfDocuments;
            }
            else
            {
                var collectionStats = Database.DocumentsStorage.GetCollection(collection, context);

                buffer[0] = Database.DocumentsStorage.GetLastDocumentEtag(context, collection);
                buffer[1] = Database.DocumentsStorage.GetLastTombstoneEtag(context, collection);
                buffer[2] = collectionStats.Count;
            }

            resultToFill.ResultEtag = (long)Hashing.XXHash64.Calculate((byte *)buffer, sizeof(long) * 3);
        }
Esempio n. 4
0
        private IEnumerable <(string name, DatabaseStatusReport report)> CollectDatabaseInformation(TransactionOperationContext ctx)
        {
            foreach (var dbName in _server.Cluster.GetDatabaseNames(ctx))
            {
                if (_token.IsCancellationRequested)
                {
                    yield break;
                }

                if (_server.DatabasesLandlord.DatabasesCache.TryGetValue(dbName, out var dbTask) == false)
                {
                    continue; // Database does not exists in this server
                }

                var report = new DatabaseStatusReport
                {
                    Name     = dbName,
                    NodeName = _server.NodeTag
                };

                if (dbTask.IsCanceled || dbTask.IsFaulted)
                {
                    report.Status = DatabaseStatus.Faulted;
                    report.Error  = dbTask.Exception.ToString();
                    yield return(dbName, report);

                    continue;
                }

                if (dbTask.IsCompleted == false)
                {
                    report.Status = DatabaseStatus.Loading;
                    yield return(dbName, report);

                    continue;
                }

                var dbInstance       = dbTask.Result;
                var documentsStorage = dbInstance.DocumentsStorage;
                var indexStorage     = dbInstance.IndexStore;

                if (dbInstance.DatabaseShutdown.IsCancellationRequested)
                {
                    report.Status = DatabaseStatus.Shutdown;
                    yield return(dbName, report);

                    continue;
                }

                report.Status = DatabaseStatus.Loaded;
                try
                {
                    using (documentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                        using (var tx = context.OpenReadTransaction())
                        {
                            report.LastEtag          = DocumentsStorage.ReadLastEtag(tx.InnerTransaction);
                            report.LastTombstoneEtag = DocumentsStorage.ReadLastTombstoneEtag(tx.InnerTransaction);
                            report.NumberOfConflicts = documentsStorage.ConflictsStorage.ConflictsCount;
                            report.NumberOfDocuments = documentsStorage.GetNumberOfDocuments(context);
                            report.LastChangeVector  = DocumentsStorage.GetDatabaseChangeVector(context);

                            if (indexStorage != null)
                            {
                                foreach (var index in indexStorage.GetIndexes())
                                {
                                    var stats = index.GetIndexStats(context);
                                    //We might have old version of this index with the same name
                                    report.LastIndexStats.Add(index.Name, new DatabaseStatusReport.ObservedIndexStatus
                                    {
                                        LastIndexedEtag = stats.LastProcessedEtag,
                                        IsSideBySide    = false, // TODO: fix this so it get whatever this has side by side or not
                                        IsStale         = stats.IsStale
                                    });
                                }
                            }
                        }
                }
                catch (Exception e)
                {
                    report.Error = e.ToString();
                }

                yield return(dbName, report);
            }
        }
Esempio n. 5
0
        private IEnumerable <(string name, DatabaseStatusReport report)> CollectDatabaseInformation(TransactionOperationContext ctx)
        {
            foreach (var dbName in _server.Cluster.GetDatabaseNames(ctx))
            {
                if (_token.IsCancellationRequested)
                {
                    yield break;
                }

                var report = new DatabaseStatusReport
                {
                    Name     = dbName,
                    NodeName = _server.NodeTag
                };

                if (_server.DatabasesLandlord.DatabasesCache.TryGetValue(dbName, out var dbTask) == false)
                {
                    var recorod = _server.Cluster.ReadDatabase(ctx, dbName);
                    if (recorod == null || recorod.Topology.RelevantFor(_server.NodeTag) == false)
                    {
                        continue; // Database does not exists in this server
                    }
                    report.Status = DatabaseStatus.Unloaded;
                    yield return(dbName, report);

                    continue;
                }

                if (dbTask.IsFaulted)
                {
                    var extractSingleInnerException = dbTask.Exception.ExtractSingleInnerException();
                    if (Equals(extractSingleInnerException.Data[DatabasesLandlord.DoNotRemove], true))
                    {
                        report.Status = DatabaseStatus.Unloaded;
                        yield return(dbName, report);

                        continue;
                    }
                }


                if (dbTask.IsCanceled || dbTask.IsFaulted)
                {
                    report.Status = DatabaseStatus.Faulted;
                    report.Error  = dbTask.Exception.ToString();
                    yield return(dbName, report);

                    continue;
                }

                if (dbTask.IsCompleted == false)
                {
                    report.Status = DatabaseStatus.Loading;
                    yield return(dbName, report);

                    continue;
                }

                var dbInstance       = dbTask.Result;
                var documentsStorage = dbInstance.DocumentsStorage;
                var indexStorage     = dbInstance.IndexStore;

                if (dbInstance.DatabaseShutdown.IsCancellationRequested)
                {
                    report.Status = DatabaseStatus.Shutdown;
                    yield return(dbName, report);

                    continue;
                }

                report.Status = DatabaseStatus.Loaded;
                try
                {
                    using (documentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                        using (var tx = context.OpenReadTransaction())
                        {
                            report.LastEtag             = DocumentsStorage.ReadLastEtag(tx.InnerTransaction);
                            report.LastTombstoneEtag    = DocumentsStorage.ReadLastTombstoneEtag(tx.InnerTransaction);
                            report.NumberOfConflicts    = documentsStorage.ConflictsStorage.ConflictsCount;
                            report.NumberOfDocuments    = documentsStorage.GetNumberOfDocuments(context);
                            report.DatabaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(context);
                            foreach (var outgoing in dbInstance.ReplicationLoader.OutgoingHandlers)
                            {
                                var node = outgoing.GetNode();
                                if (node != null)
                                {
                                    report.LastSentEtag.Add(node, outgoing._lastSentDocumentEtag);
                                }
                            }

                            if (indexStorage != null)
                            {
                                foreach (var index in indexStorage.GetIndexes())
                                {
                                    var stats = index.GetIndexStats(context);
                                    //We might have old version of this index with the same name
                                    report.LastIndexStats[index.Name] = new DatabaseStatusReport.ObservedIndexStatus
                                    {
                                        LastIndexedEtag = stats.LastProcessedEtag,
                                        IsSideBySide    = index.Name.StartsWith(Constants.Documents.Indexing.SideBySideIndexNamePrefix, StringComparison.OrdinalIgnoreCase),
                                        IsStale         = stats.IsStale,
                                        State           = index.State
                                    };
                                }
                            }
                        }
                }
                catch (Exception e)
                {
                    report.Error = e.ToString();
                }

                yield return(dbName, report);
            }
        }
Esempio n. 6
0
        private unsafe void FillCountOfResultsAndIndexEtag(QueryResultServerSide <Document> resultToFill, QueryMetadata query, DocumentsOperationContext context)
        {
            var bufferSize  = 3;
            var hasCounters = query.HasCounterSelect || query.CounterIncludes != null;

            if (hasCounters)
            {
                bufferSize++;
            }
            if (query.HasCmpXchgSelect)
            {
                bufferSize++;
            }

            var collection = query.CollectionName;
            var buffer     = stackalloc long[bufferSize];

            // If the query has include or load, it's too difficult to check the etags for just the included collections,
            // it's easier to just show etag for all docs instead.
            if (collection == Constants.Documents.Collections.AllDocumentsCollection ||
                query.HasIncludeOrLoad)
            {
                var numberOfDocuments = Database.DocumentsStorage.GetNumberOfDocuments(context);
                buffer[0] = DocumentsStorage.ReadLastDocumentEtag(context.Transaction.InnerTransaction);
                buffer[1] = DocumentsStorage.ReadLastTombstoneEtag(context.Transaction.InnerTransaction);
                buffer[2] = numberOfDocuments;

                if (hasCounters)
                {
                    buffer[3] = DocumentsStorage.ReadLastCountersEtag(context.Transaction.InnerTransaction);
                }

                resultToFill.TotalResults = (int)numberOfDocuments;
            }
            else
            {
                var collectionStats = Database.DocumentsStorage.GetCollection(collection, context);
                buffer[0] = Database.DocumentsStorage.GetLastDocumentEtag(context, collection);
                buffer[1] = Database.DocumentsStorage.GetLastTombstoneEtag(context, collection);
                buffer[2] = collectionStats.Count;

                if (hasCounters)
                {
                    buffer[3] = Database.DocumentsStorage.CountersStorage.GetLastCounterEtag(context, collection);
                }

                resultToFill.TotalResults = (int)collectionStats.Count;
            }

            if (query.HasCmpXchgSelect)
            {
                using (context.DocumentDatabase.ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext transactionContext))
                    using (transactionContext.OpenReadTransaction())
                    {
                        buffer[bufferSize - 1] = Database.ServerStore.Cluster.GetLastCompareExchangeIndexForDatabase(transactionContext, Database.Name);
                    }
            }

            resultToFill.ResultEtag = (long)Hashing.XXHash64.Calculate((byte *)buffer, sizeof(long) * (uint)bufferSize);
            resultToFill.NodeTag    = Database.ServerStore.NodeTag;
        }