Esempio n. 1
0
        /// <returns>Insert index</returns>
        public int InsertSorted(BlockBTreeEntry entryToInsert)
        {
            int insertIndex = GetSortedInsertIndex(entryToInsert);

            BlockEntryList.Insert(insertIndex, entryToInsert);
            return(insertIndex);
        }
        /// <summary>
        /// The caller must update its reference to point to the new root
        /// </summary>
        public virtual void SaveChanges()
        {
            foreach (ulong blockID in m_blocksToWrite)
            {
                Block block  = m_blockBuffer[blockID];
                long  offset = AllocationHelper.AllocateSpaceForBlock(m_file, block.TotalLength);
                block.WriteToStream(m_file.BaseStream, offset);
                m_file.BlockBTree.InsertBlockEntry(block.BlockID, offset, block.DataLength);
            }

            foreach (ulong blockID in m_blocksToFree)
            {
                BlockBTreeEntry entry = m_file.FindBlockEntryByBlockID(blockID);
                entry.cRef--;
                // Any leaf BBT entry that points to a BID holds a reference count to it.
                if (entry.cRef == 1)
                {
                    // we can mark the allocation to be freed and delete the entry,
                    // We should not free the allocation until the BBT is committed.
                    m_file.MarkAllocationToBeFreed(entry.BREF.ib, Block.GetTotalBlockLength(entry.cb));
                    m_file.BlockBTree.DeleteBlockEntry(entry.BREF.bid);
                }
                else
                {
                    m_file.BlockBTree.UpdateBlockEntry(entry.BREF.bid, entry.cRef);
                }
            }

            m_blocksToWrite.Clear();
            m_blocksToFree.Clear();
        }
Esempio n. 3
0
 public override void PopulateEntries(byte[] buffer, byte numberOfEntries)
 {
     for (int index = 0; index < numberOfEntries; index++)
     {
         int             offset = index * cbEnt;
         BlockBTreeEntry entry  = new BlockBTreeEntry(buffer, offset);
         BlockEntryList.Add(entry);
     }
 }
Esempio n. 4
0
        public void InsertBlockEntry(BlockID blockID, long offset, int dataLength)
        {
            BlockBTreeEntry entryToInsert = new BlockBTreeEntry();

            entryToInsert.BREF.bid = blockID;
            entryToInsert.BREF.ib  = (ulong)offset;
            entryToInsert.cb       = (ushort)dataLength;
            entryToInsert.cRef     = 2; // Any leaf BBT entry that points to a BID holds a reference count to it
            InsertBlockEntry(entryToInsert);
        }
Esempio n. 5
0
        private int GetSortedInsertIndex(BlockBTreeEntry entryToInsert)
        {
            ulong key = entryToInsert.BREF.bid.Value;

            int insertIndex = 0;

            while (insertIndex < BlockEntryList.Count && key > BlockEntryList[insertIndex].BREF.bid.Value)
            {
                insertIndex++;
            }
            return(insertIndex);
        }
Esempio n. 6
0
        public Block FindBlockByBlockID(ulong blockID)
        {
            BlockBTreeEntry entry = FindBlockEntryByBlockID(blockID);

            if (entry != null)
            {
                return(Block.ReadFromStream(m_stream, entry.BREF, entry.cb, Header.bCryptMethod));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        public void InsertBlockEntry(BlockBTreeEntry entryToInsert)
        {
            ulong key = entryToInsert.BREF.bid.Value;
            BlockBTreeLeafPage page = (BlockBTreeLeafPage)FindLeafBTreePage(key);

            if (page.BlockEntryList.Count < BlockBTreeLeafPage.MaximumNumberOfEntries)
            {
                int insertIndex = page.InsertSorted(entryToInsert);
                UpdatePageAndReferences(page);

                if (insertIndex == 0 && page.ParentPage != null)
                {
                    // page key has been modified, we must update the parent
                    UpdateIndexEntry(page.ParentPage, page.BlockID, page.PageKey);
                }
            }
            else
            {
                // We have to split the tree node
                BlockBTreeLeafPage newPage = page.Split();
                if (newPage.PageKey < key)
                {
                    newPage.InsertSorted(entryToInsert);
                }
                else
                {
                    int insertIndex = page.InsertSorted(entryToInsert);
                    if (insertIndex == 0 && page.ParentPage != null)
                    {
                        // page key has been modified, we must update the parent
                        UpdateIndexEntry(page.ParentPage, page.BlockID, page.PageKey);
                    }
                }
                UpdatePageAndReferences(page);
                AddPage(newPage);

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

                InsertIndexEntry(page.ParentPage, newPage.PageKey, newPage.BlockID);
            }
        }
Esempio n. 8
0
        public void IncrementBlockEntryReferenceCount(BlockID blockID)
        {
            BlockBTreeEntry entry = FindBlockEntryByBlockID(blockID.LookupValue);

            UpdateBlockEntry(blockID, (ushort)(entry.cRef + 1));
        }