Пример #1
0
 protected void DeleteIndexEntry(BTreeIndexPage indexPage, BlockID blockIDOfChild)
 {
     for (int index = 0; index < indexPage.IndexEntryList.Count; index++)
     {
         BTreeIndexEntry entry = indexPage.IndexEntryList[index];
         if (entry.BREF.bid.Value == blockIDOfChild.Value)
         {
             indexPage.IndexEntryList.RemoveAt(index);
             UpdatePageAndReferences(indexPage); // parents will now refer to the new blockID
             if (index == 0 && indexPage.ParentPage != null)
             {
                 if (indexPage.IndexEntryList.Count > 0)
                 {
                     // page key has been modified, we must update the parent as well
                     UpdateIndexEntry(indexPage.ParentPage, indexPage.BlockID, indexPage.PageKey);
                 }
                 else
                 {
                     DeleteIndexEntry(indexPage.ParentPage, indexPage.BlockID);
                     DeletePage(indexPage);
                 }
             }
         }
     }
 }
Пример #2
0
        /// <returns>Insert index</returns>
        public int InsertSorted(BTreeIndexEntry entryToInsert)
        {
            int insertIndex = GetSortedInsertIndex(entryToInsert);

            IndexEntryList.Insert(insertIndex, entryToInsert);
            return(insertIndex);
        }
Пример #3
0
        private void InsertSorted(ulong btkey, BlockID blockID)
        {
            BTreeIndexEntry entry = new BTreeIndexEntry();

            entry.BREF.bid = blockID;
            InsertSorted(entry);
        }
Пример #4
0
        protected void InsertIndexEntry(BTreeIndexPage indexPage, ulong btkey, BlockID blockID)
        {
            BTreeIndexEntry indexEntry = new BTreeIndexEntry();

            indexEntry.btkey    = btkey;
            indexEntry.BREF.bid = blockID;
            InsertIndexEntry(indexPage, indexEntry);
        }
Пример #5
0
 public override void PopulateEntries(byte[] buffer, byte numberOfEntries)
 {
     for (int index = 0; index < numberOfEntries; index++)
     {
         int             offset = index * cbEnt;
         BTreeIndexEntry entry  = new BTreeIndexEntry(buffer, offset);
         IndexEntryList.Add(entry);
     }
 }
Пример #6
0
        public int GetSortedInsertIndex(BTreeIndexEntry entryToInsert)
        {
            ulong key = entryToInsert.btkey;

            int insertIndex = 0;

            while (insertIndex < IndexEntryList.Count && key > IndexEntryList[insertIndex].btkey)
            {
                insertIndex++;
            }
            return(insertIndex);
        }
Пример #7
0
        public int GetIndexOfEntryWithMatchingRange(ulong key)
        {
            int lastToMatchIndex = 0;

            for (int index = 1; index < IndexEntryList.Count; index++)
            {
                BTreeIndexEntry entry = IndexEntryList[index];
                // All the entries in the child BTPAGE .. have key values greater than or equal to this key value.
                if (key >= entry.btkey)
                {
                    lastToMatchIndex = index;
                }
            }
            return(lastToMatchIndex);
        }
Пример #8
0
        public void CreateNewRoot()
        {
            BTreeIndexPage newRoot = BTreeIndexPage.GetEmptyIndexPage(m_bTreeRootPage.pageTrailer.ptype, m_bTreeRootPage.cLevel + 1);

            BTreeIndexEntry rootIndexEntry = new BTreeIndexEntry();

            // We make sure the old root page has been updated (to prevent the BlockID from changing during update)
            UpdatePage(m_bTreeRootPage);

            rootIndexEntry.btkey    = m_bTreeRootPage.PageKey;
            rootIndexEntry.BREF.bid = m_bTreeRootPage.BlockID;
            rootIndexEntry.BREF.ib  = 0; // this will tell BufferedBTreePageStore that the block hasn't been written yet
            newRoot.IndexEntryList.Add(rootIndexEntry);
            AddPage(newRoot);
            m_bTreeRootPage.ParentPage = newRoot;
            m_bTreeRootPage            = newRoot;
        }
Пример #9
0
        private void CascadeUpReferenceUpdate(BTreeIndexPage indexPage, ulong oldBlockID, ulong newBlockID)
        {
            int index = indexPage.GetIndexOfBlockID(oldBlockID);

            if (index >= 0)
            {
                BTreeIndexEntry entry = indexPage.IndexEntryList[index];
                entry.BREF.bid = new BlockID(newBlockID);
                entry.BREF.ib  = 0; // this will tell BufferedBTreePageStore that the block hasn't been written yet
                ulong currentBlockID = indexPage.BlockID.Value;
                UpdatePage(indexPage);
                if (currentBlockID != indexPage.BlockID.Value &&
                    indexPage.ParentPage != null)
                {
                    CascadeUpReferenceUpdate(indexPage.ParentPage, currentBlockID, indexPage.BlockID.Value);
                }
            }
        }
Пример #10
0
        protected void InsertIndexEntry(BTreeIndexPage indexPage, BTreeIndexEntry entryToInsert)
        {
            if (indexPage.IndexEntryList.Count < BTreeIndexPage.MaximumNumberOfEntries)
            {
                int insertIndex = indexPage.InsertSorted(entryToInsert);
                UpdatePageAndReferences(indexPage);
                if (insertIndex == 0 && indexPage.ParentPage != null)
                {
                    // page key has been modified, we must update the parent
                    UpdateIndexEntry(indexPage.ParentPage, indexPage.BlockID, indexPage.PageKey);
                }
            }
            else
            {
                // The tree node is full, we have to split it
                BTreeIndexPage newPage = indexPage.Split();
                if (newPage.PageKey < entryToInsert.btkey)
                {
                    newPage.InsertSorted(entryToInsert);
                }
                else
                {
                    int insertIndex = indexPage.InsertSorted(entryToInsert);
                    if (insertIndex == 0 && indexPage.ParentPage != null)
                    {
                        // page key has been modified, we must update the parent
                        UpdateIndexEntry(indexPage.ParentPage, indexPage.BlockID, indexPage.PageKey);
                    }
                }
                UpdatePageAndReferences(indexPage);
                AddPage(newPage);

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

                // We made sure we have a parent to add our new page to
                InsertIndexEntry(indexPage.ParentPage, newPage.PageKey, newPage.BlockID);
            }
        }
Пример #11
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: the returned BTreePage will have its ParentPage set (can be traversed up to the bTreeRootPage)
        /// </summary>
        protected BTreePage FindLeafBTreePage(ulong key)
        {
            BTreePage currentPage = m_bTreeRootPage;
            int       cLevel      = m_bTreeRootPage.cLevel;

            while (cLevel > 0)
            {
                int             matchingIndex = ((BTreeIndexPage)currentPage).GetIndexOfEntryWithMatchingRange(key);
                BTreeIndexEntry matchingEntry = ((BTreeIndexPage)currentPage).IndexEntryList[matchingIndex];

                BTreePage childPage = GetPage(matchingEntry.BREF);

                childPage.ParentPage = (BTreeIndexPage)currentPage;
                currentPage          = childPage;
                cLevel--;
                if (cLevel != currentPage.cLevel)
                {
                    throw new Exception("Invalid Page cLevel");
                }
            }

            return(currentPage);
        }