示例#1
0
        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);
                }
            }
        }
示例#2
0
        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)));
                }
            }
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
 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);
             }
 }
示例#5
0
        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);
                }
            }
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
        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);
                    }
                }
            }
        }
示例#11
0
        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);
                        }
                    }
        }
示例#12
0
        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");
                    }
                }
            }
        }
示例#13
0
        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);
                }
            }
        }
示例#14
0
        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));
            }
        }
示例#15
0
        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));
                    }
        }
示例#16
0
        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);
        }