示例#1
0
        public BTreeOnHeapLeaf <T> GetLeaf(HeapID leafHeapID, BTreeOnHeapIndexRecord leafIndexRecord)
        {
            BTreeOnHeapLeaf <T> result;

            if (!m_leavesCache.ContainsKey(leafHeapID.Value))
            {
                BTreeOnHeapLeaf <T> leaf = GetLeafFromHeap(leafHeapID);
                if (leaf != null)
                {
                    m_leavesCache.Add(leafHeapID.Value, leaf);
                }
                result = leaf;
            }
            else
            {
                result = m_leavesCache[leafHeapID.Value];
            }

            if (result != null && leafIndexRecord != null)
            {
                // The BTH index node might have changed since the leaf was stored,
                // We must not use the index node stored in the cache.
                result.Index = leafIndexRecord.Index;
            }

            return(result);
        }
        public int InsertSorted(BTreeOnHeapIndexRecord recordToInsert)
        {
            int insertIndex = GetSortedInsertIndex(recordToInsert);

            Records.Insert(insertIndex, recordToInsert);
            return(insertIndex);
        }
示例#3
0
        public void InsertIndexRecord(BTreeOnHeapIndex index, BTreeOnHeapIndexRecord record)
        {
            HeapID existingHeapID = index.HeapID;

            if (index.Records.Count < index.MaximumNumberOfRecords)
            {
                int insertIndex = index.InsertSorted(record);
                index.HeapID = ReplaceHeapItem(existingHeapID, index.GetBytes());
                if (index.HeapID.Value != existingHeapID.Value)
                {
                    if (index.ParentIndex == null)
                    {
                        // this is the root node
                        UpdateRootHeapID(index.HeapID);
                    }
                    else
                    {
                        UpdateIndexRecord(index.ParentIndex, existingHeapID, index.HeapID, index.NodeKey);
                    }
                }
                else if (insertIndex == 0 && index.ParentIndex != null)
                {
                    // Node key has been modified, we must update the parent
                    UpdateIndexRecord(index.ParentIndex, existingHeapID, index.HeapID, index.NodeKey);
                }
            }
            else
            {
                // The node is full, we have to split it
                BTreeOnHeapIndex newNode = index.Split();
                if (record.CompareTo(newNode.NodeKey) > 0)
                {
                    newNode.InsertSorted(record);
                }
                else
                {
                    int insertIndex = index.InsertSorted(record);
                    if (insertIndex == 0 && index.ParentIndex != null)
                    {
                        // Node key has been modified, we must update the parent
                        UpdateIndexRecord(index.ParentIndex, index.HeapID, index.HeapID, index.NodeKey);
                    }
                }

                if (index.ParentIndex == null)
                {
                    // this is a root page and it's full, we have to create a new root
                    index.ParentIndex = CreateNewRoot(index.NodeKey);
                }

                // Item will be replaced in place, because it has less items than before
                ReplaceHeapItem(index.HeapID, index.GetBytes());

                HeapID newNodeHeapID = AddItemToHeap(newNode.GetBytes());

                // We made sure we have a parent to add our new page to
                InsertIndexRecord(index.ParentIndex, newNode.NodeKey, newNodeHeapID);
            }
        }
示例#4
0
        public void InsertIndexRecord(BTreeOnHeapIndex index, byte[] key, HeapID hidNextLevel)
        {
            BTreeOnHeapIndexRecord indexRecord = new BTreeOnHeapIndexRecord();

            indexRecord.key          = key;
            indexRecord.hidNextLevel = hidNextLevel;
            InsertIndexRecord(index, indexRecord);
        }
