public NativeRowTree ( Schema.Order key, Schema.RowType keyRowType, Schema.RowType dataRowType, int fanout, int capacity, bool isClustered ) : base(keyRowType, dataRowType) { _key = key; #if DEBUG for (int index = 0; index < _key.Columns.Count; index++) { if (_key.Columns[index].Sort == null) { Error.Fail("Sort is null"); } } #endif _fanout = fanout < MinimumFanout ? MinimumFanout : fanout; _capacity = capacity; IsClustered = isClustered; Root = new NativeRowTreeDataNode(this); Head = Root; Tail = Root; Height = 1; }
protected void DeallocateNode(IValueManager manager, NativeRowTreeNode node) { using (RowTreeNode localNode = new RowTreeNode(manager, this, node, LockMode.Exclusive)) { NativeRowTreeDataNode dataNode = node as NativeRowTreeDataNode; NativeRowTreeRoutingNode routingNode = node as NativeRowTreeRoutingNode; for (int entryIndex = 0; entryIndex < node.EntryCount; entryIndex++) { if (node.NodeType == NativeRowTreeNodeType.Routing) { if (entryIndex > 0) { DisposeKey(manager, node.Keys[entryIndex]); } DeallocateNode(manager, routingNode.Nodes[entryIndex]); } else { DisposeKey(manager, dataNode.Keys[entryIndex]); DisposeData(manager, dataNode.Rows[entryIndex]); } } if (node.NextNode == null) { Tail = node.PriorNode; } else { using (RowTreeNode nextNode = new RowTreeNode(manager, this, node.NextNode, LockMode.Exclusive)) { nextNode.Node.PriorNode = node.PriorNode; } } if (node.PriorNode == null) { Head = node.NextNode; } else { using (RowTreeNode priorNode = new RowTreeNode(manager, this, node.PriorNode, LockMode.Exclusive)) { priorNode.Node.NextNode = node.NextNode; } } } }
private int Split(NativeRowTreeNode sourceNode, NativeRowTreeNode targetNode) { int entryCount = sourceNode.EntryCount; int entryPivot = entryCount / 2; if (sourceNode.NodeType == NativeRowTreeNodeType.Data) { NativeRowTreeDataNode sourceDataNode = (NativeRowTreeDataNode)sourceNode; NativeRowTreeDataNode targetDataNode = (NativeRowTreeDataNode)targetNode; // Insert the upper half of the entries from ASourceNode into ATargetNode for (int entryIndex = entryPivot; entryIndex < entryCount; entryIndex++) { targetDataNode.Insert(sourceDataNode.Keys[entryIndex], sourceDataNode.Rows[entryIndex], entryIndex - entryPivot); } // Remove the upper half of the entries from ASourceNode for (int entryIndex = entryCount - 1; entryIndex >= entryPivot; entryIndex--) { sourceDataNode.Delete(entryIndex); // Don't dispose the values here, this is a move } } else { NativeRowTreeRoutingNode sourceRoutingNode = (NativeRowTreeRoutingNode)sourceNode; NativeRowTreeRoutingNode targetRoutingNode = (NativeRowTreeRoutingNode)targetNode; // Insert the upper half of the entries from ASourceNode into ATargetNode for (int entryIndex = entryPivot; entryIndex < entryCount; entryIndex++) { targetRoutingNode.Insert(sourceRoutingNode.Keys[entryIndex], sourceRoutingNode.Nodes[entryIndex], entryIndex - entryPivot); } // Remove the upper half of the entries from ASourceNode for (int entryIndex = entryCount - 1; entryIndex >= entryPivot; entryIndex--) { sourceRoutingNode.Delete(entryIndex); } } // Notify index clients of the data change RowsMoved(sourceNode, entryPivot, entryCount - 1, targetNode, -entryPivot); return(entryPivot); }