public static Tree Open(LowLevelTransaction llt, Transaction tx, Slice name, TreeRootHeader *header, RootObjectType type = RootObjectType.VariableSizeTree, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { var tree = new Tree(llt, tx, header->RootPageNumber, name, isIndexTree, newPageAllocator) { _state = { RootObjectType = type, PageCount = header->PageCount, BranchPages = header->BranchPages, Depth = header->Depth, OverflowPages = header->OverflowPages, LeafPages = header->LeafPages, NumberOfEntries = header->NumberOfEntries, Flags = header->Flags } }; if ((tree.State.Flags & TreeFlags.LeafsCompressed) == TreeFlags.LeafsCompressed) { tree.InitializeCompression(); } return(tree); }
internal void SetNewPageAllocator(NewPageAllocator newPageAllocator) { Debug.Assert(newPageAllocator != null); _newPageAllocator = newPageAllocator; HasNewPageAllocator = true; }
public static Tree Create(LowLevelTransaction llt, Transaction tx, Slice name, TreeFlags flags = TreeFlags.None, RootObjectType type = RootObjectType.VariableSizeTree, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { if (type != RootObjectType.VariableSizeTree && type != RootObjectType.Table) { ThrowInvalidTreeCreateType(); } var newPage = newPageAllocator?.AllocateSinglePage(0) ?? llt.AllocatePage(1); TreePage newRootPage = PrepareTreePage(TreePageFlags.Leaf, 1, newPage); var tree = new Tree(llt, tx, newRootPage.PageNumber, name, isIndexTree, newPageAllocator) { _state = { RootObjectType = type, Depth = 1, Flags = flags, } }; if ((flags & TreeFlags.LeafsCompressed) == TreeFlags.LeafsCompressed) { tree.InitializeCompression(); } tree.State.RecordNewPage(newRootPage, 1); return(tree); }
public static PreAllocatedBuffersReport GetReport(NewPageAllocator preAllocatedBuffers, bool includeDetails) { var buffersReport = preAllocatedBuffers.GetNumberOfPreAllocatedFreePages(); var allocationTreeReport = GetReport(preAllocatedBuffers.GetAllocationStorageFst(), includeDetails); return(new PreAllocatedBuffersReport { AllocatedSpaceInBytes = (buffersReport.NumberOfFreePages + allocationTreeReport.PageCount) * Constants.Storage.PageSize, PreAllocatedBuffersSpaceInBytes = buffersReport.NumberOfFreePages * Constants.Storage.PageSize, NumberOfPreAllocatedPages = buffersReport.NumberOfFreePages, AllocationTree = allocationTreeReport, OriginallyAllocatedSpaceInBytes = (buffersReport.NumberOfOriginallyAllocatedPages + allocationTreeReport.PageCount) * Constants.Storage.PageSize }); }
public void Should_throw_on_attempt_to_free_page_which_was_not_allocated_by_NewPageAllocator() { using (var tx = Env.WriteTransaction()) { var parent = tx.CreateTree("parent"); var allocator = new NewPageAllocator(tx.LowLevelTransaction, parent); allocator.Create(); var pageAllocatedDirectly = tx.LowLevelTransaction.AllocatePage(1); Assert.Throws <InvalidOperationException>(() => allocator.FreePage(pageAllocatedDirectly.PageNumber)); } }
public void Invalid_usage_of_DirectAdds() { var numberOfItems = 100; ushort valueSize = Constants.Storage.PageSize / 16; Slice fstName; using (Slice.From(Allocator, "ccc", out fstName)) using (var tx = Env.WriteTransaction()) { var parent = tx.CreateTree("parent"); var allocator = new NewPageAllocator(tx.LowLevelTransaction, parent); allocator.Create(); for (int i = 0; i < 6; i++) { parent.Add($"aaaaa-{i}", new byte[1000]); } parent.Add($"dummy-8", new byte[1300]); for (int i = 0; i < 6; i++) { parent.Delete($"aaaaa-{i}"); } for (int i = 0; i < NewPageAllocator.NumberOfPagesInSection - 1; i++) { allocator.AllocateSinglePage(0); } var fst = new FixedSizeTree(tx.LowLevelTransaction, parent, fstName, valueSize, newPageAllocator: allocator); var bytes = new byte[valueSize]; Slice val; using (Slice.From(Allocator, bytes, out val)) { for (var i = 0; i < numberOfItems; i++) { fst.Add(i, val); } } tx.Commit(); } }
public static Tree Open(LowLevelTransaction llt, Transaction tx, Slice name, TreeRootHeader *header, RootObjectType type = RootObjectType.VariableSizeTree, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { return(new Tree(llt, tx, header->RootPageNumber, name, isIndexTree, newPageAllocator) { _state = { RootObjectType = type, PageCount = header->PageCount, BranchPages = header->BranchPages, Depth = header->Depth, OverflowPages = header->OverflowPages, LeafPages = header->LeafPages, NumberOfEntries = header->NumberOfEntries, Flags = header->Flags } }); }
public Tree ReadTree(Slice treeName, RootObjectType type = RootObjectType.VariableSizeTree, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { EnsureTrees(); Tree tree; if (_trees.TryGetValue(treeName, out tree)) { if (newPageAllocator == null) { return(tree); } if (tree.HasNewPageAllocator == false) { tree.SetNewPageAllocator(newPageAllocator); } return(tree); } TreeRootHeader *header = (TreeRootHeader *)_lowLevelTransaction.RootObjects.DirectRead(treeName); if (header != null) { if (header->RootObjectType != type) { ThrowInvalidTreeType(treeName, type, header); } tree = Tree.Open(_lowLevelTransaction, this, treeName, header, type, isIndexTree, newPageAllocator); if ((tree.State.Flags & TreeFlags.LeafsCompressed) == TreeFlags.LeafsCompressed) { tree.InitializeCompression(); } _trees.Add(treeName, tree); return(tree); } _trees.Add(treeName, null); return(null); }
public Tree ReadTree(string treeName, RootObjectType type = RootObjectType.VariableSizeTree, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { Slice treeNameSlice; Slice.From(Allocator, treeName, ByteStringType.Immutable, out treeNameSlice); return(ReadTree(treeNameSlice, type, isIndexTree, newPageAllocator)); }
public FixedSizeTree GetGlobalFixedSizeTree(Slice name, ushort valSize, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { if (_globalFixedSizeTree == null) { _globalFixedSizeTree = new Dictionary <Slice, FixedSizeTree>(SliceStructComparer.Instance); } FixedSizeTree tree; if (_globalFixedSizeTree.TryGetValue(name, out tree) == false) { tree = new FixedSizeTree(LowLevelTransaction, LowLevelTransaction.RootObjects, name, valSize, isIndexTree: isIndexTree, newPageAllocator: newPageAllocator); _globalFixedSizeTree[tree.Name] = tree; } else if (newPageAllocator != null && tree.HasNewPageAllocator == false) { tree.SetNewPageAllocator(newPageAllocator); } return(tree); }
public Tree CreateTree(Slice name, RootObjectType type = RootObjectType.VariableSizeTree, TreeFlags flags = TreeFlags.None, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { Tree tree = ReadTree(name, type, isIndexTree, newPageAllocator); if (tree != null) { return(tree); } if (_lowLevelTransaction.Flags == TransactionFlags.ReadWrite == false) { throw new InvalidOperationException("No such tree: '" + name + "' and cannot create trees in read transactions"); } tree = Tree.Create(_lowLevelTransaction, this, name, flags); tree.State.RootObjectType = type; byte *ptr; using (_lowLevelTransaction.RootObjects.DirectAdd(name, sizeof(TreeRootHeader), out ptr)) tree.State.CopyTo((TreeRootHeader *)ptr); tree.State.IsModified = true; AddTree(name, tree); return(tree); }
public Tree CreateTree(string name, RootObjectType type = RootObjectType.VariableSizeTree, TreeFlags flags = TreeFlags.None, bool isIndexTree = false, NewPageAllocator newPageAllocator = null) { Slice.From(Allocator, name, ByteStringType.Immutable, out var treeNameSlice); return(CreateTree(treeNameSlice, type, flags, isIndexTree, newPageAllocator)); }
private Tree(LowLevelTransaction llt, Transaction tx, long root, Slice name, bool isIndexTree, NewPageAllocator newPageAllocator) { _llt = llt; _tx = tx; IsIndexTree = isIndexTree; Name = name; if (newPageAllocator != null) { SetNewPageAllocator(newPageAllocator); } _recentlyFoundPages = new RecentlyFoundTreePages(llt.Flags == TransactionFlags.Read ? 8 : 2); _state = new TreeMutableState(llt) { RootPageNumber = root }; }