📄 storageimpl.cs
字号:
currRBitmapPage = i;
currRBitmapOffs = offs;
extend(pos + size);
if (oid != 0)
{
long prev = getPos(oid);
uint marker = (uint)prev & dbFlagsMask;
pool.copy(pos, prev - marker, size);
setPos(oid, pos | marker | dbModifiedFlag);
}
pool.unfix(pg);
pg = putBitmapPage(i);
pg.data[offs] |= (byte)((1 << (objBitSize - holeBitSize)) - 1);
if (holeBitSize != 0)
{
if (holeBitSize > offs*8)
{
memset(pg, 0, 0xFF, offs);
holeBitSize -= offs*8;
pool.unfix(pg);
pg = putBitmapPage(--i);
offs = Page.pageSize;
}
while (holeBitSize > pageBits)
{
memset(pg, 0, 0xFF, Page.pageSize);
holeBitSize -= pageBits;
bitmapPageAvailableSpace[i] = 0;
pool.unfix(pg);
pg = putBitmapPage(--i);
}
while ((holeBitSize -= 8) > 0)
{
pg.data[--offs] = (byte)0xFF;
}
pg.data[offs-1] |= (byte)~((1 << -holeBitSize) - 1);
}
pool.unfix(pg);
commitLocation();
return pos;
}
else if (maxHoleSize[mask] >= objBitSize)
{
int holeBitOffset = maxHoleOffset[mask];
pos = (((long)i*Page.pageSize + offs)*8 + holeBitOffset) << dbAllocationQuantumBits;
if (wasReserved(pos, size))
{
startOffs = offs += 1;
holeBitSize = 0;
continue;
}
reserveLocation(pos, size);
currRBitmapPage = i;
currRBitmapOffs = offs;
extend(pos + size);
if (oid != 0)
{
long prev = getPos(oid);
uint marker = (uint)prev & dbFlagsMask;
pool.copy(pos, prev - marker, size);
setPos(oid, pos | marker | dbModifiedFlag);
}
pool.unfix(pg);
pg = putBitmapPage(i);
pg.data[offs] |= (byte)(((1<<objBitSize) - 1) << holeBitOffset);
pool.unfix(pg);
commitLocation();
return pos;
}
offs += 1;
if (lastHoleSize[mask] == 8)
{
holeBitSize += 8;
}
else
{
holeBitSize = lastHoleSize[mask];
}
}
if (startOffs == 0 && holeBitSize == 0
&& spaceNeeded < bitmapPageAvailableSpace[i])
{
bitmapPageAvailableSpace[i] = spaceNeeded;
}
offs = 0;
pool.unfix(pg);
}
}
if (firstPage == 0)
{
if (freeBitmapPage > i)
{
i = freeBitmapPage;
holeBitSize = holeBeforeFreePage;
}
objBitSize -= holeBitSize;
// number of bits reserved for the object and aligned on page boundary
int skip = (objBitSize + Page.pageSize/dbAllocationQuantum - 1)
& ~(Page.pageSize/dbAllocationQuantum - 1);
// page aligned position after allocated object
pos = ((long)i << dbBitmapSegmentBits) + ((long)skip << dbAllocationQuantumBits);
long extension = (size > extensionQuantum) ? size : extensionQuantum;
int oldIndexSize = 0;
long oldIndex = 0;
int morePages = (int)((extension + Page.pageSize*(dbAllocationQuantum*8-1) - 1)
/ (Page.pageSize*(dbAllocationQuantum*8-1)));
if (i + morePages > dbLargeBitmapPages)
{
throw new StorageError(StorageError.ErrorCode.NOT_ENOUGH_SPACE);
}
if (i <= dbBitmapPages && i + morePages > dbBitmapPages)
{
// We are out of space mapped by memory default allocation bitmap
oldIndexSize = header.root[curr].indexSize;
if (oldIndexSize <= currIndexSize + dbLargeBitmapPages - dbBitmapPages)
{
int newIndexSize = oldIndexSize;
oldIndex = header.root[curr].index;
do
{
newIndexSize <<= 1;
if (newIndexSize < 0)
{
newIndexSize = int.MaxValue & ~(dbHandlesPerPage-1);
if (newIndexSize < currIndexSize + dbLargeBitmapPages - dbBitmapPages)
{
throw new StorageError(StorageError.ErrorCode.NOT_ENOUGH_SPACE);
}
break;
}
} while (newIndexSize <= currIndexSize + dbLargeBitmapPages - dbBitmapPages);
if (size + newIndexSize*8L > extensionQuantum)
{
extension = size + newIndexSize*8L;
morePages = (int)((extension + Page.pageSize*(dbAllocationQuantum*8-1) - 1)
/ (Page.pageSize*(dbAllocationQuantum*8-1)));
}
extend(pos + (long)morePages*Page.pageSize + newIndexSize*8L);
long newIndex = pos + (long)morePages*Page.pageSize;
fillBitmap(pos + (skip>>3) + (long)morePages * (Page.pageSize/dbAllocationQuantum/8),
newIndexSize >> dbAllocationQuantumBits);
pool.copy(newIndex, oldIndex, oldIndexSize*8L);
header.root[curr].index = newIndex;
header.root[curr].indexSize = newIndexSize;
}
int[] newBitmapPageAvailableSpace = new int[dbLargeBitmapPages];
Array.Copy(bitmapPageAvailableSpace, 0, newBitmapPageAvailableSpace, 0, dbBitmapPages);
for (j = dbBitmapPages; j < dbLargeBitmapPages; j++)
{
newBitmapPageAvailableSpace[j] = int.MaxValue;
}
bitmapPageAvailableSpace = newBitmapPageAvailableSpace;
for (j = 0; j < dbLargeBitmapPages - dbBitmapPages; j++)
{
setPos(currIndexSize + j, dbFreeHandleFlag);
}
header.root[curr].bitmapExtent = currIndexSize;
header.root[curr].indexUsed = currIndexSize += dbLargeBitmapPages - dbBitmapPages;
}
extend(pos + (long)morePages*Page.pageSize);
long adr = pos;
int len = objBitSize >> 3;
// fill bitmap pages used for allocation of object space with 0xFF
while (len >= Page.pageSize)
{
pg = pool.putPage(adr);
memset(pg, 0, 0xFF, Page.pageSize);
pool.unfix(pg);
adr += Page.pageSize;
len -= Page.pageSize;
}
// fill part of last page responsible for allocation of object space
pg = pool.putPage(adr);
memset(pg, 0, 0xFF, len);
pg.data[len] = (byte)((1 << (objBitSize&7))-1);
pool.unfix(pg);
// mark in bitmap newly allocated object
fillBitmap(pos + (skip>>3), morePages * (Page.pageSize/dbAllocationQuantum/8));
j = i;
while (--morePages >= 0)
{
setPos(getBitmapPageId(j++), pos | dbPageObjectFlag | dbModifiedFlag);
pos += Page.pageSize;
}
header.root[curr].bitmapEnd = j + dbBitmapId;
j = i + objBitSize / pageBits;
if (alignment != 0)
{
currRBitmapPage = j;
currRBitmapOffs = 0;
}
else
{
currPBitmapPage = j;
currPBitmapOffs = 0;
}
while (j > i)
{
bitmapPageAvailableSpace[--j] = 0;
}
pos = ((long)i*Page.pageSize*8 - holeBitSize) << dbAllocationQuantumBits;
if (oid != 0)
{
long prev = getPos(oid);
uint marker = (uint)prev & dbFlagsMask;
pool.copy(pos, prev - marker, size);
setPos(oid, pos | marker | dbModifiedFlag);
}
if (holeBitSize != 0)
{
reserveLocation(pos, size);
while (holeBitSize > pageBits)
{
holeBitSize -= pageBits;
pg = putBitmapPage(--i);
memset(pg, 0, 0xFF, Page.pageSize);
bitmapPageAvailableSpace[i] = 0;
pool.unfix(pg);
}
pg = putBitmapPage(--i);
offs = Page.pageSize;
while ((holeBitSize -= 8) > 0)
{
pg.data[--offs] = (byte)0xFF;
}
pg.data[offs-1] |= (byte)~((1 << -holeBitSize) - 1);
pool.unfix(pg);
commitLocation();
}
if (oldIndex != 0)
{
free(oldIndex, oldIndexSize*8L);
}
return pos;
}
if (gcThreshold != Int64.MaxValue && !gcDone)
{
allocatedDelta -= size;
usedSize -= size;
gc0();
currRBitmapPage = currPBitmapPage = 0;
currRBitmapOffs = currPBitmapOffs = 0;
return allocate(size, oid);
}
freeBitmapPage = i;
holeBeforeFreePage = holeBitSize;
holeBitSize = 0;
lastPage = firstPage + 1;
firstPage = 0;
offs = 0;
}
}
}
void fillBitmap(long adr, int len)
{
while (true)
{
int off = (int)adr & (Page.pageSize-1);
Page pg = pool.putPage(adr - off);
if (Page.pageSize - off >= len)
{
memset(pg, off, 0xFF, len);
pool.unfix(pg);
break;
}
else
{
memset(pg, off, 0xFF, Page.pageSize - off);
pool.unfix(pg);
adr += Page.pageSize - off;
len -= Page.pageSize - off;
}
}
}
internal void free(long pos, long size)
{
lock (objectCache)
{
Debug.Assert(pos != 0 && (pos & (dbAllocationQuantum - 1)) == 0);
long quantNo = pos >> dbAllocationQuantumBits;
int objBitSize = (int)((size+dbAllocationQuantum-1) >> dbAllocationQuantumBits);
int pageId = (int) (quantNo >> (Page.pageSizeLog + 3));
int offs = (int) (quantNo & (Page.pageSize * 8 - 1)) >> 3;
Page pg = putBitmapPage(pageId);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -