예제 #1
0
 public void Insert(ulong txnId, byte[] key, byte[] value, bool overwrite = false, BrightstarProfiler profiler = null)
 {
     using (profiler.Step("BPlusTree.Insert"))
     {
         bool   splitRoot;
         INode  rightNode;
         byte[] rootSplitKey;
         Insert(txnId, _root, key, value, out splitRoot, out rightNode, out rootSplitKey, overwrite, profiler);
         if (splitRoot)
         {
             var newRoot = new InternalNode(_pageStore.Create(), rootSplitKey, _root.PageId, rightNode.PageId,
                                            _config);
             MarkDirty(txnId, _root, profiler);
             _modifiedNodes[newRoot.PageId] = newRoot;
             _root = newRoot;
         }
     }
 }
예제 #2
0
 /// <summary>
 /// Creates a new tree in the page store
 /// </summary>
 /// <param name="pageStore"></param>
 /// <param name="keySize">The size of the B+ tree's key (in bytes)</param>
 /// <param name="dataSize">The size of the values stored in leaf nodes (in bytes)</param>
 public BPlusTree(IPageStore pageStore, int keySize = 8, int dataSize = 64) 
 {
     _config = new BPlusTreeConfiguration(keySize, dataSize, pageStore.PageSize);
     _pageStore = pageStore;
     _modifiedNodes = new Dictionary<ulong, INode>();
     _root = new LeafNode(pageStore.Create(), 0, 0, _config);
     _nodeCache = new WeakReferenceNodeCache();
     _modifiedNodes[_root.PageId] = _root;
     _nodeCache.Add(_root);
 }
예제 #3
0
 /// <summary>
 /// Creates a new tree in the page store
 /// </summary>
 /// <param name="pageStore"></param>
 /// <param name="keySize">The size of the B+ tree's key (in bytes)</param>
 /// <param name="dataSize">The size of the values stored in leaf nodes (in bytes)</param>
 public BPlusTree(IPageStore pageStore, int keySize = 8, int dataSize = 64)
 {
     _config        = new BPlusTreeConfiguration(keySize, dataSize, pageStore.PageSize);
     _pageStore     = pageStore;
     _modifiedNodes = new Dictionary <ulong, INode>();
     _root          = new LeafNode(pageStore.Create(), 0, 0, _config);
     _nodeCache     = new WeakReferenceNodeCache();
     _modifiedNodes[_root.PageId] = _root;
     _nodeCache.Add(_root);
 }
예제 #4
0
        public ulong Write(IPageStore pageStore, ulong transactionId, BrightstarProfiler profiler)
        {
            IPage startPage   = pageStore.Create(transactionId);
            IPage currentPage = startPage;

            byte[] buff   = new byte[pageStore.PageSize];
            int    offset = 0;

            foreach (var entry in _shortValueMappings)
            {
                byte[] encodedPrefix = Encoding.UTF8.GetBytes(entry.Key);
                byte[] encodedUri    = Encoding.UTF8.GetBytes(entry.Value);
                int    totalLength   = encodedUri.Length + encodedPrefix.Length + 4;
                if (offset + totalLength > (pageStore.PageSize - 10))
                {
                    // Not enough room for the entry and the next page pointer
                    // So create a new page for this entry and write a pointer to it
                    // onto the current page
                    IPage nextPage = pageStore.Create(transactionId);
                    BitConverter.GetBytes(ushort.MaxValue).CopyTo(buff, offset);
                    offset += 2;
                    BitConverter.GetBytes(nextPage.Id).CopyTo(buff, offset);
                    currentPage.SetData(buff);
                    currentPage = nextPage;
                    buff        = new byte[pageStore.PageSize];
                    offset      = 0;
                }
                BitConverter.GetBytes((ushort)encodedPrefix.Length).CopyTo(buff, offset);
                offset += 2;
                encodedPrefix.CopyTo(buff, offset);
                offset += encodedPrefix.Length;
                BitConverter.GetBytes((ushort)encodedUri.Length).CopyTo(buff, offset);
                offset += 2;
                encodedUri.CopyTo(buff, offset);
                offset += encodedUri.Length;
            }
            // Write the end marker
            BitConverter.GetBytes(ushort.MaxValue).CopyTo(buff, offset);
            offset += 2;
            BitConverter.GetBytes(0ul).CopyTo(buff, offset);
            currentPage.SetData(buff);
            return(startPage.Id);
        }
예제 #5
0
        private void StartNewPage(ulong transactionId, BrightstarProfiler profiler)
        {
            ulong nextPage = _pageStore.Create();

            if (_currentPage > 0)
            {
                _pageStore.Write(transactionId, _currentPage, BitConverter.GetBytes(nextPage), 0, _pageStore.PageSize - 8, 8, profiler);
            }
            _currentPage = nextPage;
            _nextSegment = 0;
        }
예제 #6
0
        public void Insert(ulong txnId, byte[] key, byte[] value, bool overwrite = false, BrightstarProfiler profiler = null)
        {
            using (profiler.Step("BPlusTree.Insert"))
            {
                bool   splitRoot;
                INode  rightNode;
                byte[] rootSplitKey;
                var    root = GetNode(_rootId, profiler);
                Insert(txnId, root, key, value, out splitRoot, out rightNode, out rootSplitKey, overwrite, profiler);
                if (splitRoot)
                {
                    var newRoot = MakeInternalNode(_pageStore.Create(txnId), rootSplitKey, root.PageId,
                                                   rightNode.PageId);
                    //var newRoot = new InternalNode(_pageStore.Create(), rootSplitKey, _root.PageId, rightNode.PageId,
                    //                               _config);
                    MarkDirty(txnId, root, profiler);
                    MarkDirty(txnId, newRoot, profiler);
                    _rootId = newRoot.PageId;
#if DEBUG_BTREE
                    _config.BTreeDebug("BPlusTree.Insert: Root node has split. New root ID {0}: {1}", _rootId, newRoot.Dump());
#endif
                }
                else
                {
                    // Update root page pointer
                    // If the store is a BinaryFilePageStore, then the root page ID shouldn't change.
                    // If the store is an AppendOnlyPageSTore, then the root will change if the root
                    // is a leaf node or if a lower level split bubbled up to insert a new key into
                    // the root node.
                    _rootId = root.PageId;
#if DEBUG_BTREE
                    _config.BTreeDebug("BPlusTree.Insert: Updated root node id is {0}", _rootId);
#endif
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Copies all the indexes from this store to the specified target page store
        /// </summary>
        /// <param name="pageStore">The page store to copy to</param>
        /// <param name="txnId">The transaction Id to use in the target page store for the write</param>
        /// <returns>The ID of the root store page in the target page store</returns>
        public ulong CopyTo(IPageStore pageStore, ulong txnId)
        {
            var graphIndexId    = _graphIndex.Write(pageStore, txnId, null);
            var prefixManagerId = _prefixManager.Write(pageStore, txnId, null);
            var resourceIndexId = _resourceIndex.Write(pageStore, txnId, null);
            var subjectRelatedResourceIndexId = _subjectRelatedResourceIndex.Write(pageStore, txnId, null);
            var objectRelatedResourceIndexId  = _objectRelatedResourceIndex.Write(pageStore, txnId, null);
            var buff = CreateStoreHeader(graphIndexId, prefixManagerId, resourceIndexId, subjectRelatedResourceIndexId,
                                         objectRelatedResourceIndexId);
            var storePage = pageStore.Create(txnId);

            storePage.SetData(buff);
            storePage.SetData(buff, 0, 128);
            pageStore.Commit(txnId, null);
            return(storePage.Id);
        }
예제 #8
0
 /// <summary>
 /// Copies all the indexes from this store to the specified target page store
 /// </summary>
 /// <param name="pageStore">The page store to copy to</param>
 /// <param name="txnId">The transaction Id to use in the target page store for the write</param>
 /// <returns>The ID of the root store page in the target page store</returns>
 public ulong CopyTo(IPageStore pageStore, ulong txnId)
 {
     var graphIndexId = _graphIndex.Write(pageStore, txnId, null);
     var prefixManagerId = _prefixManager.Write(pageStore, txnId, null);
     var resourceIndexId = _resourceIndex.Write(pageStore, txnId, null);
     var subjectRelatedResourceIndexId = _subjectRelatedResourceIndex.Write(pageStore, txnId, null);
     var objectRelatedResourceIndexId = _objectRelatedResourceIndex.Write(pageStore, txnId, null);
     var buff = CreateStoreHeader(graphIndexId, prefixManagerId, resourceIndexId, subjectRelatedResourceIndexId,
                                  objectRelatedResourceIndexId);
     var storePage = pageStore.Create(txnId);
     storePage.SetData(buff);
     storePage.SetData(buff, 0, 128);
     pageStore.Commit(txnId, null);
     return storePage.Id;
 }
예제 #9
0
 public ulong Write(IPageStore pageStore, ulong transactionId, BrightstarProfiler profiler)
 {
     ulong rootPage = pageStore.Create();
     ulong currentPage = rootPage;
     var buff = new byte[pageStore.PageSize];
     int offset = 0;
     foreach (var graphIndexEntry in _allEntries)
     {
         int entrySize = String.IsNullOrEmpty(graphIndexEntry.Uri)
                             ? 1
                             : 3 + Encoding.UTF8.GetByteCount(graphIndexEntry.Uri);
         if (offset + entrySize > pageStore.PageSize - 9)
         {
             ulong nextPage = pageStore.Create();
             buff[offset] = 0xff;
             BitConverter.GetBytes(nextPage).CopyTo(buff, pageStore.PageSize - 8);
             pageStore.Write(transactionId, currentPage, buff, profiler: profiler);
             currentPage = nextPage;
             offset = 0;
         }
         else
         {
             if (String.IsNullOrEmpty(graphIndexEntry.Uri))
             {
                 // Record an empty entry
                 buff[offset++] = 2;
             }
             else
             {
                 if (graphIndexEntry.IsDeleted)
                 {
                     buff[offset++] = 1;
                 }
                 else
                 {
                     buff[offset++] = 0;
                 }
                 var uriBytes = Encoding.UTF8.GetBytes(graphIndexEntry.Uri);
                 BitConverter.GetBytes(uriBytes.Length).CopyTo(buff, offset);
                 offset += 4;
                 uriBytes.CopyTo(buff, offset);
                 offset += uriBytes.Length;
             }
         }
     }
     buff[offset] = 0xff;
     BitConverter.GetBytes(0ul).CopyTo(buff, pageStore.PageSize - 8);
     pageStore.Write(transactionId, currentPage, buff, profiler: profiler);
     return rootPage;
 }
예제 #10
0
 public ulong Write(IPageStore pageStore, ulong transactionId, BrightstarProfiler profiler)
 {
     ulong startPageId = pageStore.Create();
     ulong currentPageId = startPageId;
     byte[] currentPage = new byte[pageStore.PageSize];
     int offset = 0;
     foreach (var entry in _shortValueMappings)
     {
         byte[] encodedPrefix = Encoding.UTF8.GetBytes(entry.Key);
         byte[] encodedUri = Encoding.UTF8.GetBytes(entry.Value);
         int totalLength = encodedUri.Length + encodedPrefix.Length + 4;
         if (offset + totalLength > (pageStore.PageSize - 10))
         {
             // Not enough room for the entry and the next page pointer
             // So create a new page for this entry and write a pointer to it
             // onto the current page
             ulong nextPage = pageStore.Create();
             BitConverter.GetBytes(ushort.MaxValue).CopyTo(currentPage, offset);
             offset += 2;
             BitConverter.GetBytes(nextPage).CopyTo(currentPage, offset);
             pageStore.Write(transactionId, currentPageId, currentPage, profiler: profiler);
             currentPageId = nextPage;
             currentPage = new byte[pageStore.PageSize];
             offset = 0;
         }
         BitConverter.GetBytes((ushort)encodedPrefix.Length).CopyTo(currentPage, offset);
         offset += 2;
         encodedPrefix.CopyTo(currentPage, offset);
         offset += encodedPrefix.Length;
         BitConverter.GetBytes((ushort)encodedUri.Length).CopyTo(currentPage, offset);
         offset += 2;
         encodedUri.CopyTo(currentPage, offset);
         offset += encodedUri.Length;
     }
     // Write the end marker
     BitConverter.GetBytes(ushort.MaxValue).CopyTo(currentPage, offset);
     offset += 2;
     BitConverter.GetBytes(0ul).CopyTo(currentPage, offset);
     pageStore.Write(transactionId, currentPageId, currentPage, profiler: profiler);
     return startPageId;
 }
예제 #11
0
        private IInternalNode MakeInternalNode(ulong txnId, KeyValuePair <byte[], ulong> onlyChild)
        {
            var nodePage = _pageStore.Create(txnId);

            return(MakeInternalNode(nodePage, onlyChild.Value));
        }
예제 #12
0
        private InternalNode MakeInternalNode(KeyValuePair <byte[], ulong> onlyChild)
        {
            var nodePage = _pageStore.Create();

            return(new InternalNode(nodePage, onlyChild.Value, _config));
        }