private List<SplitTreeNode> UpdateBlock(BlockBatch blockBatch) { Block block = dictionary.Container.ReadBlock(blockBatch.BlockOffset); //todo: review types List<Record> records = MergeRecords(block.Records, blockBatch.Records, blockBatch.MaskOffset/8); SplitTreeNode splitTreeRoot = new SplitTreeNode(null, -1, blockBatch.MaskOffset, blockBatch.NodeIndex, blockBatch.BlockOffset, records); List<SplitTreeNode> updatedTreeNodes = new List<SplitTreeNode>(); updatedTreeNodes.Add(splitTreeRoot); List<SplitTreeNode> unsplitTreeNodes = new List<SplitTreeNode>(); if (splitTreeRoot.Records.Count > dictionary.Container.RecordsPerBlock) { unsplitTreeNodes.Add(splitTreeRoot); } while (unsplitTreeNodes.Count != 0) { SplitTreeNode nodeToSplit = unsplitTreeNodes[unsplitTreeNodes.Count - 1]; unsplitTreeNodes.RemoveAt(unsplitTreeNodes.Count - 1); List<SplitTreeNode> newNodes = Split(nodeToSplit); foreach (SplitTreeNode treeNode in newNodes) { updatedTreeNodes.Add(treeNode); if (treeNode.Records.Count > dictionary.Container.RecordsPerBlock) { unsplitTreeNodes.Add(treeNode); } } } return updatedTreeNodes; }
private List<BlockBatch> SplitByBlock(List<Record> records, bool addMissingBranches) { Dictionary<long, BlockBatch> blockBatches = new Dictionary<long, BlockBatch>(); foreach (var record in records) { int maskOffset = 0; int nodeIndex = 0; CompactTreeNode node = dictionary.Container.GetTreeNode(nodeIndex); int childNum = 0; while (node.IsSplitNode) { bool left = (record.Key.GetByteAt(maskOffset/8) & (1 << (7 - maskOffset%8))) == 0; childNum = left ? 0 : 1; int childIndex = node.GetChild(childNum); if (childIndex == 0) { break; } nodeIndex = childIndex; node = dictionary.Container.GetTreeNode(nodeIndex); maskOffset++; } if (node.IsSplitNode) { if (addMissingBranches) { //todo: test this branch long blockOffset = dictionary.Container.AllocateBlock(); nodeIndex = dictionary.Container.AddDataNode(nodeIndex, childNum, blockOffset); node = dictionary.Container.GetTreeNode(nodeIndex); maskOffset++; } } if (node.IsDataNode) { long blockOffset = node.Value; BlockBatch blockBatch; if (!blockBatches.TryGetValue(blockOffset, out blockBatch)) { blockBatch = new BlockBatch(blockOffset, maskOffset, nodeIndex); blockBatches.Add(blockOffset, blockBatch); } blockBatch.Records.Add(record); } } List<BlockBatch> batchesList = blockBatches.Values.ToList(); foreach (BlockBatch batch in batchesList) { batch.Records.Sort((recordA, recordB) => CompareKeys(recordA.Key, recordB.Key, batch.MaskOffset/8)); } return batchesList; }