private static async Task ActualTest(int numberOfUsers, string[] locations, Index index, MapReduceIndexingContext mapReduceContext, IIndexingWork reducer, DocumentDatabase database) { TransactionOperationContext indexContext; using (index._contextPool.AllocateOperationContext(out indexContext)) { ulong hashOfReduceKey = 73493; using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < numberOfUsers; i++) { using (var mappedResult = indexContext.ReadObject(new DynamicJsonValue { ["Count"] = 1, ["Location"] = locations[i % locations.Length] }, $"users/{i}")) { store.Add(i, mappedResult); } } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction)); var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); tx.Commit(); } using (var termSingleUse = DocumentsOperationContext.ShortTermSingleUse(database)) { var queryResult = await index.Query(new IndexQueryServerSide($"FROM INDEX '{index.Name}'"), termSingleUse, OperationCancelToken.None); var results = queryResult.Results; Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected, results[i].Data["Count"]); } } // update using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < locations.Length; i++) { using (var mappedResult = indexContext.ReadObject(new DynamicJsonValue { ["Count"] = 2, // increased by 1 ["Location"] = locations[i % locations.Length] }, $"users/{i}")) { store.Add(i, mappedResult); } } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction)); var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); tx.Commit(); } using (var shortTermSingleUse = DocumentsOperationContext.ShortTermSingleUse(database)) { var queryResult = await index.Query(new IndexQueryServerSide($"FROM INDEX '{index.Name}'"), shortTermSingleUse, OperationCancelToken.None); var results = queryResult.Results; Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected + 1, results[i].Data["Count"]); } } // delete using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < locations.Length; i++) { store.Delete(i); } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction)); var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); tx.Commit(); } using (var documentsOperationContext = DocumentsOperationContext.ShortTermSingleUse(database)) { var queryResult = await index.Query(new IndexQueryServerSide("FROM Users ORDER BY Location"), documentsOperationContext, OperationCancelToken.None); var results = queryResult.Results; Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected - 1, results[i].Data["Count"]); } } } }
private static void ActualTest(int numberOfUsers, string[] locations, Index index, MapReduceIndexingContext mapReduceContext, IIndexingWork reducer, DocumentDatabase database, string outputToCollectionName) { using (index._contextPool.AllocateOperationContext(out TransactionOperationContext indexContext)) { ulong hashOfReduceKey = 73493; using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < numberOfUsers; i++) { using (var mappedResult = indexContext.ReadObject(new DynamicJsonValue { ["Count"] = 1, ["Location"] = locations[i % locations.Length] }, $"users/{i}")) { store.Add(i, mappedResult); } } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction, indexContext)); var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); tx.Commit(); } using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) using (context.OpenReadTransaction()) { var results = database.DocumentsStorage.GetDocumentsFrom(context, outputToCollectionName, 0, 0, int.MaxValue).ToList(); Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected, results[i].Data["Count"]); } } // update using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < locations.Length; i++) { using (var mappedResult = indexContext.ReadObject(new DynamicJsonValue { ["Count"] = 2, // increased by 1 ["Location"] = locations[i % locations.Length] }, $"users/{i}")) { store.Add(i, mappedResult); } } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction, indexContext)); try { var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); } finally { if (writeOperation.IsValueCreated) { writeOperation.Value.Dispose(); } } tx.Commit(); } using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) using (context.OpenReadTransaction()) { var results = database.DocumentsStorage.GetDocumentsFrom(context, outputToCollectionName, 0, 0, int.MaxValue).ToList(); Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected + 1, results[i].Data["Count"]); } } // delete using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < locations.Length; i++) { store.Delete(i); } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction, indexContext)); try { var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); tx.Commit(); } finally { if (writeOperation.IsValueCreated) { writeOperation.Value.Dispose(); } } } using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) using (context.OpenReadTransaction()) { var results = database.DocumentsStorage.GetDocumentsFrom(context, outputToCollectionName, 0, 0, int.MaxValue).ToList(); Assert.Equal(locations.Length, results.Count); for (int i = 0; i < locations.Length; i++) { Assert.Equal(locations[i], results[i].Data["Location"].ToString()); long expected = numberOfUsers / locations.Length + numberOfUsers % (locations.Length - i); Assert.Equal(expected - 1, results[i].Data["Count"]); } } // delete entries for one reduce key using (var tx = indexContext.OpenWriteTransaction()) { mapReduceContext.MapPhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .MapPhaseTreeName); mapReduceContext.ReducePhaseTree = tx.InnerTransaction.CreateTree(MapReduceIndexBase <MapIndexDefinition, IndexField> .ReducePhaseTreeName); var store = new MapReduceResultsStore(hashOfReduceKey, MapResultsStorageType.Tree, indexContext, mapReduceContext, true); for (int i = 0; i < numberOfUsers; i++) { if (i % locations.Length == 0) { store.Delete(i); } } mapReduceContext.StoreByReduceKeyHash.Add(hashOfReduceKey, store); var writeOperation = new Lazy <IndexWriteOperation>(() => index.IndexPersistence.OpenIndexWriter(tx.InnerTransaction, indexContext)); try { var stats = new IndexingStatsScope(new IndexingRunStats()); reducer.Execute(null, indexContext, writeOperation, stats, CancellationToken.None); using (var indexWriteOperation = writeOperation.Value) { indexWriteOperation.Commit(stats); } index.IndexPersistence.RecreateSearcher(tx.InnerTransaction); mapReduceContext.Dispose(); tx.Commit(); } finally { if (writeOperation.IsValueCreated) { writeOperation.Value.Dispose(); } } } using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) using (context.OpenReadTransaction()) { var results = database.DocumentsStorage.GetDocumentsFrom(context, outputToCollectionName, 0, 0, int.MaxValue).ToList(); Assert.Equal(locations.Length - 1, results.Count); } } }