Example #1
0
        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
            });
        }
Example #2
0
        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);
            }
        }