public void First_index_corruption_should_not_error_it_immediately() { UseNewLocalServer(); using (var db = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }, db)) { PutUser(db); index._indexStorage.SimulateCorruption = true; index.Start(); // should unload db but not error the index Assert.True(SpinWait.SpinUntil(() => db.ServerStore.DatabasesLandlord.DatabasesCache.Any() == false, TimeSpan.FromMinutes(1))); Assert.Equal(IndexState.Normal, index.State); } } }
public void Three_consecutive_write_errors_should_error_index() { UseNewLocalServer(); using (var db = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }, db)) { PutUser(db); index._indexStorage.SimulateIndexWriteException = new FormatException(); index.Start(); Assert.True(SpinWait.SpinUntil(() => index.State == IndexState.Error, TimeSpan.FromMinutes(1))); } } }
public void Can_update_lock_mode_and_priority_of_index_even_if_indexing_is_running() { using (var database = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }, database)) { using (index._indexStorage._contextPool.AllocateOperationContext(out TransactionOperationContext context)) using (context.OpenWriteTransaction()) // open write tx to simulate running indexing batch { var task = Task.Factory.StartNew(() => { index.SetLock(IndexLockMode.LockedIgnore); index.SetPriority(IndexPriority.High); }, TaskCreationOptions.LongRunning); Assert.True(task.Wait(TimeSpan.FromMinutes(1))); } index.Start(); // will persist the introduced changes IndexDefinition persistedDef = null; for (int i = 0; i < 10; i++) { persistedDef = MapIndexDefinition.Load(index._indexStorage.Environment(), out var version); if (persistedDef.Priority == IndexPriority.High) { break; } Thread.Sleep(1000); } Assert.Equal(IndexLockMode.LockedIgnore, persistedDef.LockMode); Assert.Equal(IndexPriority.High, persistedDef.Priority); } } }
public void multi_map_index_with_load_document_to_same_collection() { using (var database = CreateDocumentDatabase()) using (var index = MapIndex.CreateNew(new IndexDefinition { Name = "Index", Maps = { @"from user in docs.Users select new { Name = LoadDocument(""shippers/1"", ""Shippers"").Name }", @"from product in docs.Products select new { Name = LoadDocument(""shippers/1"", ""Shippers"").Name }" }, Type = IndexType.Map }, database)) using (var contextPool = new TransactionContextPool(database.DocumentsStorage.Environment)) { new IndexStorage(index, contextPool, database); } }
public void ThreadUsage_WhenThreadsHaveSameCpuUsageAndTotalProcessorTime_ShouldListThemBoth() { using var database = CreateDocumentDatabase(); using var index1 = MapIndex.CreateNew(new IndexDefinition { Name = "Companies_ByName", Maps = { "from company in docs.Companies select new { company.Name }" }, }, database); using var index2 = MapIndex.CreateNew(new IndexDefinition { Name = "Users_ByName", Maps = { "from user in docs.Orders select new { user.Name }" }, }, database); using var index3 = MapIndex.CreateNew(new IndexDefinition { Name = "Orders_ByName", Maps = { "from order in docs.Orders select new { order.Name }" }, }, database); index1.Start(); index2.Start(); index3.Start(); for (int i = 0;; i++) { try { var threadsUsage = new ThreadsUsage(); var threadsInfo = threadsUsage.Calculate(); var threadNames = threadsInfo.List.Select(ti => ti.Name).OrderBy(n => n).ToArray(); RavenTestHelper.AssertAll(() => string.Join('\n', threadNames.Select(s => $"\"{s}\"")), () => AssertContains(index1._indexingThread.Name), () => AssertContains(index2._indexingThread.Name), () => AssertContains(index3._indexingThread.Name)); break; void AssertContains(string threadName) => Assert.True(threadNames.Contains(threadName), $"Not found : {threadName}"); } catch { if (i >= 5) { throw; } Thread.Sleep(100); } } }
public void Should_leave_low_memory_mode() { using (var database = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, }, database)) { index.SimulateLowMemory(); Assert.True(index.IsLowMemory); for (var i = 0; i < Raven.Server.Documents.Indexes.Index.LowMemoryPressure; i++) { index.LowMemoryOver(); } Assert.False(index.IsLowMemory); } } }
private Index ResetIndexInternal(Index index) { DeleteIndexInternal(index); var definitionBase = index.Definition; if (definitionBase is AutoMapIndexDefinition) { index = AutoMapIndex.CreateNew((AutoMapIndexDefinition)definitionBase, _documentDatabase); } else if (definitionBase is AutoMapReduceIndexDefinition) { index = AutoMapReduceIndex.CreateNew((AutoMapReduceIndexDefinition)definitionBase, _documentDatabase); } else { var staticIndexDefinition = index.Definition.ConvertToIndexDefinition(index); switch (staticIndexDefinition.Type) { case IndexType.Map: index = MapIndex.CreateNew(staticIndexDefinition, _documentDatabase); break; case IndexType.MapReduce: index = MapReduceIndex.CreateNew(staticIndexDefinition, _documentDatabase); break; default: throw new NotSupportedException($"Cannot create {staticIndexDefinition.Type} index from IndexDefinition"); } } CreateIndexInternal(index); return(index); }
public void NumberOfDocumentsAndTombstonesToProcessShouldBeCalculatedCorrectly() { using (var database = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(1, new IndexDefinition() { Name = "Index1", Maps = { "from doc in docs.Users select new { doc.Name }" }, Type = IndexType.Map }, database)) { using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { using (var doc = CreateDocument(context, "users/1", new DynamicJsonValue { ["Name"] = "John", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/1", null, doc); } using (var doc = CreateDocument(context, "users/2", new DynamicJsonValue { ["Name"] = "Bob", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/2", null, doc); } using (var doc = CreateDocument(context, "people/1", new DynamicJsonValue { ["Name"] = "Edward", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "People" } })) { database.DocumentsStorage.Put(context, "people/1", null, doc); } tx.Commit(); } IndexProgress progress; using (context.OpenReadTransaction()) { progress = index.GetProgress(context); } Assert.Equal(0, progress.Collections["Users"].LastProcessedDocumentEtag); Assert.Equal(0, progress.Collections["Users"].LastProcessedTombstoneEtag); Assert.Equal(2, progress.Collections["Users"].NumberOfDocumentsToProcess); Assert.Equal(0, progress.Collections["Users"].NumberOfTombstonesToProcess); Assert.Equal(2, progress.Collections["Users"].TotalNumberOfDocuments); Assert.Equal(0, progress.Collections["Users"].TotalNumberOfTombstones); var batchStats = new IndexingRunStats(); var scope = new IndexingStatsScope(batchStats); index.DoIndexingWork(scope, CancellationToken.None); using (context.OpenReadTransaction()) { progress = index.GetProgress(context); } Assert.Equal(2, progress.Collections["Users"].LastProcessedDocumentEtag); Assert.Equal(0, progress.Collections["Users"].LastProcessedTombstoneEtag); Assert.Equal(0, progress.Collections["Users"].NumberOfDocumentsToProcess); Assert.Equal(0, progress.Collections["Users"].NumberOfTombstonesToProcess); Assert.Equal(2, progress.Collections["Users"].TotalNumberOfDocuments); Assert.Equal(0, progress.Collections["Users"].TotalNumberOfTombstones); using (var tx = context.OpenWriteTransaction()) { database.DocumentsStorage.Delete(context, "users/1", null); using (var doc = CreateDocument(context, "users/3", new DynamicJsonValue { ["Name"] = "George", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/3", null, doc); } using (var doc = CreateDocument(context, "people/2", new DynamicJsonValue { ["Name"] = "Edward", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "People" } })) { database.DocumentsStorage.Put(context, "people/2", null, doc); } tx.Commit(); } using (context.OpenReadTransaction()) { progress = index.GetProgress(context); } Assert.Equal(2, progress.Collections["Users"].LastProcessedDocumentEtag); Assert.Equal(0, progress.Collections["Users"].LastProcessedTombstoneEtag); Assert.Equal(1, progress.Collections["Users"].NumberOfDocumentsToProcess); Assert.Equal(1, progress.Collections["Users"].NumberOfTombstonesToProcess); Assert.Equal(2, progress.Collections["Users"].TotalNumberOfDocuments); Assert.Equal(1, progress.Collections["Users"].TotalNumberOfTombstones); batchStats = new IndexingRunStats(); scope = new IndexingStatsScope(batchStats); index.DoIndexingWork(scope, CancellationToken.None); using (context.OpenReadTransaction()) { progress = index.GetProgress(context); } Assert.Equal(5, progress.Collections["Users"].LastProcessedDocumentEtag); Assert.Equal(4, progress.Collections["Users"].LastProcessedTombstoneEtag); Assert.Equal(0, progress.Collections["Users"].NumberOfDocumentsToProcess); Assert.Equal(0, progress.Collections["Users"].NumberOfTombstonesToProcess); Assert.Equal(2, progress.Collections["Users"].TotalNumberOfDocuments); Assert.Equal(1, progress.Collections["Users"].TotalNumberOfTombstones); } } } }
public void StalenessCalculationShouldWorkForAllDocsIndexes() { using (var database = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(1, new IndexDefinition() { Name = "Index1", Maps = { "from doc in docs select new { doc.Name }" }, Type = IndexType.Map }, database)) { using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { using (var doc = CreateDocument(context, "users/1", new DynamicJsonValue { ["Name"] = "John", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/1", null, doc); } using (var doc = CreateDocument(context, "people/1", new DynamicJsonValue { ["Name"] = "Edward", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "People" } })) { database.DocumentsStorage.Put(context, "people/1", null, doc); } tx.Commit(); } using (context.OpenReadTransaction()) { var isStale = index.IsStale(context); Assert.True(isStale); } var batchStats = new IndexingRunStats(); var scope = new IndexingStatsScope(batchStats); index.DoIndexingWork(scope, CancellationToken.None); Assert.Equal(2, batchStats.MapAttempts); Assert.Equal(2, batchStats.MapSuccesses); Assert.Equal(0, batchStats.MapErrors); using (context.OpenReadTransaction()) { var isStale = index.IsStale(context); Assert.False(isStale); } using (var tx = context.OpenWriteTransaction()) { database.DocumentsStorage.Delete(context, "people/1", null); tx.Commit(); } using (context.OpenReadTransaction()) { var isStale = index.IsStale(context); Assert.True(isStale); } batchStats = new IndexingRunStats(); scope = new IndexingStatsScope(batchStats); index.DoIndexingWork(scope, CancellationToken.None); using (context.OpenReadTransaction()) { var isStale = index.IsStale(context); Assert.False(isStale); } } } } }
public async Task The_easiest_static_index() { using (var database = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(1, new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }, database)) { using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { using (var doc = CreateDocument(context, "users/1", new DynamicJsonValue { ["Name"] = "John", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/1", null, doc); } using (var doc = CreateDocument(context, "users/2", new DynamicJsonValue { ["Name"] = "Edward", [Constants.Metadata.Key] = new DynamicJsonValue { [Constants.Headers.RavenEntityName] = "Users" } })) { database.DocumentsStorage.Put(context, "users/2", null, doc); } tx.Commit(); } var batchStats = new IndexingRunStats(); var scope = new IndexingStatsScope(batchStats); index.DoIndexingWork(scope, CancellationToken.None); Assert.Equal(2, batchStats.MapAttempts); Assert.Equal(2, batchStats.MapSuccesses); Assert.Equal(0, batchStats.MapErrors); var queryResult = await index.Query(new IndexQueryServerSide(), context, OperationCancelToken.None); Assert.Equal(2, queryResult.Results.Count); context.ResetAndRenew(); queryResult = await index.Query(new IndexQueryServerSide() { Query = "Name:John" }, context, OperationCancelToken.None); Assert.Equal(1, queryResult.Results.Count); Assert.Equal("users/1", queryResult.Results[0].Key); } } } }
public async Task CleanupOfMultiMapIndexWithLoadDocument() { var indexDefinition = new IndexDefinition() { Name = "NewIndex", Maps = new HashSet <string> { "from p in docs.Orders select new { CompanyName = LoadDocument(p.Company, \"Companies\").Name }", "from p in docs.Companies select new { CompanyName = p.Name }" } }; using (var database = CreateDocumentDatabase()) using (var index = MapIndex.CreateNew(indexDefinition, database)) using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { using (var doc = CreateDocument(context, "key/1", new DynamicJsonValue { ["Name"] = "John", [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Orders" } })) { database.DocumentsStorage.Put(context, "key/1", null, doc); } tx.Commit(); } var batchStats = new IndexingRunStats(); var stats = new IndexingStatsScope(batchStats); index.DoIndexingWork(stats, CancellationToken.None); var tombstones = index.GetLastProcessedTombstonesPerCollection(); Assert.Equal(2, tombstones.Count); Assert.Equal(0, tombstones["Orders"]); Assert.Equal(0, tombstones["Companies"]); using (context.OpenReadTransaction()) { var count = database.DocumentsStorage.GetTombstonesFrom(context, "Orders", 0, 0, 128).Count(); Assert.Equal(0, count); } using (var tx = context.OpenWriteTransaction()) { database.DocumentsStorage.Delete(context, "key/1", null); tx.Commit(); } tombstones = index.GetLastProcessedTombstonesPerCollection(); Assert.Equal(2, tombstones.Count); Assert.Equal(0, tombstones["Orders"]); Assert.Equal(0, tombstones["Companies"]); using (context.OpenReadTransaction()) { var count = database.DocumentsStorage.GetTombstonesFrom(context, "Orders", 0, 0, 128).Count(); Assert.Equal(1, count); } await database.TombstoneCleaner.ExecuteCleanup(); using (context.OpenReadTransaction()) { var count = database.DocumentsStorage.GetTombstonesFrom(context, "Orders", 0, 0, 128).Count(); Assert.Equal(1, count); } batchStats = new IndexingRunStats(); stats = new IndexingStatsScope(batchStats); index.DoIndexingWork(stats, CancellationToken.None); tombstones = index.GetLastProcessedTombstonesPerCollection(); Assert.Equal(2, tombstones.Count); Assert.Equal(2, tombstones["Orders"]); Assert.Equal(0, tombstones["Companies"]); await database.TombstoneCleaner.ExecuteCleanup(); using (context.OpenReadTransaction()) { var list = database.DocumentsStorage.GetTombstonesFrom(context, "Orders", 0, 0, 128).ToList(); Assert.Equal(0, list.Count); } } }
public async Task ReplaceIndexShouldWork() { using (var database = CreateDocumentDatabase(runInMemory: false)) { var testingStuff = database.IndexStore.ForTestingPurposesOnly(); using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, }, database)) { index.IndexPersistence.TempFileCache.SetMemoryStreamCapacity(1); testingStuff.RunFakeIndex(index); using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { using (var doc = CreateDocument(context, "users/1", new DynamicJsonValue { ["Name"] = "John", [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Users" } })) { database.DocumentsStorage.Put(context, "users/1", null, doc); } using (var doc = CreateDocument(context, "users/2", new DynamicJsonValue { ["Name"] = "Edward", [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Users" } })) { database.DocumentsStorage.Put(context, "users/2", null, doc); } tx.Commit(); } } while (index.HadRealIndexingWork == false) { await Task.Delay(100); } var mre = new SemaphoreSlim(initialCount: 0); database.Changes.OnIndexChange += change => { if (change.Type == IndexChangeTypes.SideBySideReplace) { mre.Release(); } }; using (var newIndex = MapIndex.CreateNew( new IndexDefinition() { Name = $"{Constants.Documents.Indexing.SideBySideIndexNamePrefix}Users_ByName", Maps = { " from user in docs.Users select new { user.Name }" }, }, database)) { newIndex.IndexPersistence.TempFileCache.SetMemoryStreamCapacity(1); testingStuff.RunFakeIndex(newIndex); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(15)), "Index wasn't replaced"); Assert.True(SpinWait.SpinUntil(() => newIndex.Status == IndexRunningStatus.Running, TimeSpan.FromSeconds(10)), "newIndex.Status == IndexRunningStatus.Running"); } } } }
public void Should_be_able_to_read_index_stats_even_if_corruption_happened() { UseNewLocalServer(); using (var db = CreateDocumentDatabase()) { using (var index = MapIndex.CreateNew(new IndexDefinition() { Name = "Users_ByName", Maps = { "from user in docs.Users select new { user.Name }" }, Type = IndexType.Map }, db)) { PutUser(db); index._indexStorage.SimulateCorruption = true; db.ServerStore.DatabasesLandlord.CatastrophicFailureHandler.MaxDatabaseUnloads = 0; var mre = new ManualResetEventSlim(); db.Changes.OnIndexChange += change => { if (change.Type == IndexChangeTypes.IndexMarkedAsErrored) { mre.Set(); } }; index.Start(); Assert.True(mre.Wait(TimeSpan.FromMinutes(1))); Assert.Equal(IndexState.Error, index.State); long errorCount = 0; for (int i = 0; i < 20; i++) { errorCount = index.GetErrorCount(); if (errorCount > 0) { break; } Thread.Sleep(500); // errors are updated in next tx when we update the stats } Assert.Equal(1, errorCount); using (var context = QueryOperationContext.ShortTermSingleUse(db)) { using (context.OpenReadTransaction()) { var indexStats = index.GetIndexingState(context); Assert.True(indexStats.IsStale); } } var indexingErrors = index.GetErrors(); Assert.Equal(1, indexingErrors.Count); } } }
public int CreateIndex(IndexDefinition definition) { if (definition == null) { throw new ArgumentNullException(nameof(definition)); } lock (_locker) { Index existingIndex; var lockMode = ValidateIndexDefinition(definition.Name, out existingIndex); if (lockMode == IndexLockMode.LockedIgnore) { return(existingIndex.IndexId); } definition.RemoveDefaultValues(); switch (GetIndexCreationOptions(definition, existingIndex)) { case IndexCreationOptions.Noop: return(existingIndex.IndexId); case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex: switch (definition.Type) { case IndexType.Map: MapIndex.Update(existingIndex, definition, _documentDatabase); break; case IndexType.MapReduce: MapReduceIndex.Update(existingIndex, definition, _documentDatabase); break; default: throw new NotSupportedException($"Cannot update {definition.Type} index from IndexDefinition"); } return(existingIndex.IndexId); case IndexCreationOptions.Update: DeleteIndex(existingIndex.IndexId); break; } var indexId = _indexes.GetNextIndexId(); Index index; switch (definition.Type) { case IndexType.Map: index = MapIndex.CreateNew(indexId, definition, _documentDatabase); break; case IndexType.MapReduce: index = MapReduceIndex.CreateNew(indexId, definition, _documentDatabase); break; default: throw new NotSupportedException($"Cannot create {definition.Type} index from IndexDefinition"); } return(CreateIndexInternal(index, indexId)); } }
public void CanSetMapBatchSize(int?mapBatchSize, int numberOfDocs) { var indexDefinition = new IndexDefinition { Name = "NewIndex", Maps = new HashSet <string> { "from p in docs.Orders select new { CompanyName = LoadDocument(p.Company, \"Companies\").Name }" }, Configuration = new IndexConfiguration { { RavenConfiguration.GetKey(x => x.Indexing.MapBatchSize), mapBatchSize?.ToString() } } }; using (var database = CreateDocumentDatabase()) using (var index = MapIndex.CreateNew(indexDefinition, database)) using (var queryContext = QueryOperationContext.ShortTermSingleUse(database)) { var context = queryContext.Documents; Assert.Equal(mapBatchSize, index.Configuration.MapBatchSize); using (var tx = context.OpenWriteTransaction()) { for (var i = 0; i < numberOfDocs; i++) { var orderDocumentId = $"orders/{i}"; var companyDocumentId = $"companies/{i}"; using (var doc = CreateDocument(context, orderDocumentId, new DynamicJsonValue { ["Name"] = "John", ["Company"] = companyDocumentId, [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Orders" } })) { database.DocumentsStorage.Put(context, orderDocumentId, null, doc); } } tx.Commit(); } using (var tx = context.OpenWriteTransaction()) { for (var i = 0; i < numberOfDocs; i++) { var companyDocumentId = $"companies/{i}"; using (var doc = CreateDocument(context, companyDocumentId, new DynamicJsonValue { ["Name"] = "RavenDB", [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Companies" } })) { database.DocumentsStorage.Put(context, companyDocumentId, null, doc); } } tx.Commit(); } var numberOfBatches = numberOfDocs / mapBatchSize; var batchStats = new IndexingRunStats(); var stats = new IndexingStatsScope(batchStats); for (var i = 0; i < numberOfBatches; i++) { index.DoIndexingWork(stats, CancellationToken.None); Assert.Equal((i + 1) * mapBatchSize, stats.MapAttempts); } index.DoIndexingWork(stats, CancellationToken.None); Assert.Equal(numberOfDocs, stats.MapAttempts); using (var tx = context.OpenWriteTransaction()) { for (var i = 0; i < numberOfDocs; i++) { var companyDocumentId = $"companies/{i}"; using (var doc = CreateDocument(context, companyDocumentId, new DynamicJsonValue { ["Name"] = "Hibernating Rhinos", [Constants.Documents.Metadata.Key] = new DynamicJsonValue { [Constants.Documents.Metadata.Collection] = "Companies" } })) { database.DocumentsStorage.Put(context, companyDocumentId, null, doc); } } tx.Commit(); } batchStats = new IndexingRunStats(); stats = new IndexingStatsScope(batchStats); for (var i = 0; i < numberOfBatches; i++) { index.DoIndexingWork(stats, CancellationToken.None); Assert.Equal((i + 1) * mapBatchSize, stats.MapReferenceAttempts); } index.DoIndexingWork(stats, CancellationToken.None); Assert.Equal(numberOfDocs, stats.MapReferenceAttempts); using (context.OpenReadTransaction()) Assert.False(index.IsStale(queryContext)); } }
private void HandleStaticIndexChange(string name, IndexDefinition definition) { var creationOptions = IndexCreationOptions.Create; var currentIndex = GetIndex(name); IndexDefinitionCompareDifferences currentDifferences = IndexDefinitionCompareDifferences.None; if (currentIndex != null) { creationOptions = GetIndexCreationOptions(definition, currentIndex, out currentDifferences); } var replacementIndexName = Constants.Documents.Indexing.SideBySideIndexNamePrefix + definition.Name; if (creationOptions == IndexCreationOptions.Noop) { Debug.Assert(currentIndex != null); var replacementIndex = GetIndex(replacementIndexName); if (replacementIndex != null) { DeleteIndexInternal(replacementIndex); } return; } if (creationOptions == IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex) { Debug.Assert(currentIndex != null); var replacementIndex = GetIndex(replacementIndexName); if (replacementIndex != null) { DeleteIndexInternal(replacementIndex); } if (currentDifferences != IndexDefinitionCompareDifferences.None) { UpdateIndex(definition, currentIndex, currentDifferences); } return; } UpdateStaticIndexLockModeAndPriority(definition, currentIndex, currentDifferences); if (creationOptions == IndexCreationOptions.Update) { Debug.Assert(currentIndex != null); definition.Name = replacementIndexName; var replacementIndex = GetIndex(replacementIndexName); if (replacementIndex != null) { creationOptions = GetIndexCreationOptions(definition, replacementIndex, out IndexDefinitionCompareDifferences sideBySideDifferences); if (creationOptions == IndexCreationOptions.Noop) { return; } if (creationOptions == IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex) { UpdateIndex(definition, replacementIndex, sideBySideDifferences); return; } DeleteIndexInternal(replacementIndex); } } Index index; switch (definition.Type) { case IndexType.Map: index = MapIndex.CreateNew(definition, _documentDatabase); break; case IndexType.MapReduce: index = MapReduceIndex.CreateNew(definition, _documentDatabase); break; default: throw new NotSupportedException($"Cannot create {definition.Type} index from IndexDefinition"); } CreateIndexInternal(index); }