private AggregationResult AggregateLeafPage(TreePage page, LowLevelTransaction lowLevelTransaction, TransactionOperationContext indexContext, CancellationToken token) { using (_treeReductionStats.LeafAggregation.Start()) { for (int i = 0; i < page.NumberOfEntries; i++) { var valueReader = TreeNodeHeader.Reader(lowLevelTransaction, page.GetNode(i)); var reduceEntry = new BlittableJsonReaderObject(valueReader.Base, valueReader.Length, indexContext); _aggregationBatch.Add(reduceEntry); } return(AggregateBatchResults(_aggregationBatch, indexContext, token)); } }
private static unsafe ReduceTree RenderTree(Tree tree, ulong reduceKeyHash, Dictionary <long, string> idToDocIdHash, Index index, TransactionOperationContext context) { var stack = new Stack <ReduceTreePage>(); var rootPage = tree.GetReadOnlyTreePage(tree.State.RootPageNumber); var root = new ReduceTreePage(rootPage); root.AggregationResult = GetReduceResult(reduceKeyHash, index, context); stack.Push(root); var table = context.Transaction.InnerTransaction.OpenTable( ReduceMapResultsBase <MapReduceIndexDefinition> .ReduceResultsSchema, ReduceMapResultsBase <MapReduceIndexDefinition> .PageNumberToReduceResultTableName); var tx = tree.Llt; while (stack.Count > 0) { var node = stack.Pop(); var page = node.Page; if (page.IsCompressed) { var decompressed = tree.DecompressPage(page, DecompressionUsage.Read, true); node.DecompressedLeaf = decompressed; page = decompressed; } if (page.NumberOfEntries == 0 && page != rootPage) { throw new InvalidOperationException($"The page {page.PageNumber} is empty"); } for (var i = 0; i < page.NumberOfEntries; i++) { if (page.IsBranch) { var p = page.GetNode(i)->PageNumber; var childNode = new ReduceTreePage(tree.GetReadOnlyTreePage(p)); node.Children.Add(childNode); stack.Push(childNode); } else { var entry = new MapResultInLeaf(); var valueReader = TreeNodeHeader.Reader(tx, page.GetNode(i)); entry.Data = new BlittableJsonReaderObject(valueReader.Base, valueReader.Length, context); using (page.GetNodeKey(tx, i, out Slice s)) { var mapEntryId = Bits.SwapBytes(*(long *)s.Content.Ptr); if (idToDocIdHash.TryGetValue(mapEntryId, out string docId)) { entry.Source = docId; } } node.Entries.Add(entry); } } if (node != root) { node.AggregationResult = GetAggregationResult(node.PageNumber, table, context); } } return(new ReduceTree { DisplayName = GetTreeName(root.AggregationResult, index.Definition, context), Name = tree.Name.ToString(), Root = root, Depth = tree.State.Depth, PageCount = tree.State.PageCount, NumberOfEntries = tree.State.NumberOfEntries }); }