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; }
/// <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; }
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; }
/// <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; }
/// <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); }
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; }
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; }
/// <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 }
/// <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); }
/// <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); }
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 }
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; }
/// <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 }
/// <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 }
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; }
/// <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 }
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); }
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]; } }
/// <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 }
/// <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++; } }
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 }
/// <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; }