📄 storageimpl.java
字号:
if (multiclientSupport) {
beginThreadTransaction(READ_WRITE_TRANSACTION);
}
byte[] buf = new byte[Header.sizeof];
int rc = file.read(0, buf);
if (rc > 0 && rc < Header.sizeof) {
throw new StorageError(StorageError.DATABASE_CORRUPTED);
}
header.unpack(buf);
if (header.curr < 0 || header.curr > 1) {
throw new StorageError(StorageError.DATABASE_CORRUPTED);
}
transactionId = header.transactionId;
if (!header.initialized) {
int indexSize = initIndexSize;
if (indexSize < dbFirstUserId) {
indexSize = dbFirstUserId;
}
indexSize = (indexSize + dbHandlesPerPage - 1) & ~(dbHandlesPerPage-1);
header.curr = currIndex = 0;
long used = Page.pageSize;
header.root[0].index = used;
header.root[0].indexSize = indexSize;
header.root[0].indexUsed = dbFirstUserId;
header.root[0].freeList = 0;
used += indexSize*8L;
header.root[1].index = used;
header.root[1].indexSize = indexSize;
header.root[1].indexUsed = dbFirstUserId;
header.root[1].freeList = 0;
used += indexSize*8L;
header.root[0].shadowIndex = header.root[1].index;
header.root[1].shadowIndex = header.root[0].index;
header.root[0].shadowIndexSize = indexSize;
header.root[1].shadowIndexSize = indexSize;
int bitmapPages =
(int)((used + Page.pageSize*(dbAllocationQuantum*8-1) - 1)
/ (Page.pageSize*(dbAllocationQuantum*8-1)));
long bitmapSize = (long)bitmapPages*Page.pageSize;
int usedBitmapSize = (int)((used + bitmapSize) >>> (dbAllocationQuantumBits + 3));
for (i = 0; i < bitmapPages; i++) {
pg = pool.putPage(used + (long)i*Page.pageSize);
byte[] bitmap = pg.data;
int n = usedBitmapSize > Page.pageSize ? Page.pageSize : usedBitmapSize;
for (int j = 0; j < n; j++) {
bitmap[j] = (byte)0xFF;
}
usedBitmapSize -= Page.pageSize;
pool.unfix(pg);
}
int bitmapIndexSize =
((dbBitmapId + dbBitmapPages)*8 + Page.pageSize - 1)
& ~(Page.pageSize - 1);
byte[] index = new byte[bitmapIndexSize];
Bytes.pack8(index, dbInvalidId*8, dbFreeHandleFlag);
for (i = 0; i < bitmapPages; i++) {
Bytes.pack8(index, (dbBitmapId+i)*8, used | dbPageObjectFlag);
used += Page.pageSize;
}
header.root[0].bitmapEnd = dbBitmapId + i;
header.root[1].bitmapEnd = dbBitmapId + i;
while (i < dbBitmapPages) {
Bytes.pack8(index, (dbBitmapId+i)*8, dbFreeHandleFlag);
i += 1;
}
header.root[0].size = used;
header.root[1].size = used;
usedSize = used;
committedIndexSize = currIndexSize = dbFirstUserId;
pool.write(header.root[1].index, index);
pool.write(header.root[0].index, index);
header.dirty = true;
header.root[0].size = header.root[1].size;
pg = pool.putPage(0);
header.pack(pg.data);
pool.flush();
pool.modify(pg);
header.initialized = true;
header.pack(pg.data);
pool.unfix(pg);
pool.flush();
} else {
int curr = header.curr;
currIndex = curr;
if (header.root[curr].indexSize != header.root[curr].shadowIndexSize) {
throw new StorageError(StorageError.DATABASE_CORRUPTED);
}
if (isDirty()) {
if (listener != null) {
listener.databaseCorrupted();
}
System.err.println("Database was not normally closed: start recovery");
header.root[1-curr].size = header.root[curr].size;
header.root[1-curr].indexUsed = header.root[curr].indexUsed;
header.root[1-curr].freeList = header.root[curr].freeList;
header.root[1-curr].index = header.root[curr].shadowIndex;
header.root[1-curr].indexSize = header.root[curr].shadowIndexSize;
header.root[1-curr].shadowIndex = header.root[curr].index;
header.root[1-curr].shadowIndexSize = header.root[curr].indexSize;
header.root[1-curr].bitmapEnd = header.root[curr].bitmapEnd;
header.root[1-curr].rootObject = header.root[curr].rootObject;
header.root[1-curr].classDescList = header.root[curr].classDescList;
header.root[1-curr].bitmapExtent = header.root[curr].bitmapExtent;
pg = pool.putPage(0);
header.pack(pg.data);
pool.unfix(pg);
pool.copy(header.root[1-curr].index, header.root[curr].index,
(header.root[curr].indexUsed*8L + Page.pageSize - 1) & ~(Page.pageSize-1));
if (listener != null) {
listener.recoveryCompleted();
}
System.err.println("Recovery completed");
}
currIndexSize = header.root[1-curr].indexUsed;
committedIndexSize = currIndexSize;
usedSize = header.root[curr].size;
}
int bitmapSize = header.root[1-currIndex].bitmapExtent == 0 ? dbBitmapPages : dbLargeBitmapPages;
bitmapPageAvailableSpace = new int[bitmapSize];
for (i = 0; i < bitmapPageAvailableSpace.length; i++) {
bitmapPageAvailableSpace[i] = Integer.MAX_VALUE;
}
currRBitmapPage = currPBitmapPage = 0;
currRBitmapOffs = currPBitmapOffs = 0;
opened = true;
reloadScheme();
if (multiclientSupport) {
endThreadTransaction();
}
}
public boolean isOpened() {
return opened;
}
static void checkIfFinal(ClassDescriptor desc) {
Class cls = desc.cls;
if (cls != null) {
for (ClassDescriptor next = desc.next; next != null; next = next.next) {
next.load();
if (cls.isAssignableFrom(next.cls)) {
desc.hasSubclasses = true;
} else if (next.cls.isAssignableFrom(cls)) {
next.hasSubclasses = true;
}
}
}
}
void reloadScheme() {
classDescMap.clear();
customAllocatorMap = null;
customAllocatorList = null;
defaultAllocator = new DefaultAllocator(this);
int descListOid = header.root[1-currIndex].classDescList;
classDescMap.put(ClassDescriptor.class,
new ClassDescriptor(this, ClassDescriptor.class));
classDescMap.put(ClassDescriptor.FieldDescriptor.class,
new ClassDescriptor(this, ClassDescriptor.FieldDescriptor.class));
if (descListOid != 0) {
ClassDescriptor desc;
descList = findClassDescriptor(descListOid);
for (desc = descList; desc != null; desc = desc.next) {
desc.load();
}
for (desc = descList; desc != null; desc = desc.next) {
if (classDescMap.get(desc.cls) == desc) {
desc.resolve();
}
if (desc.allocator != null) {
if (customAllocatorMap == null) {
customAllocatorMap = new HashMap();
customAllocatorList = new ArrayList();
}
desc.allocator.load();
customAllocatorMap.put(desc.cls, desc.allocator);
customAllocatorList.add(desc.allocator);
}
checkIfFinal(desc);
}
} else {
descList = null;
}
}
final void assignOid(IPersistent obj, int oid) {
obj.assignOid(this, oid, false);
}
final void registerClassDescriptor(ClassDescriptor desc) {
classDescMap.put(desc.cls, desc);
desc.next = descList;
descList = desc;
checkIfFinal(desc);
storeObject0(desc, false);
header.root[1-currIndex].classDescList = desc.getOid();
modified = true;
}
final ClassDescriptor getClassDescriptor(Class cls) {
ClassDescriptor desc = (ClassDescriptor)classDescMap.get(cls);
if (desc == null) {
desc = new ClassDescriptor(this, cls);
registerClassDescriptor(desc);
}
return desc;
}
public synchronized IPersistent getRoot() {
if (!opened) {
throw new StorageError(StorageError.STORAGE_NOT_OPENED);
}
int rootOid = header.root[1-currIndex].rootObject;
return (rootOid == 0) ? null : lookupObject(rootOid, null);
}
public synchronized void setRoot(IPersistent root) {
if (!opened) {
throw new StorageError(StorageError.STORAGE_NOT_OPENED);
}
if (root == null) {
header.root[1-currIndex].rootObject = 0;
} else {
if (!root.isPersistent()) {
storeObject0(root, false);
}
header.root[1-currIndex].rootObject = root.getOid();
}
modified = true;
}
public void commit() {
synchronized (backgroundGcMonitor) {
synchronized (this) {
if (!opened) {
throw new StorageError(StorageError.STORAGE_NOT_OPENED);
}
objectCache.flush();
if (customAllocatorList != null) {
Iterator iterator = customAllocatorList.iterator();
while (iterator.hasNext()) {
CustomAllocator alloc = (CustomAllocator)iterator.next();
if (alloc.isModified()) {
alloc.store();
}
alloc.commit();
}
}
if (!modified) {
return;
}
commit0();
modified = false;
}
}
}
private final void commit0()
{
int i, j, n;
int curr = currIndex;
int[] map = dirtyPagesMap;
int oldIndexSize = header.root[curr].indexSize;
int newIndexSize = header.root[1-curr].indexSize;
int nPages = committedIndexSize >>> dbHandlesPerPageBits;
Page pg;
if (newIndexSize > oldIndexSize) {
cloneBitmap(header.root[curr].index, oldIndexSize*8L);
long newIndex;
while (true) {
newIndex = allocate(newIndexSize*8L, 0);
if (newIndexSize == header.root[1-curr].indexSize) {
break;
}
free(newIndex, newIndexSize*8L);
newIndexSize = header.root[1-curr].indexSize;
}
header.root[1-curr].shadowIndex = newIndex;
header.root[1-curr].shadowIndexSize = newIndexSize;
free(header.root[curr].index, oldIndexSize*8L);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -