/// <summary>
        /// Creates an empty right sibling node and inserts the provided key in this node.
        /// Note: This should only be called if there is no right sibling and the key should go in
        /// that node.
        /// </summary>
        private void NewNodeThenInsert(TKey key, TValue value)
        {
            TKey dividingKey = new TKey(); //m_tempKey;

            key.CopyTo(dividingKey);

            uint newNodeIndex = m_getNextNewNodeIndex();

            if (!IsRightSiblingIndexNull)
            {
                throw new Exception("Incorrectly implemented");
            }

            RightSiblingNodeIndex = newNodeIndex;

            CreateNewNode(newNodeIndex, 0, (ushort)HeaderSize, NodeIndex, uint.MaxValue, key, UpperKey);

            UpperKey = key;

            SetNodeIndex(newNodeIndex);

            InsertUnlessFull(0, key, value);

            SparseIndex.Add(dividingKey, newNodeIndex, (byte)(Level + 1));
        }
Exemple #2
0
        private void UpdateBoundsAndRemoveEmptyNode(Node <TKey> leftNode, Node <TKey> rightNode)
        {
            if (leftNode.RecordCount == 0) //Remove the left node
            {
                //Change the existing pointer to the left node to point to the right node.
                SparseIndex.UpdateValue(leftNode.LowerKey, new SnapUInt32(rightNode.NodeIndex), (byte)(Level + 1));
                //Now remove the unused key position
                SparseIndex.Remove(rightNode.LowerKey, (byte)(Level + 1));

                rightNode.LowerKey             = leftNode.LowerKey;
                rightNode.LeftSiblingNodeIndex = leftNode.LeftSiblingNodeIndex;
                if (leftNode.LeftSiblingNodeIndex != uint.MaxValue)
                {
                    leftNode.SeekToLeftSibling();
                    leftNode.RightSiblingNodeIndex = rightNode.NodeIndex;
                }
            }
            else if (rightNode.RecordCount == 0) //Remove the right node.
            {
                SparseIndex.Remove(rightNode.LowerKey, (byte)(Level + 1));

                leftNode.UpperKey = rightNode.UpperKey;
                leftNode.RightSiblingNodeIndex = rightNode.RightSiblingNodeIndex;

                if (rightNode.RightSiblingNodeIndex != uint.MaxValue)
                {
                    rightNode.SeekToRightSibling();
                    rightNode.LeftSiblingNodeIndex = leftNode.NodeIndex;
                }
            }
            else
            {
                throw new Exception("Should never get here");
            }
        }
        //private TKey[] m_keys;
        //private TValue[] m_values;

        //public TKey[] Keys
        //{
        //    get
        //    {
        //        BuildKeyList();
        //        return m_keys;
        //    }
        //}

        //public TValue[] Values
        //{
        //    get
        //    {
        //        BuildKeyList();
        //        return m_values;
        //    }
        //}

        //public void WriteNodeData(StringBuilder sb)
        //{
        //    BuildKeyList();
        //    sb.AppendLine(string.Format("Node Index: {0} Record Count: {1} Node Level: {2} " +
        //                                "Right Sibling: {3} Left Sibling: {4} Lower Key: {5} Upper Key: {6}", NodeIndex, RecordCount,
        //                                Level, RightSiblingNodeIndex, LeftSiblingNodeIndex, LowerKey, UpperKey));

        //    foreach (TKey key in m_keys)
        //    {
        //        sb.Append(key.ToString());
        //        sb.Append("\t");
        //    }
        //    sb.AppendLine();

        //    foreach (TValue value in m_values)
        //    {
        //        sb.Append(value.ToString());
        //        sb.Append("\t");
        //    }
        //    sb.AppendLine();
        //}

        //private void BuildKeyList()
        //{
        //    if (m_keys is null || m_keys.Length != RecordCount)
        //    {
        //        m_keys = new TKey[RecordCount];
        //        m_values = new TValue[RecordCount];

        //        for (int x = 0; x < RecordCount; x++)
        //        {
        //            m_keys[x] = new TKey();
        //            m_values[x] = new TValue();
        //        }
        //    }
        //    for (int x = 0; x < RecordCount; x++)
        //    {
        //        Read(x, m_keys[x], m_values[x]);
        //    }
        //}

        #region [ Methods ]

        /// <summary>
        /// Seeks to the first node at this level of the tree
        /// </summary>
        public void SeekToFirstNode()
        {
            //Only need to do a seek if I'm not already on the first node.
            if (NodeIndex == uint.MaxValue || LeftSiblingNodeIndex != uint.MaxValue)
            {
                SetNodeIndex(SparseIndex.GetFirstIndex(Level));
            }
        }
 private void Initialize()
 {
     Indexer                 = new SparseIndex <TKey>();
     LeafStorage             = Library.CreateTreeNode <TKey, TValue>(m_header.TreeNodeType, 0);
     Indexer.RootHasChanged += IndexerOnRootHasChanged;
     Indexer.Initialize(Stream, m_header.BlockSize, GetNextNewNodeIndex, m_header.RootNodeLevel, m_header.RootNodeIndexAddress);
     LeafStorage.Initialize(Stream, m_header.BlockSize, GetNextNewNodeIndex, Indexer);
 }
