Esempio n. 1
0
 public void RowsMoved(NativeRowTreeNode oldNode, int oldEntryNumberMin, int oldEntryNumberMax, NativeRowTreeNode newNode, int entryNumberDelta)
 {
     if (OnRowsMoved != null)
     {
         OnRowsMoved(this, oldNode, oldEntryNumberMin, oldEntryNumberMax, newNode, entryNumberDelta);
     }
 }
Esempio n. 2
0
 public void RowDeleted(NativeRowTreeNode node, int entryNumber)
 {
     if (OnRowDeleted != null)
     {
         OnRowDeleted(this, node, entryNumber);
     }
 }
Esempio n. 3
0
 private void RowTreeRowDeleted(NativeRowTree rowTree, NativeRowTreeNode node, int entryNumber)
 {
     if ((_indexNode.Node == node) && (_entryNumber == entryNumber))
     {
         UpdateScanPointer();
     }
 }
Esempio n. 4
0
 public override void Drop(IValueManager manager)
 {
     // Deallocate all nodes in the tree
     DeallocateNode(manager, Root);
     Root   = null;
     Tail   = null;
     Head   = null;
     Height = 0;
 }
Esempio n. 5
0
 public RowTreeNode(IValueManager manager, NativeRowTree tree, NativeRowTreeNode node, LockMode lockMode)
 {
     Manager     = manager;
     Tree        = tree;
     Node        = node;
     DataNode    = Node as NativeRowTreeDataNode;
     RoutingNode = Node as NativeRowTreeRoutingNode;
                 #if LOCKROWTREE
     Manager.Lock(Node.LockID, ALockMode);
                 #endif
 }
Esempio n. 6
0
        public void Insert(NativeRow key, NativeRowTreeNode node, int entryNumber)
        {
            // Slide all entries above the insert index
            Array.Copy(_keys, entryNumber, _keys, entryNumber + 1, _entryCount - entryNumber);
            Array.Copy(_nodes, entryNumber, _nodes, entryNumber + 1, _entryCount - entryNumber);

            // Set the new entry data
            _keys[entryNumber]  = key;
            _nodes[entryNumber] = node;

            // Increment entry count
            _entryCount++;
        }
Esempio n. 7
0
        private void RowTreeRowsMoved(NativeRowTree rowTree, NativeRowTreeNode oldNode, int oldEntryNumberMin, int oldEntryNumberMax, NativeRowTreeNode newNode, int entryNumberDelta)
        {
            if ((_indexNode.Node == oldNode) && (_entryNumber >= oldEntryNumberMin) && (_entryNumber <= oldEntryNumberMax))
            {
                if (oldNode != newNode)
                {
                    SetIndexNode(new RowTreeNode(_manager, _indexNode.Tree, newNode, LockMode.Shared));
                }

                _entryNumber += entryNumberDelta;
                UpdateScanPointer();
            }
        }
Esempio n. 8
0
        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;
                    }
                }
            }
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
 public NativeRowTreeRoutingNode(NativeRowTree nativeRowTree) : base(nativeRowTree)
 {
     _nodeType = NativeRowTreeNodeType.Routing;
     _keys     = new NativeRow[_nativeRowTree.Fanout];
     _nodes    = new NativeRowTreeNode[_nativeRowTree.Fanout];
 }
Esempio n. 11
0
        private void InternalInsert(IValueManager manager, RowTreeSearchPath rowTreeSearchPath, int entryNumber, NativeRow key, NativeRow data)
        {
            // Walk back up the search path, inserting data and splitting pages as necessary
            RowTreeNode       newRowTreeNode;
            NativeRowTreeNode splitNode = null;

            for (int index = rowTreeSearchPath.Count - 1; index >= 0; index--)
            {
                if (rowTreeSearchPath[index].Node.EntryCount >= Capacity)
                {
                    // Allocate a new node
                    using (newRowTreeNode = AllocateNode(manager, rowTreeSearchPath[index].Node.NodeType))
                    {
                        // Thread it into the list of leaves, if necessary
                        if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                        {
                            newRowTreeNode.Node.PriorNode          = rowTreeSearchPath[index].Node;
                            newRowTreeNode.Node.NextNode           = rowTreeSearchPath[index].Node.NextNode;
                            rowTreeSearchPath[index].Node.NextNode = newRowTreeNode.Node;
                            if (newRowTreeNode.Node.NextNode == null)
                            {
                                Tail = newRowTreeNode.Node;
                            }
                            else
                            {
                                using (RowTreeNode nextRowTreeNode = new RowTreeNode(manager, this, newRowTreeNode.Node.NextNode, LockMode.Exclusive))
                                {
                                    nextRowTreeNode.Node.PriorNode = newRowTreeNode.Node;
                                }
                            }
                        }

                        int entryPivot = Split(rowTreeSearchPath[index].Node, newRowTreeNode.Node);

                        // Insert the new entry into the appropriate node
                        if (entryNumber >= entryPivot)
                        {
                            if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                            {
                                newRowTreeNode.InsertData(key, data, entryNumber - entryPivot);
                            }
                            else
                            {
                                newRowTreeNode.InsertRouting(key, splitNode, entryNumber - entryPivot);
                            }
                        }
                        else
                        if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                        {
                            rowTreeSearchPath[index].InsertData(key, data, entryNumber);
                        }
                        else
                        {
                            rowTreeSearchPath[index].InsertRouting(key, splitNode, entryNumber);
                        }

                        // Reset the AKey for the next round
                        // The key for the entry one level up is the first key for the newly allocated node
                        key = CopyKey(manager, newRowTreeNode.Node.Keys[0]);

                        // Set LSplitNode to the newly allocated node
                        splitNode = newRowTreeNode.Node;
                    }

                    if (index == 0)
                    {
                        // Allocate a new root node and grow the height of the tree by 1
                        using (newRowTreeNode = AllocateNode(manager, NativeRowTreeNodeType.Routing))
                        {
                            newRowTreeNode.InsertRouting(null, rowTreeSearchPath[index].Node, 0);                             // 1st key of a routing node is not used
                            newRowTreeNode.InsertRouting(key, splitNode, 1);
                            Root = newRowTreeNode.Node;
                            Height++;
                        }
                    }
                    else
                    {
                        // reset AEntryNumber for the next round
                        bool result = rowTreeSearchPath[index - 1].NodeSearch(KeyRowType, key, out entryNumber);

                        // At this point we should be guaranteed to have a routing key which does not exist in the parent node
                        if (result)
                        {
                            throw new IndexException(IndexException.Codes.DuplicateRoutingKey);
                        }
                    }
                }
                else
                {
                    if (rowTreeSearchPath[index].Node.NodeType == NativeRowTreeNodeType.Data)
                    {
                        rowTreeSearchPath[index].InsertData(key, data, entryNumber);
                    }
                    else
                    {
                        rowTreeSearchPath[index].InsertRouting(key, splitNode, entryNumber);
                    }
                    break;
                }
            }
        }
Esempio n. 12
0
 public void UpdateRouting(NativeRowTreeNode node, int entryNumber)
 {
     RoutingNode.Nodes[entryNumber] = node;
 }
Esempio n. 13
0
        public void InsertRouting(NativeRow key, NativeRowTreeNode node, int entryNumber)
        {
            RoutingNode.Insert(key, node, entryNumber);

            Tree.RowsMoved(Node, entryNumber, Node.EntryCount - 2, Node, 1);
        }