📄 storageimpl.java
字号:
long size;
Location next;
}
final boolean wasReserved(long pos, long size)
{
for (Location location = reservedChain; location != null; location = location.next) {
if ((pos >= location.pos && pos - location.pos < location.size)
|| (pos <= location.pos && location.pos - pos < size))
{
return true;
}
}
return false;
}
final void reserveLocation(long pos, long size)
{
Location location = new Location();
location.pos = pos;
location.size = size;
location.next = reservedChain;
reservedChain = location;
}
final void commitLocation()
{
reservedChain = reservedChain.next;
}
final void setDirty()
{
modified = true;
if (!header.dirty) {
header.dirty = true;
Page pg = pool.putPage(0);
header.pack(pg.data);
pool.flush();
pool.unfix(pg);
}
}
final Page putBitmapPage(int i) {
return putPage(getBitmapPageId(i));
}
final Page getBitmapPage(int i) {
return getPage(getBitmapPageId(i));
}
final long allocate(long size, int oid)
{
synchronized (objectCache) {
setDirty();
size = (size + dbAllocationQuantum-1) & ~(dbAllocationQuantum-1);
Assert.that(size != 0);
int objBitSize = (int)(size >> dbAllocationQuantumBits);
Assert.that(objBitSize == (size >> dbAllocationQuantumBits));
long pos;
int holeBitSize = 0;
int alignment = (int)size & (Page.pageSize-1);
int offs, firstPage, lastPage, i, j;
int holeBeforeFreePage = 0;
int freeBitmapPage = 0;
int curr = 1 - currIndex;
Page pg;
lastPage = header.root[curr].bitmapEnd - dbBitmapId;
usedSize += size;
if (alignment == 0) {
firstPage = currPBitmapPage;
offs = (currPBitmapOffs+inc-1) & ~(inc-1);
} else {
firstPage = currRBitmapPage;
offs = currRBitmapOffs;
}
while (true) {
if (alignment == 0) {
// allocate page object
for (i = firstPage; i < lastPage; i++){
int spaceNeeded = objBitSize - holeBitSize < pageBits
? objBitSize - holeBitSize : pageBits;
if (bitmapPageAvailableSpace[i] <= spaceNeeded) {
holeBitSize = 0;
offs = 0;
continue;
}
pg = getBitmapPage(i);
int startOffs = offs;
while (offs < Page.pageSize) {
if (pg.data[offs++] != 0) {
offs = (offs + inc - 1) & ~(inc-1);
holeBitSize = 0;
} else if ((holeBitSize += 8) == objBitSize) {
pos = (((long)i*Page.pageSize + offs)*8 - holeBitSize)
<< dbAllocationQuantumBits;
if (wasReserved(pos, size)) {
startOffs = offs = (offs+inc) & ~(inc-1);
holeBitSize = 0;
continue;
}
reserveLocation(pos, size);
currPBitmapPage = i;
currPBitmapOffs = offs;
extend(pos + size);
if (oid != 0) {
long prev = getPos(oid);
int marker = (int)prev & dbFlagsMask;
pool.copy(pos, prev - marker, size);
setPos(oid, pos | marker | dbModifiedFlag);
}
pool.unfix(pg);
pg = putBitmapPage(i);
int holeBytes = holeBitSize >> 3;
if (holeBytes > offs) {
memset(pg, 0, 0xFF, offs);
holeBytes -= offs;
pool.unfix(pg);
pg = putBitmapPage(--i);
offs = Page.pageSize;
}
while (holeBytes > Page.pageSize) {
memset(pg, 0, 0xFF, Page.pageSize);
holeBytes -= Page.pageSize;
bitmapPageAvailableSpace[i] = 0;
pool.unfix(pg);
pg = putBitmapPage(--i);
}
memset(pg, offs-holeBytes, 0xFF, holeBytes);
commitLocation();
pool.unfix(pg);
return pos;
}
}
if (startOffs == 0 && holeBitSize == 0
&& spaceNeeded < bitmapPageAvailableSpace[i])
{
bitmapPageAvailableSpace[i] = spaceNeeded;
}
offs = 0;
pool.unfix(pg);
}
} else {
for (i = firstPage; i < lastPage; i++){
int spaceNeeded = objBitSize - holeBitSize < pageBits
? objBitSize - holeBitSize : pageBits;
if (bitmapPageAvailableSpace[i] <= spaceNeeded) {
holeBitSize = 0;
offs = 0;
continue;
}
pg = getBitmapPage(i);
int startOffs = offs;
while (offs < Page.pageSize) {
int mask = pg.data[offs] & 0xFF;
if (holeBitSize + firstHoleSize[mask] >= objBitSize) {
pos = (((long)i*Page.pageSize + offs)*8
- holeBitSize) << 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);
int marker = (int)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);
int marker = (int)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.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 = Integer.MAX_VALUE & ~(dbHandlesPerPage-1);
if (newIndexSize < currIndexSize + dbLargeBitmapPages - dbBitmapPages) {
throw new StorageError(StorageError.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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -