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; } } }
/// <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); }
/// <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 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); }
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; }
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 } } }
/// <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); }
/// <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; }
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; }
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; }
private IInternalNode MakeInternalNode(ulong txnId, KeyValuePair <byte[], ulong> onlyChild) { var nodePage = _pageStore.Create(txnId); return(MakeInternalNode(nodePage, onlyChild.Value)); }
private InternalNode MakeInternalNode(KeyValuePair <byte[], ulong> onlyChild) { var nodePage = _pageStore.Create(); return(new InternalNode(nodePage, onlyChild.Value, _config)); }