Exemple #5
0
        private void UpdateBoundsOfNode(Node <TKey> leftNode, Node <TKey> rightNode)
        {
            TKey oldLowerKey = new TKey();
            TKey newLowerKey = new TKey();

            rightNode.LowerKey.CopyTo(oldLowerKey);
            newLowerKey.Read(rightNode.GetReadPointerAfterHeader()); //ToDo: Make Generic
            rightNode.LowerKey = newLowerKey;
            leftNode.UpperKey  = newLowerKey;

            SparseIndex.UpdateKey(oldLowerKey, newLowerKey, (byte)(Level + 1));
        }
        /// <summary>
        /// Initializes the required parameters for this tree to function. Must be called once.
        /// </summary>
        /// <param name="stream">the stream to use.</param>
        /// <param name="blockSize">the size of each block</param>
        /// <param name="getNextNewNodeIndex"></param>
        /// <param name="sparseIndex"></param>
        public void Initialize(BinaryStreamPointerBase stream, int blockSize, Func <uint> getNextNewNodeIndex, SparseIndex <TKey> sparseIndex)
        {
            if (m_initialized)
            {
                throw new Exception("Duplicate calls to initialize");
            }
            m_initialized = true;

            InitializeNode(stream, blockSize);

            m_tempNode1           = new Node <TKey>(stream, blockSize, Level);
            m_tempNode2           = new Node <TKey>(stream, blockSize, Level);
            SparseIndex           = sparseIndex;
            m_minRecordNodeBytes  = BlockSize >> 2;
            m_getNextNewNodeIndex = getNextNewNodeIndex;

            InitializeType();
        }
        /// <summary>
        /// Splits the current node and then inserts the provided key/value into the correct node.
        /// </summary>
        private void SplitNodeThenInsert(TKey key, TValue value)
        {
            uint currentNode  = NodeIndex;
            uint newNodeIndex = m_getNextNewNodeIndex();

            TKey dividingKey = new TKey(); //m_tempKey;

            Split(newNodeIndex, dividingKey);

            SetNodeIndex(currentNode);
            if (IsKeyInsideBounds(key))
            {
                InsertUnlessFull(~GetIndexOf(key), key, value);
                UpperKey.CopyTo(dividingKey);
            }
            else
            {
                SeekToRightSibling();
                InsertUnlessFull(~GetIndexOf(key), key, value);
                LowerKey.CopyTo(dividingKey);
            }

            SparseIndex.Add(dividingKey, newNodeIndex, (byte)(Level + 1));
        }
        public static void TestNode <TKey, TValue>(SortedTreeNodeBase <TKey, TValue> node, TreeNodeRandomizerBase <TKey, TValue> randomizer, int count)
            where TKey : SnapTypeBase <TKey>, new()
            where TValue : SnapTypeBase <TValue>, new()
        {
            int  Max       = count;
            uint rootKey   = 0;
            byte rootLevel = 0;

            uint        nextKeyIndex = 2;
            bool        hasChanged   = false;
            Func <uint> getNextKey   = () =>
            {
                nextKeyIndex++;
                return(nextKeyIndex - 1);
            };

            StringBuilder sb = new StringBuilder();

            using (BinaryStream bs = new BinaryStream())
            {
                const int          pageSize = 512;
                SparseIndex <TKey> sparse   = new SparseIndex <TKey>();
                sparse.Initialize(bs, pageSize, getNextKey, 0, 1);
                node.Initialize(bs, pageSize, getNextKey, sparse);
                node.CreateEmptyNode(1);

                TKey   key    = new TKey();
                TKey   key2   = new TKey();
                TValue value  = new TValue();
                TValue value2 = new TValue();

                randomizer.Reset(Max);
                for (int x = 0; x < Max; x++)
                {
                    randomizer.Next();
                    //Add the next point
                    randomizer.GetRandom(x, key, value);

                    //node.WriteNodeData(sb);

                    if (!node.TryInsert(key, value))
                    {
                        throw new Exception();
                    }

                    //node.WriteNodeData(sb);
                    //File.WriteAllText("c:\\temp\\temp.log", sb.ToString());


                    //Check if all points exist
                    for (int y = 0; y <= x; y++)
                    {
                        randomizer.GetRandom(y, key, value);
                        if (!node.TryGet(key, value2))
                        {
                            throw new Exception();
                        }
                        if (!value.IsEqualTo(value2))
                        {
                            throw new Exception();
                        }
                    }

                    //Check if scanner works.
                    SortedTreeScannerBase <TKey, TValue> scanner = node.CreateTreeScanner();
                    scanner.SeekToStart();
                    for (int y = 0; y <= x; y++)
                    {
                        randomizer.GetInSequence(y, key, value);
                        if (!scanner.Read(key2, value2))
                        {
                            throw new Exception();
                        }
                        if (!key.IsEqualTo(key2))
                        {
                            throw new Exception();
                        }
                        if (!value.IsEqualTo(value2))
                        {
                            throw new Exception();
                        }
                    }
                    if (scanner.Read(key2, value2))
                    {
                        throw new Exception();
                    }
                }

                node = node;
            }
        }
        internal static void TestSpeed <TKey, TValue>(SortedTreeNodeBase <TKey, TValue> nodeInitializer, TreeNodeRandomizerBase <TKey, TValue> randomizer, int count, int pageSize)
            where TKey : SnapTypeBase <TKey>, new()
            where TValue : SnapTypeBase <TValue>, new()
        {
            int Max = count;

            uint        nextKeyIndex = 2;
            Func <uint> getNextKey   = () =>
            {
                nextKeyIndex++;
                return(nextKeyIndex - 1);
            };


            using (BinaryStream bs = new BinaryStream())
            {
                randomizer.Reset(Max);
                for (int x = 0; x < Max; x++)
                {
                    randomizer.Next();
                }

                TKey   key   = new TKey();
                TValue value = new TValue();
                SortedTreeNodeBase <TKey, TValue> node = null;

                System.Console.WriteLine(StepTimer.Time(count, (sw) =>
                {
                    nextKeyIndex = 2;
                    node         = nodeInitializer.Clone(0);
                    SparseIndex <TKey> sparse = new SparseIndex <TKey>();
                    sparse.Initialize(bs, pageSize, getNextKey, 0, 1);
                    node.Initialize(bs, pageSize, getNextKey, sparse);
                    node.CreateEmptyNode(1);
                    sw.Start();
                    for (int x = 0; x < Max; x++)
                    {
                        //Add the next point
                        randomizer.GetRandom(x, key, value);

                        if (!node.TryInsert(key, value))
                        {
                            throw new Exception();
                        }
                    }
                    sw.Stop();
                }));


                System.Console.WriteLine(StepTimer.Time(count, () =>
                {
                    for (int x = 0; x < Max; x++)
                    {
                        //Add the next point
                        randomizer.GetRandom(x, key, value);

                        if (!node.TryGet(key, value))
                        {
                            throw new Exception();
                        }
                    }
                }));



                System.Console.WriteLine(StepTimer.Time(count, () =>
                {
                    SortedTreeScannerBase <TKey, TValue> scanner = node.CreateTreeScanner();
                    scanner.SeekToStart();
                    while (scanner.Read(key, value))
                    {
                        ;
                    }
                }));

                node = node;
            }
        }