示例#5
0
        /// <summary>
        /// Find the leaf BTreePage where the entry with the given key should be located
        /// We use this method for search and insertion
        /// Note: you can use record.Index to find the BTreeOnHeapIndex of the record
        /// </summary>
        private BTreeOnHeapIndexRecord FindLeafIndexRecord(byte[] key)
        {
            int keyLength = BTreeHeader.cbKey;

            if (keyLength != key.Length)
            {
                throw new ArgumentException("Key length is not valid");
            }

            if (BTreeHeader.bIdxLevels > 0)
            {
                if (BTreeHeader.hidRoot.IsEmpty)
                {
                    throw new Exception("PST is corrupted, bIdxLevels > 0 and BTH root is empty");
                }
                byte             level      = BTreeHeader.bIdxLevels;
                byte[]           indexBytes = GetHeapItem(BTreeHeader.hidRoot);
                BTreeOnHeapIndex index      = new BTreeOnHeapIndex(indexBytes, keyLength);
                index.HeapID = BTreeHeader.hidRoot;

                while (level > 0)
                {
                    BTreeOnHeapIndexRecord lastToMatch = index.Records[0];

                    for (int recordIndex = 1; recordIndex < index.Records.Count; recordIndex++)
                    {
                        BTreeOnHeapIndexRecord record = index.Records[recordIndex];
                        // All the entries in the child have key values greater than or equal to this key value.
                        if (record.CompareTo(key) <= 0)
                        {
                            lastToMatch = record;
                        }
                        else
                        {
                            break;
                        }
                    }

                    level--;

                    if (level == 0)
                    {
                        lastToMatch.Index = index;
                        return(lastToMatch);
                    }
                    else
                    {
                        byte[]           bytes      = GetHeapItem(lastToMatch.hidNextLevel);
                        BTreeOnHeapIndex childIndex = new BTreeOnHeapIndex(bytes, keyLength);
                        childIndex.ParentIndex = index;
                        childIndex.HeapID      = lastToMatch.hidNextLevel;
                        index = childIndex;
                    }
                }
            }

            return(null);
        }
        public int GetSortedInsertIndex(BTreeOnHeapIndexRecord recordToInsert)
        {
            int insertIndex = 0;

            while (insertIndex < Records.Count && recordToInsert.CompareTo(Records[insertIndex]) > 0)
            {
                insertIndex++;
            }
            return(insertIndex);
        }
        public BTreeOnHeapIndex(byte[] heapItemBytes, int keyLength)
        {
            KeyLength = keyLength;
            int offset = 0;

            while (offset < heapItemBytes.Length)
            {
                BTreeOnHeapIndexRecord record = new BTreeOnHeapIndexRecord(heapItemBytes, offset, keyLength);
                Records.Add(record);
                offset += keyLength + HeapID.Length;
            }
        }
示例#8
0
        public BTreeOnHeapIndex CreateNewRoot(byte[] nextLevelKey)
        {
            BTreeOnHeapIndex       newRoot         = new BTreeOnHeapIndex(nextLevelKey.Length);
            BTreeOnHeapIndexRecord rootIndexRecord = new BTreeOnHeapIndexRecord();

            rootIndexRecord.key          = nextLevelKey;
            rootIndexRecord.hidNextLevel = BTreeHeader.hidRoot;
            newRoot.Records.Add(rootIndexRecord);
            newRoot.HeapID = AddItemToHeap(newRoot.GetBytes());

            BTreeHeader.hidRoot = newRoot.HeapID;
            BTreeHeader.bIdxLevels++;
            UpdateBTreeHeader();

            return(newRoot);
        }
示例#9
0
        public BTreeOnHeapLeaf <T> FindLeaf(byte[] key)
        {
            BTreeOnHeapIndexRecord leafIndexRecord = FindLeafIndexRecord(key);

            // note: the leaf we refer to here is one level below the leaf index record
            HeapID leafHeapID;

            if (leafIndexRecord == null)
            {
                leafHeapID = BTreeHeader.hidRoot;
            }
            else
            {
                leafHeapID = leafIndexRecord.hidNextLevel;
            }

            return(GetLeaf(leafHeapID, leafIndexRecord));
        }
 public int CompareTo(BTreeOnHeapIndexRecord record)
 {
     return(CompareTo(record.key));
 }