internal void PutNewIndexIntoStorage(string name, IndexDefinition definition) { Debug.Assert(Database.IndexStorage != null); Debug.Assert(TransactionalStorage != null); Debug.Assert(WorkContext != null); TransactionalStorage.Batch(actions => { definition.IndexId = (int)Database.Documents.GetNextIdentityValueWithoutOverwritingOnExistingDocuments("IndexId", actions, null); IndexDefinitionStorage.RegisterNewIndexInThisSession(name, definition); // this has to happen in this fashion so we will expose the in memory status after the commit, but // before the rest of the world is notified about this. IndexDefinitionStorage.CreateAndPersistIndex(definition); Database.IndexStorage.CreateIndexImplementation(definition); InvokeSuggestionIndexing(name, definition); actions.Indexing.AddIndex(definition.IndexId, definition.IsMapReduce); }); if (name.Equals(Constants.DocumentsByEntityNameIndex, StringComparison.InvariantCultureIgnoreCase) == false && Database.IndexStorage.HasIndex(Constants.DocumentsByEntityNameIndex)) { // optimization of handling new index creation when the number of document in a database is significantly greater than // number of documents that this index applies to - let us use built-in RavenDocumentsByEntityName to get just appropriate documents var index = Database.IndexStorage.GetIndexInstance(definition.IndexId); TryApplyPrecomputedBatchForNewIndex(index, definition); } WorkContext.ShouldNotifyAboutWork(() => "PUT INDEX " + name); WorkContext.NotifyAboutWork(); // The act of adding it here make it visible to other threads // we have to do it in this way so first we prepare all the elements of the // index, then we add it to the storage in a way that make it public IndexDefinitionStorage.AddIndex(definition.IndexId, definition); }
internal void PutNewIndexIntoStorage(string name, IndexDefinition definition, bool disableIndex = false) { Debug.Assert(Database.IndexStorage != null); Debug.Assert(TransactionalStorage != null); Debug.Assert(WorkContext != null); Index index = null; TransactionalStorage.Batch(actions => { var maxId = 0; if (Database.IndexStorage.Indexes.Length > 0) { maxId = Database.IndexStorage.Indexes.Max(); } definition.IndexId = (int)Database.Documents.GetNextIdentityValueWithoutOverwritingOnExistingDocuments("IndexId", actions); if (definition.IndexId <= maxId) { actions.General.SetIdentityValue("IndexId", maxId + 1); definition.IndexId = (int)Database.Documents.GetNextIdentityValueWithoutOverwritingOnExistingDocuments("IndexId", actions); } IndexDefinitionStorage.RegisterNewIndexInThisSession(name, definition); // this has to happen in this fashion so we will expose the in memory status after the commit, but // before the rest of the world is notified about this. IndexDefinitionStorage.CreateAndPersistIndex(definition); Database.IndexStorage.CreateIndexImplementation(definition); index = Database.IndexStorage.GetIndexInstance(definition.IndexId); // If we execute multiple indexes at once and want to activate them all at once we will disable the index from the endpoint if (disableIndex) { index.Priority = IndexingPriority.Disabled; } //ensure that we don't start indexing it right away, let the precomputation run first, if applicable index.IsMapIndexingInProgress = true; if (definition.IsTestIndex) { index.MarkQueried(); // test indexes should be mark queried, so the cleanup task would not delete them immediately } InvokeSuggestionIndexing(name, definition, index); actions.Indexing.AddIndex(definition.IndexId, definition.IsMapReduce); }); Debug.Assert(index != null); Action precomputeTask = null; if (WorkContext.RunIndexing && name.Equals(Constants.DocumentsByEntityNameIndex, StringComparison.InvariantCultureIgnoreCase) == false && Database.IndexStorage.HasIndex(Constants.DocumentsByEntityNameIndex)) { // optimization of handling new index creation when the number of document in a database is significantly greater than // number of documents that this index applies to - let us use built-in RavenDocumentsByEntityName to get just appropriate documents precomputeTask = TryCreateTaskForApplyingPrecomputedBatchForNewIndex(index, definition); } else { index.IsMapIndexingInProgress = false; // we can't apply optimization, so we'll make it eligible for running normally } // The act of adding it here make it visible to other threads // we have to do it in this way so first we prepare all the elements of the // index, then we add it to the storage in a way that make it public IndexDefinitionStorage.AddIndex(definition.IndexId, definition); // we start the precomuteTask _after_ we finished adding the index if (precomputeTask != null) { precomputeTask(); } WorkContext.ShouldNotifyAboutWork(() => "PUT INDEX " + name); WorkContext.NotifyAboutWork(); }