public string DebugDump(RawDataSmallPageHeader *pageHeader)
        {
            var sb =
                new StringBuilder(
                    $"Page {pageHeader->PageNumber}, {pageHeader->NumberOfEntries} entries, next allocation: {pageHeader->NextAllocation}")
                .AppendLine();

            for (int i = sizeof(RawDataSmallPageHeader); i < pageHeader->NextAllocation;)
            {
                var oldSize = (RawDataEntrySizes *)((byte *)pageHeader + i);
                sb.Append($"{i} - {oldSize->AllocatedSize} / {oldSize->UsedSize} - ");

                if (oldSize->UsedSize > 0)
                {
                    var tvr = new TableValueReader((byte *)pageHeader + i + sizeof(RawDataEntrySizes),
                                                   oldSize->UsedSize);

                    sb.Append(tvr.Count);
                }

                sb.AppendLine();
                i += oldSize->AllocatedSize + sizeof(RawDataEntrySizes);
            }

            return(sb.ToString());
        }
        private RawDataSmallPageHeader *DefragPage(RawDataSmallPageHeader *pageHeader)
        {
            pageHeader = ModifyPage(pageHeader);

            if (pageHeader->NumberOfEntries == 0)
            {
                pageHeader->NextAllocation = (ushort)sizeof(RawDataSmallPageHeader);
                Memory.Set((byte *)pageHeader + pageHeader->NextAllocation, 0,
                           Constants.Storage.PageSize - pageHeader->NextAllocation);

                return(pageHeader);
            }


            TemporaryPage tmp;

            using (_tx.Environment.GetTemporaryPage(_tx, out tmp))
            {
                var maxUsedPos = pageHeader->NextAllocation;
                Memory.Copy(tmp.TempPagePointer, (byte *)pageHeader, Constants.Storage.PageSize);

                pageHeader->NextAllocation = (ushort)sizeof(RawDataSmallPageHeader);
                Memory.Set((byte *)pageHeader + pageHeader->NextAllocation, 0,
                           Constants.Storage.PageSize - pageHeader->NextAllocation);

                pageHeader->NumberOfEntries = 0;
                var pos = pageHeader->NextAllocation;
                while (pos < maxUsedPos)
                {
                    var oldSize = (RawDataEntrySizes *)(tmp.TempPagePointer + pos);

                    if (oldSize->AllocatedSize <= 0)
                    {
                        VoronUnrecoverableErrorException.Raise(_tx, $"Allocated size cannot be zero or negative, but was {oldSize->AllocatedSize} in page {pageHeader->PageNumber}");
                    }

                    if (oldSize->UsedSize < 0)
                    {
                        pos += (ushort)(oldSize->AllocatedSize + sizeof(RawDataEntrySizes));
                        continue; // this was freed
                    }
                    var prevId = (pageHeader->PageNumber) * Constants.Storage.PageSize + pos;
                    var newId  = (pageHeader->PageNumber) * Constants.Storage.PageSize + pageHeader->NextAllocation;
                    if (prevId != newId)
                    {
                        OnDataMoved(prevId, newId, tmp.TempPagePointer + pos + sizeof(RawDataEntrySizes), oldSize->UsedSize);
                    }

                    var newSize = (RawDataEntrySizes *)(((byte *)pageHeader) + pageHeader->NextAllocation);
                    newSize->AllocatedSize      = oldSize->AllocatedSize;
                    newSize->UsedSize           = oldSize->UsedSize;
                    pageHeader->NextAllocation += (ushort)sizeof(RawDataEntrySizes);
                    pageHeader->NumberOfEntries++;
                    Memory.Copy(((byte *)pageHeader) + pageHeader->NextAllocation, tmp.TempPagePointer + pos + sizeof(RawDataEntrySizes),
                                oldSize->UsedSize);

                    pageHeader->NextAllocation += (ushort)oldSize->AllocatedSize;
                    pos += (ushort)(oldSize->AllocatedSize + sizeof(RawDataEntrySizes));
                }
            }
            return(pageHeader);
        }
        protected RawDataSmallPageHeader *ModifyPage(RawDataSmallPageHeader *pageHeader)
        {
            var page = _pageLocator.GetWritablePage(pageHeader->PageNumber);

            return((RawDataSmallPageHeader *)page.Pointer);
        }
示例#4
0
        protected RawDataSmallPageHeader *ModifyPage(RawDataSmallPageHeader *pageHeader)
        {
            var page = _tx.ModifyPage(pageHeader->PageNumber);

            return((RawDataSmallPageHeader *)page.Pointer);
        }
示例#5
0
        private RawDataSmallPageHeader *DefragPage(RawDataSmallPageHeader *pageHeader)
        {
            pageHeader = ModifyPage(pageHeader);

            if (pageHeader->NumberOfEntries == 0)
            {
                pageHeader->NextAllocation = (ushort)sizeof(RawDataSmallPageHeader);
                Memory.Set((byte *)pageHeader + pageHeader->NextAllocation, 0,
                           Constants.Storage.PageSize - pageHeader->NextAllocation);

                return(pageHeader);
            }

            using (_llt.Environment.GetTemporaryPage(_llt, out TemporaryPage tmp))
            {
                var maxUsedPos = pageHeader->NextAllocation;
                Memory.Copy(tmp.TempPagePointer, (byte *)pageHeader, Constants.Storage.PageSize);

                pageHeader->NextAllocation = (ushort)sizeof(RawDataSmallPageHeader);
                Memory.Set((byte *)pageHeader + pageHeader->NextAllocation, 0,
                           Constants.Storage.PageSize - pageHeader->NextAllocation);

                pageHeader->NumberOfEntries = 0;
                var pos = pageHeader->NextAllocation;

                while (pos < maxUsedPos)
                {
                    var oldSize = (RawDataEntrySizes *)(tmp.TempPagePointer + pos);

                    if (oldSize->AllocatedSize <= 0)
                    {
                        VoronUnrecoverableErrorException.Raise(_llt, $"Allocated size cannot be zero or negative, but was {oldSize->AllocatedSize} in page {pageHeader->PageNumber}");
                    }

                    if (oldSize->IsFreed)
                    {
                        pos += (ushort)(oldSize->AllocatedSize + sizeof(RawDataEntrySizes));
                        continue; // this was freed
                    }
                    var   prevId   = (pageHeader->PageNumber) * Constants.Storage.PageSize + pos;
                    var   newId    = (pageHeader->PageNumber) * Constants.Storage.PageSize + pageHeader->NextAllocation;
                    byte *entryPos = tmp.TempPagePointer + pos + sizeof(RawDataEntrySizes);
                    if (prevId != newId)
                    {
                        var size = oldSize->UsedSize;
                        if (oldSize->IsCompressed)
                        {
                            using var __ = Table.DecompressValue(_transaction, entryPos, size, out var buffer);
                            OnDataMoved(prevId, newId, buffer.Ptr, buffer.Length);
                        }
                        else
                        {
                            OnDataMoved(prevId, newId, entryPos, oldSize->UsedSize);
                        }
                    }

                    var newSize = (RawDataEntrySizes *)(((byte *)pageHeader) + pageHeader->NextAllocation);
                    newSize->AllocatedSize      = oldSize->AllocatedSize;
                    newSize->UsedSize_Buffer    = oldSize->UsedSize_Buffer;
                    pageHeader->NextAllocation += (ushort)sizeof(RawDataEntrySizes);
                    pageHeader->NumberOfEntries++;
                    Memory.Copy(((byte *)pageHeader) + pageHeader->NextAllocation, entryPos,
                                oldSize->UsedSize);

                    pageHeader->NextAllocation += (ushort)oldSize->AllocatedSize;
                    pos += (ushort)(oldSize->AllocatedSize + sizeof(RawDataEntrySizes));
                }
            }
            return(pageHeader);
        }