public unsafe Report GetNumberOfPreAllocatedFreePages() { var fst = _parentTree.FixedTreeFor(AllocationStorage, valSize: BitmapSize); if (fst.NumberOfEntries == 0) { return(new Report()); } var free = 0; using (var it = fst.Iterate()) { if (it.Seek(long.MinValue) == false) { throw new InvalidOperationException($"Could not seek to the first element of {fst.Name} tree"); } Slice slice; using (it.Value(out slice)) { byte *ptr = slice.Content.Ptr; for (int i = 0; i < NumberOfPagesInSection; i++) { if (PtrBitVector.GetBitInPointer(ptr, i) == false) { free++; } } } } int amountOfPagesActuallyAllocated = GetNumberOfPagesToAllocate(); return(new Report { NumberOfOriginallyAllocatedPages = fst.NumberOfEntries * amountOfPagesActuallyAllocated, NumberOfFreePages = free }); }
public unsafe Page AllocateSinglePage(long nearbyPage) { var fst = _parentTree.FixedTreeFor(AllocationStorage, valSize: BitmapSize); using (var it = fst.Iterate()) { Page page; if (it.Seek(nearbyPage)) // found a value >= from the nearby page { if (it.CurrentKey > nearbyPage) { // go back one step if we can if (it.MovePrev() == false) { it.Seek(nearbyPage); // if we can't, go back to the original find } } } else // probably it is on the last entry, after the first page, so we'll use the last entry { if (it.SeekToLast() == false) { // shouldn't actuallly happen, but same behavior as running out of space page = AllocateMoreSpace(fst); SetValue(fst, page.PageNumber, 0); return(page); } } var startPage = it.CurrentKey; while (true) { Slice slice; using (it.Value(out slice)) { var hasSpace = false; var buffer = (ulong *)(slice.Content.Ptr); for (int i = 0; i < BitmapSize / sizeof(ulong); i++) { if (buffer[i] != ulong.MaxValue) { hasSpace = true; break; } } if (hasSpace == false) { if (TryMoveNextCyclic(it, startPage) == false) { break; } } for (int i = 0; i < BitmapSize * 8; i++) { if (PtrBitVector.GetBitInPointer(buffer, i) == false) { var currentSectionStart = it.CurrentKey; SetValue(fst, currentSectionStart, i); return(_llt.ModifyPage(currentSectionStart + i)); } } if (TryMoveNextCyclic(it, startPage) == false) { break; } } } page = AllocateMoreSpace(fst); SetValue(fst, page.PageNumber, 0); return(page); } }