📄 storageimpl.java
字号:
}
header.root[1-curr].shadowIndex = newIndex;
header.root[1-curr].shadowIndexSize = newIndexSize;
free(header.root[curr].index, oldIndexSize*8L);
}
long currSize = header.root[1-curr].size;
for (i = 0; i < nPages; i++) {
if ((map[i >> 5] & (1 << (i & 31))) != 0) {
Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i*Page.pageSize);
Page dstIndex = pool.getPage(header.root[curr].index + (long)i*Page.pageSize);
for (j = 0; j < Page.pageSize; j += 8) {
long pos = Bytes.unpack8(dstIndex.data, j);
if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize) {
if ((pos & dbFreeHandleFlag) == 0) {
if ((pos & dbPageObjectFlag) != 0) {
free(pos & ~dbFlagsMask, Page.pageSize);
} else if (pos != 0) {
int offs = (int)pos & (Page.pageSize-1);
pg = pool.getPage(pos-offs);
free(pos, ObjectHeader.getSize(pg.data, offs));
pool.unfix(pg);
}
}
}
}
pool.unfix(srcIndex);
pool.unfix(dstIndex);
}
}
n = committedIndexSize & (dbHandlesPerPage-1);
if (n != 0 && (map[i >> 5] & (1 << (i & 31))) != 0) {
Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i*Page.pageSize);
Page dstIndex = pool.getPage(header.root[curr].index + (long)i*Page.pageSize);
j = 0;
do {
long pos = Bytes.unpack8(dstIndex.data, j);
if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize) {
if ((pos & dbFreeHandleFlag) == 0) {
if ((pos & dbPageObjectFlag) != 0) {
free(pos & ~dbFlagsMask, Page.pageSize);
} else if (pos != 0) {
int offs = (int)pos & (Page.pageSize-1);
pg = pool.getPage(pos - offs);
free(pos, ObjectHeader.getSize(pg.data, offs));
pool.unfix(pg);
}
}
}
j += 8;
} while (--n != 0);
pool.unfix(srcIndex);
pool.unfix(dstIndex);
}
for (i = 0; i <= nPages; i++) {
if ((map[i >> 5] & (1 << (i & 31))) != 0) {
pg = pool.putPage(header.root[1-curr].index + (long)i*Page.pageSize);
for (j = 0; j < Page.pageSize; j += 8) {
Bytes.pack8(pg.data, j, Bytes.unpack8(pg.data, j) & ~dbModifiedFlag);
}
pool.unfix(pg);
}
}
if (currIndexSize > committedIndexSize) {
long page = (header.root[1-curr].index
+ committedIndexSize*8L) & ~(Page.pageSize-1);
long end = (header.root[1-curr].index + Page.pageSize - 1
+ currIndexSize*8L) & ~(Page.pageSize-1);
while (page < end) {
pg = pool.putPage(page);
for (j = 0; j < Page.pageSize; j += 8) {
Bytes.pack8(pg.data, j, Bytes.unpack8(pg.data, j) & ~dbModifiedFlag);
}
pool.unfix(pg);
page += Page.pageSize;
}
}
header.root[1-curr].usedSize = usedSize;
pg = pool.putPage(0);
header.pack(pg.data);
pool.flush();
pool.modify(pg);
Assert.that(header.transactionId == transactionId);
header.transactionId = ++transactionId;
header.curr = curr ^= 1;
header.dirty = true;
header.pack(pg.data);
pool.unfix(pg);
pool.flush();
header.root[1-curr].size = header.root[curr].size;
header.root[1-curr].indexUsed = currIndexSize;
header.root[1-curr].freeList = header.root[curr].freeList;
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;
if (currIndexSize == 0 || newIndexSize != oldIndexSize) {
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;
pool.copy(header.root[1-curr].index, header.root[curr].index,
currIndexSize*8L);
i = (currIndexSize+dbHandlesPerPage*32-1) >>> (dbHandlesPerPageBits+5);
while (--i >= 0) {
map[i] = 0;
}
} else {
for (i = 0; i < nPages; i++) {
if ((map[i >> 5] & (1 << (i & 31))) != 0) {
map[i >> 5] -= (1 << (i & 31));
pool.copy(header.root[1-curr].index + (long)i*Page.pageSize,
header.root[curr].index + (long)i*Page.pageSize,
Page.pageSize);
}
}
if (currIndexSize > i*dbHandlesPerPage &&
((map[i >> 5] & (1 << (i & 31))) != 0
|| currIndexSize != committedIndexSize))
{
pool.copy(header.root[1-curr].index + (long)i*Page.pageSize,
header.root[curr].index + (long)i*Page.pageSize,
8L*currIndexSize - (long)i*Page.pageSize);
j = i>>>5;
n = (currIndexSize + dbHandlesPerPage*32 - 1) >>> (dbHandlesPerPageBits+5);
while (j < n) {
map[j++] = 0;
}
}
}
gcDone = false;
currIndex = curr;
committedIndexSize = currIndexSize;
if (multiclientSupport) {
pool.flush();
pg = pool.putPage(0);
header.dirty = false;
header.pack(pg.data);
pool.unfix(pg);
pool.flush();
}
}
public synchronized void rollback() {
if (!opened) {
throw new StorageError(StorageError.STORAGE_NOT_OPENED);
}
objectCache.invalidate();
if (!modified) {
return;
}
rollback0();
modified = false;
}
private final void rollback0() {
int curr = currIndex;
int[] map = dirtyPagesMap;
if (header.root[1-curr].index != header.root[curr].shadowIndex) {
pool.copy(header.root[curr].shadowIndex, header.root[curr].index, 8L*committedIndexSize);
} else {
int nPages = (committedIndexSize + dbHandlesPerPage - 1) >>> dbHandlesPerPageBits;
for (int i = 0; i < nPages; i++) {
if ((map[i >> 5] & (1 << (i & 31))) != 0) {
pool.copy(header.root[curr].shadowIndex + (long)i*Page.pageSize,
header.root[curr].index + (long)i*Page.pageSize,
Page.pageSize);
}
}
}
for (int j = (currIndexSize+dbHandlesPerPage*32-1) >>> (dbHandlesPerPageBits+5);
--j >= 0;
map[j] = 0);
header.root[1-curr].index = header.root[curr].shadowIndex;
header.root[1-curr].indexSize = header.root[curr].shadowIndexSize;
header.root[1-curr].indexUsed = committedIndexSize;
header.root[1-curr].freeList = header.root[curr].freeList;
header.root[1-curr].bitmapEnd = header.root[curr].bitmapEnd;
header.root[1-curr].size = header.root[curr].size;
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;
usedSize = header.root[curr].size;
currIndexSize = committedIndexSize;
currRBitmapPage = currPBitmapPage = 0;
currRBitmapOffs = currPBitmapOffs = 0;
reloadScheme();
}
public synchronized void backup(OutputStream out) throws java.io.IOException
{
if (!opened) {
throw new StorageError(StorageError.STORAGE_NOT_OPENED);
}
objectCache.flush();
int curr = 1-currIndex;
final int nObjects = header.root[curr].indexUsed;
long indexOffs = header.root[curr].index;
int i, j, k;
int nUsedIndexPages = (nObjects + dbHandlesPerPage - 1) / dbHandlesPerPage;
int nIndexPages = (int)((header.root[curr].indexSize + dbHandlesPerPage - 1) / dbHandlesPerPage);
long totalRecordsSize = 0;
long nPagedObjects = 0;
int bitmapExtent = header.root[curr].bitmapExtent;
final long[] index = new long[nObjects];
final int[] oids = new int[nObjects];
if (bitmapExtent == 0) {
bitmapExtent = Integer.MAX_VALUE;
}
for (i = 0, j = 0; i < nUsedIndexPages; i++) {
Page pg = pool.getPage(indexOffs + (long)i*Page.pageSize);
for (k = 0; k < dbHandlesPerPage && j < nObjects; k++, j++) {
long pos = Bytes.unpack8(pg.data, k*8);
index[j] = pos;
oids[j] = j;
if ((pos & dbFreeHandleFlag) == 0) {
if ((pos & dbPageObjectFlag) != 0) {
nPagedObjects += 1;
} else if (pos != 0) {
int offs = (int)pos & (Page.pageSize-1);
Page op = pool.getPage(pos - offs);
int size = ObjectHeader.getSize(op.data, offs & ~dbFlagsMask);
size = (size + dbAllocationQuantum-1) & ~(dbAllocationQuantum-1);
totalRecordsSize += size;
pool.unfix(op);
}
}
}
pool.unfix(pg);
}
Header newHeader = new Header();
newHeader.curr = 0;
newHeader.dirty = false;
newHeader.initialized = true;
long newFileSize = (long)(nPagedObjects + nIndexPages*2 + 1)*Page.pageSize + totalRecordsSize;
newFileSize = (newFileSize + Page.pageSize-1) & ~(Page.pageSize-1);
newHeader.root = new RootPage[2];
newHeader.root[0] = new RootPage();
newHeader.root[1] = new RootPage();
newHeader.root[0].size = newHeader.root[1].size = newFileSize;
newHeader.root[0].index = newHeader.root[1].shadowIndex = Page.pageSize;
newHeader.root[0].shadowIndex = newHeader.root[1].index = Page.pageSize + (long)nIndexPages*Page.pageSize;
newHeader.root[0].shadowIndexSize = newHeader.root[0].indexSize =
newHeader.root[1].shadowIndexSize = newHeader.root[1].indexSize = nIndexPages*dbHandlesPerPage;
newHeader.root[0].indexUsed = newHeader.root[1].indexUsed = nObjects;
newHeader.root[0].freeList = newHeader.root[1].freeList = header.root[curr].freeList;
newHeader.root[0].bitmapEnd = newHeader.root[1].bitmapEnd = header.root[curr].bitmapEnd;
newHeader.root[0].rootObject = newHeader.root[1].rootObject = header.root[curr].rootObject;
newHeader.root[0].classDescList = newHeader.root[1].classDescList = header.root[curr].classDescList;
newHeader.root[0].bitmapExtent = newHeader.root[1].bitmapExtent = header.root[curr].bitmapExtent;
byte[] page = new byte[Page.pageSize];
newHeader.pack(page);
out.write(page);
long pageOffs = (long)(nIndexPages*2 + 1)*Page.pageSize;
long recOffs = (long)(nPagedObjects + nIndexPages*2 + 1)*Page.pageSize;
GenericSort.sort(new GenericSortArray() {
public int size() {
return nObjects;
}
public int compare(int i, int j) {
return index[i] < index[j] ? -1 : index[i] == index[j] ? 0 : 1;
}
public void swap(int i, int j) {
long t1 = index[i];
index[i] = index[j];
index[j] = t1;
int t2 = oids[i];
oids[i] = oids[j];
oids[j] = t2;
}
}
);
byte[] newIndex = new byte[nIndexPages*dbHandlesPerPage*8];
for (i = 0; i < nObjects; i++) {
long pos = index[i];
int oid = oids[i];
if ((pos & dbFreeHandleFlag) == 0) {
if ((pos & dbPageObjectFlag) != 0) {
Bytes.pack8(newIndex, oid*8, pageOffs | dbPageObjectFlag);
pageOffs += Page.pageSize;
} else if (pos != 0) {
Bytes.pack8(newIndex, oid*8, recOffs);
int offs = (int)pos & (Page.pageSize-1);
Page op = pool.getPage(pos - offs);
int size = ObjectHeader.getSize(op.data, offs & ~dbFlagsMask);
size = (size + dbAllocationQuantum-1) & ~(dbAllocationQuantum-1);
recOffs += size;
pool.unfix(op);
}
} else {
Bytes.pack8(newIndex, oid*8, pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -