示例#1
0
        public LeafNode(ulong nodeId, byte[] nodePage, int keyCount, BPlusTreeConfiguration treeConfiguration)
        {
            _config       = treeConfiguration;
            _keyCount     = keyCount;
            _prevPointer  = BitConverter.ToUInt64(nodePage, 4);
            _nextPointer  = BitConverter.ToUInt64(nodePage, 12);
            _keys         = new byte[_config.LeafLoadFactor][];
            _dataSegments = new byte[_config.LeafLoadFactor][];

            for (int i = 0, j = BPlusTreeConfiguration.LeafNodeHeaderSize; i < _keyCount; i++, j += _config.KeySize)
            {
                _keys[i] = new byte[_config.KeySize];
                Array.Copy(nodePage, j, _keys[i], 0, _config.KeySize);
            }
            if (_config.ValueSize > 0)
            {
                for (int i = 0, j = _config.LeafDataStartOffset; i < _keyCount; i++, j += (_config.ValueSize + 1))
                {
                    byte dataLength = nodePage[j];
                    _dataSegments[i] = new byte[dataLength];
                    Array.Copy(nodePage, j + 1, _dataSegments[i], 0, dataLength);
                }
            }
            PageId  = nodeId;
            IsDirty = false;
        }
示例#2
0
        /// <summary>
        /// Opens an existing tree in the page store
        /// </summary>
        /// <param name="pageStore"></param>
        /// <param name="rootPageId">The page ID of the BTree root node</param>
        /// <param name="keySize"></param>
        /// <param name="dataSize"></param>
        /// <param name="profiler"></param>
        public BPlusTree(IPageStore pageStore, ulong rootPageId, int keySize = 8, int dataSize = 64, BrightstarProfiler profiler = null)
        {
            _config    = new BPlusTreeConfiguration(pageStore, keySize, dataSize, pageStore.PageSize);
            _pageStore = pageStore;
            var root = GetNode(rootPageId, profiler);

            _rootId = root.PageId;
        }
示例#3
0
 public BPlusTreeBuilder(IPageStore targetPageStore, BPlusTreeConfiguration targetTreeConfiguration)
 {
     _pageStore = targetPageStore;
     _config    = targetTreeConfiguration;
     // These values are copied locally to allow us to later change the default loading from 100% to something lower if we want
     _leafLoadFactor       = _config.LeafLoadFactor;
     _internalBranchFactor = _config.InternalBranchFactor;
 }
示例#4
0
        /// <summary>
        /// Creates a new tree in the page store
        /// </summary>
        /// <param name="txnId">The transaction id for the update</param>
        /// <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(ulong txnId, IPageStore pageStore, int keySize = 8, int dataSize = 64)
        {
            _config    = new BPlusTreeConfiguration(pageStore, keySize, dataSize, pageStore.PageSize);
            _pageStore = pageStore;
            var root = MakeLeafNode(txnId);

            _rootId = root.PageId;
        }
示例#5
0
 /// <summary>
 /// Opens an existing tree in the page store
 /// </summary>
 /// <param name="pageStore"></param>
 /// <param name="rootPageId">The page ID of the BTree root node</param>
 /// <param name="keySize"></param>
 /// <param name="dataSize"></param>
 /// <param name="profiler"></param>
 public BPlusTree(IPageStore pageStore, ulong rootPageId, int keySize = 8, int dataSize = 64, BrightstarProfiler profiler = null)
 {
     _config        = new BPlusTreeConfiguration(keySize, dataSize, pageStore.PageSize);
     _pageStore     = pageStore;
     _modifiedNodes = new Dictionary <ulong, INode>();
     _nodeCache     = new WeakReferenceNodeCache();
     _root          = GetNode(rootPageId, profiler);
     _nodeCache.Add(_root);
 }
示例#6
0
 public InternalNode(ulong id, ulong onlyChild, BPlusTreeConfiguration treeConfiguration)
 {
     _config           = treeConfiguration;
     PageId            = id;
     _keyCount         = 0;
     _keys             = new byte[_config.InternalBranchFactor][];
     _childPointers    = new ulong[_config.InternalBranchFactor + 1];
     _childPointers[0] = onlyChild;
 }
示例#7
0
 private InternalNode(ulong pageId, BPlusTreeConfiguration treeConfiguration)
 {
     _config        = treeConfiguration;
     PageId         = pageId;
     _keys          = new byte[_config.InternalBranchFactor][];
     _childPointers = new ulong[_config.InternalBranchFactor + 1];
     _keyCount      = 0;
     IsDirty        = true;
 }
示例#8
0
        /// <summary>
        /// Initializes a new node using the data contained in the specified persisten storage page
        /// </summary>
        /// <param name="page">The page used to back the node</param>
        /// <param name="keyCount">The number of keys in the node (as read from page data)</param>
        /// <param name="treeConfig">The tree configuration parameters</param>
        /// <remarks>Strictly speaking we don't have to pass the key count because it can be read from
        /// the page data. However, the code that invokes this constructor needs to check the key
        /// count value to see if a node contains a leaf or an internal node and having this constructor
        /// separate from one that specifies that the page is empty initially is also convenient</remarks>
        public InternalNode(IPage page, int keyCount, BPlusTreeConfiguration treeConfig)
        {
            _config   = treeConfig;
            _page     = page;
            _keyCount = keyCount;
#if DEBUG_BTREE
            treeConfig.BTreeDebug("+Internal {0}", page.Id);
#endif
        }
示例#9
0
        /// <summary>
        /// Creates a new tree in the page store
        /// </summary>
        /// <param name="txnId">The transaction id for the update</param>
        /// <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(ulong txnId, IPageStore pageStore, int keySize = 8, int dataSize = 64)
        {
            _config    = new BPlusTreeConfiguration(pageStore, keySize, dataSize, pageStore.PageSize);
            _pageStore = pageStore;
            var root = MakeLeafNode(txnId);

            _rootId    = root.PageId;
            _nodeCache = new WeakReferenceNodeCache();
            _nodeCache.Add(root);
        }
示例#10
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);
 }
示例#11
0
        public LeafNode(IPage page, int keyCount, BPlusTreeConfiguration treeConfiguration)
        {
            _page        = page;
            _keyCount    = keyCount;
            _prevPointer = BitConverter.ToUInt64(_page.Data, 4);
            _nextPointer = BitConverter.ToUInt64(_page.Data, 12);
            _config      = treeConfiguration;
#if DEBUG_BTREE
            _config.BTreeDebug("+Leaf2 {0}", _page.Id);
#endif
        }
示例#12
0
 public LeafNode(ulong reservedPageId, ulong prevPointer, ulong nextPointer, BPlusTreeConfiguration treeConfig)
 {
     _config       = treeConfig;
     _keyCount     = 0;
     _prevPointer  = prevPointer;
     _nextPointer  = nextPointer;
     _keys         = new byte[_config.LeafLoadFactor][];
     _dataSegments = new byte[_config.LeafLoadFactor][];
     PageId        = reservedPageId;
     IsDirty       = true;
 }
示例#13
0
        /// <summary>
        /// Creates a new node backed by the specified persistent storage page that has only
        /// a single child node pointer
        /// </summary>
        /// <param name="page">The page used to back the node. Must be writeable.</param>
        /// <param name="onlyChild">The child node pointer</param>
        /// <param name="treeConfiguration">The tree configuration</param>
        /// <exception cref="InvalidOperationException">Raised if <paramref name="page"/> is not a writeable page</exception>
        public InternalNode(IPage page, ulong onlyChild, BPlusTreeConfiguration treeConfiguration)
        {
            _config = treeConfiguration;
            AssertWriteable(page);
            _page = page;
            _page.SetData(BitConverter.GetBytes(onlyChild), 0, PointerOffset(0), 8);
            KeyCount = 0;
#if DEBUG_BTREE
            _config.BTreeDebug("+Internal {0}", _page.Id);
#endif
        }
示例#14
0
        /// <summary>
        /// Creates a leaf node that will be backed by a new page
        /// </summary>
        /// <param name="reservedPage">The backing page for this node. Must be writeable</param>
        /// <param name="prevPointer">UNUSED</param>
        /// <param name="nextPointer">UNUSED</param>
        /// <param name="treeConfiguration">The tree configuration parameters</param>
        public LeafNode(IPage reservedPage, ulong prevPointer, ulong nextPointer,
                        BPlusTreeConfiguration treeConfiguration)
        {
            _config = treeConfiguration;
            AssertWriteable(reservedPage);
            _page    = reservedPage;
            KeyCount = 0;
            Prev     = prevPointer;
            Next     = nextPointer;
#if DEBUG_BTREE
            _config.BTreeDebug("+Leaf1 {0}", _page.Id);
#endif
        }
示例#15
0
 public InternalNode(ulong pageId, byte[] key, ulong leftChild, ulong rightChild,
                     BPlusTreeConfiguration treeConfiguration)
 {
     _config           = treeConfiguration;
     PageId            = pageId;
     _keys             = new byte[_config.InternalBranchFactor][];
     _childPointers    = new ulong[_config.InternalBranchFactor + 1];
     _keys[0]          = key; // TODO: copy key ?
     _childPointers[0] = leftChild;
     _childPointers[1] = rightChild;
     _keyCount         = 1;
     IsDirty           = true;
 }
示例#16
0
        /// <summary>
        /// Creates a new node backed by the specified persistent storage page with a single
        /// key and left and right pointers.
        /// </summary>
        /// <param name="page">The page used to back the node. Must be writeable.</param>
        /// <param name="splitKey">The key that separates left and right child pointers</param>
        /// <param name="leftPageId">The left child node pointer</param>
        /// <param name="rightPageId">The right child node pointer</param>
        /// <param name="treeConfiguration">The tree configuration</param>
        /// <exception cref="InvalidOperationException">Raised if <paramref name="page"/> is not a writeable page</exception>
        public InternalNode(IPage page, byte[] splitKey, ulong leftPageId, ulong rightPageId,
                            BPlusTreeConfiguration treeConfiguration)
        {
            _config = treeConfiguration;
            AssertWriteable(page);
            _page = page;
            _page.SetData(splitKey, 0, KeyOffset(0), _config.KeySize);
            _page.SetData(BitConverter.GetBytes(leftPageId), 0, PointerOffset(0), 8);
            _page.SetData(BitConverter.GetBytes(rightPageId), 0, PointerOffset(1), 8);
            KeyCount = 1;
#if DEBUG_BTREE
            _config.BTreeDebug("+Internal {0}", _page.Id);
#endif
        }
示例#17
0
 public InternalNode(ulong id, byte[] nodePage, int keyCount, BPlusTreeConfiguration treeConfiguration)
 {
     _config   = treeConfiguration;
     PageId    = id;
     _keyCount = keyCount;
     _keys     = new byte[_config.InternalBranchFactor][];
     for (int i = 0, offset = BPlusTreeConfiguration.InternalNodeHeaderSize;
          i < _keyCount;
          i++, offset += _config.KeySize)
     {
         _keys[i] = new byte[_config.KeySize];
         Array.Copy(nodePage, offset, _keys[i], 0, _config.KeySize);
     }
     _childPointers = ByteArrayHelper.ToUlongArray(nodePage, _config.InternalNodeChildStartOffset,
                                                   _config.InternalBranchFactor + 1);
 }
示例#18
0
 public InternalNode(ulong id, List <byte[]> keys, List <ulong> childPointers, BPlusTreeConfiguration treeConfiguration)
 {
     _config        = treeConfiguration;
     PageId         = id;
     _keyCount      = keys.Count;
     _keys          = new byte[_config.InternalBranchFactor][];
     _childPointers = new ulong[_config.InternalBranchFactor + 1];
     for (int i = 0; i < _keyCount; i++)
     {
         _keys[i] = keys[i];
     }
     for (int i = 0; i <= _keyCount; i++)
     {
         _childPointers[i] = childPointers[i];
     }
 }
示例#19
0
        /// <summary>
        /// Creates a new node backed by the specified persistent storage page
        /// containing a list of keys and child values
        /// </summary>
        /// <param name="page">The page used to back the node. Must be writeable</param>
        /// <param name="keys">The list of keys for the node</param>
        /// <param name="values">The list of values for the node</param>
        /// <param name="treeConfiguration">The tree configuration</param>
        public InternalNode(IPage page, List <byte[]> keys, List <ulong> values, BPlusTreeConfiguration treeConfiguration)
        {
            _config = treeConfiguration;
            AssertWriteable(page);
            _page    = page;
            KeyCount = keys.Count;
            int i, keyOffset, pointerOffset;

            for (i = 0, keyOffset = KeyOffset(0); i < keys.Count; i++, keyOffset += _config.KeySize)
            {
                _page.SetData(keys[i], 0, keyOffset, _config.KeySize);
            }
            for (i = 0, pointerOffset = PointerOffset(0); i < KeyCount + 1; i++, pointerOffset += 8)
            {
                _page.SetData(BitConverter.GetBytes(values[i]), 0, pointerOffset, 8);
            }
#if DEBUG_BTREE
            _config.BTreeDebug("+Internal {0}", _page.Id);
#endif
        }
示例#20
0
 /// <summary>
 /// Creates a new leaf node with content loaded from an ordered enumeration of key/value pairs
 /// </summary>
 /// <param name="reservedPageId"></param>
 /// <param name="prevPointer"></param>
 /// <param name="nextPointer"></param>
 /// <param name="treeConfiguration"></param>
 /// <param name="orderedValues">The enumerateion of key-value pairs to load into the leaf node</param>
 /// <param name="numValuesToLoad">The maximum number of key-value pairs to insert into the new leaf node</param>
 public LeafNode(ulong reservedPageId, ulong prevPointer, ulong nextPointer, BPlusTreeConfiguration treeConfiguration, IEnumerable <KeyValuePair <byte[], byte []> > orderedValues, int numValuesToLoad)
 {
     _config       = treeConfiguration;
     _prevPointer  = prevPointer;
     _nextPointer  = nextPointer;
     _keys         = new byte[_config.LeafLoadFactor][];
     _dataSegments = new byte[_config.LeafLoadFactor][];
     PageId        = reservedPageId;
     IsDirty       = true;
     _keyCount     = 0;
     foreach (var kvp in orderedValues.Take(numValuesToLoad))
     {
         _keys[_keyCount]         = new byte[_config.KeySize];
         _dataSegments[_keyCount] = new byte[_config.ValueSize];
         Array.Copy(kvp.Key, _keys[_keyCount], _config.KeySize);
         if (_config.ValueSize > 0)
         {
             Array.Copy(kvp.Value, _dataSegments[_keyCount], _config.ValueSize);
         }
         _keyCount++;
     }
 }
示例#21
0
        public LeafNode(IPage page, ulong prevPointer, ulong nextPointer,
                        BPlusTreeConfiguration treeConfiguration,
                        IEnumerable <KeyValuePair <byte[], byte[]> > orderedValues, int numValuesToLoad)
        {
            _page   = page;
            _config = treeConfiguration;
            Prev    = prevPointer;
            Next    = nextPointer;
            int numLoaded = 0;

            foreach (var kvp in orderedValues.Take(numValuesToLoad))
            {
                SetKey(numLoaded, kvp.Key);
                if (_config.ValueSize > 0)
                {
                    SetValue(numLoaded, kvp.Value);
                }
                numLoaded++;
            }
            KeyCount = numLoaded;
#if DEBUG_BTREE
            _config.BTreeDebug("+Leaf3 {0}", _page.Id);
#endif
        }
示例#22
0
 /// <summary>
 /// Creates a new empty node backed by the specified persistant storage page
 /// </summary>
 /// <param name="page">The page to be used to back the node</param>
 /// <param name="treeConfig">The tree configuration parameters</param>
 private InternalNode(IPage page, BPlusTreeConfiguration treeConfig)
 {
     _page     = page;
     _config   = treeConfig;
     _keyCount = 0;
 }