📄 storageimpl.java
字号:
for (j = dbBitmapPages; j < dbLargeBitmapPages; j++) {
newBitmapPageAvailableSpace[j] = Integer.MAX_VALUE;
}
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);
int marker = (int)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 != Long.MAX_VALUE && !gcDone && !gcActive) {
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;
}
}
}
final 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;
}
}
}
final void free(long pos, long size)
{
synchronized (objectCache) {
Assert.that(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);
int bitOffs = (int)quantNo & 7;
allocatedDelta -= (long)objBitSize << dbAllocationQuantumBits;
usedSize -= (long)objBitSize << dbAllocationQuantumBits;
if ((pos & (Page.pageSize-1)) == 0 && size >= Page.pageSize) {
if (pageId == currPBitmapPage && offs < currPBitmapOffs) {
currPBitmapOffs = offs;
}
}
if (pageId == currRBitmapPage && offs < currRBitmapOffs) {
currRBitmapOffs = offs;
}
bitmapPageAvailableSpace[pageId] = Integer.MAX_VALUE;
if (objBitSize > 8 - bitOffs) {
objBitSize -= 8 - bitOffs;
pg.data[offs++] &= (1 << bitOffs) - 1;
while (objBitSize + offs*8 > Page.pageSize*8) {
memset(pg, offs, 0, Page.pageSize - offs);
pool.unfix(pg);
pg = putBitmapPage(++pageId);
bitmapPageAvailableSpace[pageId] = Integer.MAX_VALUE;
objBitSize -= (Page.pageSize - offs)*8;
offs = 0;
}
while ((objBitSize -= 8) > 0) {
pg.data[offs++] = (byte)0;
}
pg.data[offs] &= (byte)~((1 << (objBitSize + 8)) - 1);
} else {
pg.data[offs] &= (byte)~(((1 << objBitSize) - 1) << bitOffs);
}
pool.unfix(pg);
}
}
final void cloneBitmap(long pos, long size)
{
synchronized (objectCache) {
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;
int bitOffs = (int)quantNo & 7;
int oid = getBitmapPageId(pageId);
pos = getPos(oid);
if ((pos & dbModifiedFlag) == 0) {
dirtyPagesMap[oid >>> (dbHandlesPerPageBits+5)]
|= 1 << ((oid >>> dbHandlesPerPageBits) & 31);
allocate(Page.pageSize, oid);
cloneBitmap(pos & ~dbFlagsMask, Page.pageSize);
}
if (objBitSize > 8 - bitOffs) {
objBitSize -= 8 - bitOffs;
offs += 1;
while (objBitSize + offs*8 > Page.pageSize*8) {
oid = getBitmapPageId(++pageId);
pos = getPos(oid);
if ((pos & dbModifiedFlag) == 0) {
dirtyPagesMap[oid >>> (dbHandlesPerPageBits+5)]
|= 1 << ((oid >>> dbHandlesPerPageBits) & 31);
allocate(Page.pageSize, oid);
cloneBitmap(pos & ~dbFlagsMask, Page.pageSize);
}
objBitSize -= (Page.pageSize - offs)*8;
offs = 0;
}
}
}
}
public void open(String filePath) {
open(filePath, DEFAULT_PAGE_POOL_SIZE);
}
public void open(IFile file) {
open(file, DEFAULT_PAGE_POOL_SIZE);
}
public synchronized void open(String filePath, int pagePoolSize) {
IFile file = filePath.startsWith("@")
? (IFile)new MultiFile(filePath.substring(1), readOnly, noFlush)
: (IFile)new OSFile(filePath, readOnly, noFlush);
try {
open(file, pagePoolSize);
} catch (StorageError ex) {
file.close();
throw ex;
}
}
public synchronized void open(String filePath, int pagePoolSize, String cryptKey) {
Rc4File file = new Rc4File(filePath, readOnly, noFlush, cryptKey);
try {
open(file, pagePoolSize);
} catch (StorageError ex) {
file.close();
throw ex;
}
}
public void clearObjectCache() {
objectCache.clear();
}
protected OidHashTable createObjectCache(String kind, int pagePoolSize, int objectCacheSize)
{
if (pagePoolSize == INFINITE_PAGE_POOL || "strong".equals(kind)) {
return new StrongHashTable(objectCacheSize);
}
if ("soft".equals(kind)) {
return new SoftHashTable(objectCacheSize);
}
if ("weak".equals(kind)) {
return new WeakHashTable(objectCacheSize);
}
if ("pinned".equals(kind)) {
return new PinWeakHashTable(objectCacheSize);
}
return new LruObjectCache(objectCacheSize);
}
protected boolean isDirty() {
return header.dirty;
}
protected void initialize(IFile file, int pagePoolSize)
{
this.file = file;
if (lockFile && !multiclientSupport) {
if (!file.tryLock(false)) {
throw new StorageError(StorageError.STORAGE_IS_USED);
}
}
dirtyPagesMap = new int[dbDirtyPageBitmapSize/4+1];
gcThreshold = Long.MAX_VALUE;
backgroundGcMonitor = new Object();
backgroundGcStartMonitor = new Object();
gcThread = null;
gcActive = false;
gcDone = false;
allocatedDelta = 0;
nNestedTransactions = 0;
nBlockedTransactions = 0;
nCommittedTransactions = 0;
scheduledCommitTime = Long.MAX_VALUE;
transactionMonitor = new Object();
transactionLock = new PersistentResource();
modified = false;
objectCache = createObjectCache(cacheKind, pagePoolSize, objectCacheInitSize);
classDescMap = new HashMap();
descList = null;
header = new Header();
pool = new PagePool(pagePoolSize/Page.pageSize, pagePoolLruLimit);
pool.open(file);
}
public synchronized void open(IFile file, int pagePoolSize) {
Page pg;
int i;
if (opened) {
throw new StorageError(StorageError.STORAGE_ALREADY_OPENED);
}
initialize(file, pagePoolSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -