Ejemplo n.º 1
0
        public void AddPage(BTreePage page)
        {
            // It is not clear whether new BTree pages should be marked as internal or not
            // Outlook sometimes chooses to mark them as internal, and sometimes not (for both BBT and NBT)
            page.BlockID = m_file.Header.AllocateNextPageBlockID();

            m_pageBuffer.Add(page.BlockID.Value, page);
            m_pagesToWrite.Add(page.BlockID.Value);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// After modifying a page, we must update its parent's BlockID to refer to the new page
        /// </summary>
        protected void UpdatePageAndReferences(BTreePage page)
        {
            ulong currentBlockID = page.BlockID.Value;

            UpdatePage(page);

            if (currentBlockID != page.BlockID.Value &&
                page.ParentPage != null)
            {
                // we must update the parent to refer to the new page,
                // and cascade the changes up to the root page
                CascadeUpReferenceUpdate(page.ParentPage, currentBlockID, page.BlockID.Value);
            }
        }
Ejemplo n.º 3
0
        public BTreePage GetPage(BlockRef blockRef)
        {
            ulong blockID = blockRef.bid.Value;

            if (m_pageBuffer.ContainsKey(blockID))
            {
                return(m_pageBuffer[blockID]);
            }
            else
            {
                BTreePage page = BTreePage.ReadFromStream(m_file.BaseStream, blockRef);
                m_pageBuffer.Add(blockRef.bid.Value, page);
                return(page);
            }
        }
Ejemplo n.º 4
0
 private static int CompareByCLevel(BTreePage x, BTreePage y)
 {
     if (x.cLevel > y.cLevel)
     {
         return(1);
     }
     else if (x.cLevel < y.cLevel)
     {
         return(-1);
     }
     else
     {
         return(0);
     }
 }
Ejemplo n.º 5
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;
        }
Ejemplo n.º 6
0
        public void DeletePage(BTreePage page)
        {
            ulong blockID = page.BlockID.Value;

            if (m_pageBuffer.ContainsKey(blockID))
            {
                // remove the old block from the cache
                m_pageBuffer.Remove(blockID);
            }

            // no need to free a block that has not been written yet
            if (IsPagePendingWrite(page))
            {
                m_pagesToWrite.Remove(blockID);
            }
            else
            {
                m_offsetsToFree.Add(page.Offset);
            }
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        public void UpdatePage(BTreePage page)
        {
            if (IsPagePendingWrite(page))
            {
                m_pageBuffer[page.BlockID.Value] = page;
            }
            else
            {
                ulong oldBlockID = page.BlockID.Value;
                if (m_pageBuffer.ContainsKey(oldBlockID))
                {
                    // remove the old block from the buffer
                    m_pageBuffer.Remove(oldBlockID);
                }

                m_offsetsToFree.Add(page.Offset);

                page.BlockID = m_file.Header.AllocateNextPageBlockID();

                m_pageBuffer.Add(page.BlockID.Value, page);
                m_pagesToWrite.Add(page.BlockID.Value);
            }
        }
Ejemplo n.º 9
0
 public BTree(PSTFile file, BTreePage bTreeRootPage) : base(file)
 {
     m_bTreeRootPage = bTreeRootPage;
 }
Ejemplo n.º 10
0
 public BlockBTree(PSTFile file, BTreePage bTreeRootPage) : base(file, bTreeRootPage)
 {
 }
Ejemplo n.º 11
0
 public bool IsPagePendingWrite(BTreePage page)
 {
     return(IsPagePendingWrite(page.BlockID.Value));
 }
Ejemplo n.º 12
0
 public NodeBTree(PSTFile file, BTreePage bTreeRootPage) : base(file, bTreeRootPage)
 {
 }