Exemple #10
0
        //ToDO: Checked
        protected bool TryRemove2(TKey key)
        {
            NavigateToNode(key);

            int index = GetIndexOf(key);

            if (index < 0)
            {
                return(false);
            }

            if (!RemoveUnlessOverflow(index))
            {
                //ToDo:SplitAndThenRemove
                throw new NotImplementedException();
            }

            if (ValidBytes > m_minRecordNodeBytes) //if the node has not underflowed, we can exit early.
            {
                return(true);
            }
            if (IsRightSiblingIndexNull && IsLeftSiblingIndexNull) //If there are no nodes to combine with, we can quit early.
            {
                return(true);
            }
            if (RecordCount > 0 && (IsRightSiblingIndexNull || IsLeftSiblingIndexNull)) //There can be fewer than the minimum it is the first or last node on the level.
            {
                return(true);
            }

            bool canCombineWithLeft;
            bool canCombineWithRight;

            SparseIndex.CanCombineWithSiblings(LowerKey, (byte)(Level + 1), out canCombineWithLeft, out canCombineWithRight);


            if (RecordCount == 0) //Only will occur if the right or left node is empty (but not both)
            {
                if (canCombineWithLeft && IsRightSiblingIndexNull)
                {
                    CombineNodes(LeftSiblingNodeIndex, NodeIndex);
                }
                else if (canCombineWithRight && IsLeftSiblingIndexNull)
                {
                    CombineNodes(NodeIndex, RightSiblingNodeIndex);
                }
                else
                {
                    throw new Exception("Should never reach this condition");
                }
                return(true);
            }


            int deltaBytesWhenCombining = MaxOverheadWithCombineNodes - HeaderSize;

            if (IsRightSiblingIndexNull) //We can only combine with the left node.
            {
                if (!canCombineWithLeft)
                {
                    throw new Exception("Should never reach this condition");
                }

                if (ValidBytes + GetValidBytes(LeftSiblingNodeIndex) + deltaBytesWhenCombining < BlockSize)
                {
                    CombineNodes(LeftSiblingNodeIndex, NodeIndex);
                }
                else
                {
                    RebalanceNodes(LeftSiblingNodeIndex, NodeIndex);
                }
            }
            else if (IsLeftSiblingIndexNull) //We can only combine with the right node.
            {
                if (!canCombineWithRight)
                {
                    throw new Exception("Should never reach this condition");
                }

                if (ValidBytes + GetValidBytes(RightSiblingNodeIndex) + deltaBytesWhenCombining < BlockSize)
                {
                    CombineNodes(NodeIndex, RightSiblingNodeIndex);
                }
                else
                {
                    RebalanceNodes(NodeIndex, RightSiblingNodeIndex);
                }
            }
            else //I can combine with the right or the left node
            {
                if (canCombineWithLeft && ValidBytes + GetValidBytes(LeftSiblingNodeIndex) + deltaBytesWhenCombining < BlockSize)
                {
                    CombineNodes(LeftSiblingNodeIndex, NodeIndex);
                }
                else if (canCombineWithRight && ValidBytes + GetValidBytes(RightSiblingNodeIndex) + deltaBytesWhenCombining < BlockSize)
                {
                    CombineNodes(NodeIndex, RightSiblingNodeIndex);
                }
                else if (canCombineWithLeft)
                {
                    RebalanceNodes(LeftSiblingNodeIndex, NodeIndex);
                }
                else if (canCombineWithRight)
                {
                    RebalanceNodes(NodeIndex, RightSiblingNodeIndex);
                }
                else
                {
                    throw new Exception("Should never reach this condition");
                }
            }
            return(true);
        }