📄 diskfile.java
字号:
try {
cache.clear();
file.close();
FileUtils.delete(fileName);
} catch (IOException e) {
throw Message.convertIOException(e, fileName);
} finally {
file = null;
fileName = null;
}
}
}
// private int allocateBest(int start, int blocks) {
// while (true) {
// int p = getLastUsedPlusOne(start, blocks);
// if (p == start) {
// start = p;
// break;
// }
// start = p;
// }
// allocate(start, blocks);
// return start;
// }
public void writeBack(CacheObject obj) throws SQLException {
synchronized (database) {
writeCount++;
Record record = (Record) obj;
int blockCount = record.getBlockCount();
record.prepareWrite();
go(record.getPos());
DataPage buff = rowBuff;
buff.reset();
buff.checkCapacity(blockCount * BLOCK_SIZE);
buff.writeInt(blockCount);
buff.writeInt(record.getStorageId());
record.write(buff);
buff.fill(blockCount * BLOCK_SIZE);
buff.updateChecksum();
file.write(buff.getBytes(), 0, buff.length());
record.setChanged(false);
}
}
/*
* Must be synchronized externally
*/
BitField getUsed() {
return used;
}
void updateRecord(Session session, Record record) throws SQLException {
synchronized (database) {
record.setChanged(true);
int pos = record.getPos();
Record old = (Record) cache.update(pos, record);
if (SysProperties.CHECK) {
if (old != null) {
if (old != record) {
database.checkPowerOff();
throw Message.getInternalError("old != record old=" + old + " new=" + record);
}
int blockCount = record.getBlockCount();
for (int i = 0; i < blockCount; i++) {
if (deleted.get(i + pos)) {
throw Message.getInternalError("update marked as deleted: " + (i + pos));
}
}
}
}
if (logChanges) {
log.add(session, this, record);
}
}
}
void writeDirectDeleted(int recordId, int blockCount) throws SQLException {
synchronized (database) {
go(recordId);
for (int i = 0; i < blockCount; i++) {
file.write(freeBlock.getBytes(), 0, freeBlock.length());
}
free(recordId, blockCount);
}
}
void writeDirect(Storage storage, int pos, byte[] data, int offset) throws SQLException {
synchronized (database) {
go(pos);
file.write(data, offset, BLOCK_SIZE);
setBlockOwner(null, storage, pos, 1, true);
}
}
public int copyDirect(int pos, OutputStream out) throws SQLException {
synchronized (database) {
try {
if (pos < 0) {
// read the header
byte[] buffer = new byte[OFFSET];
file.seek(0);
file.readFullyDirect(buffer, 0, OFFSET);
out.write(buffer);
return 0;
}
if (pos >= fileBlockCount) {
return -1;
}
int blockSize = DiskFile.BLOCK_SIZE;
byte[] buff = new byte[blockSize];
DataPage s = DataPage.create(database, buff);
database.setProgress(DatabaseEventListener.STATE_BACKUP_FILE, this.fileName, pos, fileBlockCount);
go(pos);
file.readFully(buff, 0, blockSize);
s.reset();
int blockCount = s.readInt();
if (SysProperties.CHECK && blockCount < 0) {
throw Message.getInternalError();
}
if (blockCount == 0) {
blockCount = 1;
}
int id = s.readInt();
if (SysProperties.CHECK && id < 0) {
throw Message.getInternalError();
}
s.checkCapacity(blockCount * blockSize);
if (blockCount > 1) {
file.readFully(s.getBytes(), blockSize, blockCount * blockSize - blockSize);
}
if (file.isEncrypted()) {
s.reset();
go(pos);
file.readFullyDirect(s.getBytes(), 0, blockCount * blockSize);
}
out.write(s.getBytes(), 0, blockCount * blockSize);
return pos + blockCount;
} catch (IOException e) {
throw Message.convertIOException(e, fileName);
}
}
}
void removeRecord(Session session, int pos, Record record, int blockCount) throws SQLException {
synchronized (database) {
if (logChanges) {
log.add(session, this, record);
}
cache.remove(pos);
deleted.setRange(pos, blockCount, true);
setUnused(session, pos, blockCount);
}
}
void addRecord(Session session, Record record) throws SQLException {
synchronized (database) {
if (logChanges) {
log.add(session, this, record);
}
cache.put(record);
}
}
/*
* Must be synchronized externally
*/
public Cache getCache() {
return cache;
}
void free(int pos, int blockCount) {
synchronized (database) {
used.setRange(pos, blockCount, false);
}
}
public int getRecordOverhead() {
return recordOverhead;
}
public void truncateStorage(Session session, Storage storage, IntArray pages) throws SQLException {
synchronized (database) {
int storageId = storage.getId();
// make sure the cache records of this storage are not flushed to disk
// afterwards
ObjectArray list = cache.getAllChanged();
for (int i = 0; i < list.size(); i++) {
Record r = (Record) list.get(i);
if (r.getStorageId() == storageId) {
r.setChanged(false);
}
}
int[] pagesCopy = new int[pages.size()];
// can not use pages directly, because setUnused removes rows from there
pages.toArray(pagesCopy);
for (int i = 0; i < pagesCopy.length; i++) {
int page = pagesCopy[i];
if (logChanges) {
log.addTruncate(session, this, storageId, page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE);
}
for (int j = 0; j < BLOCKS_PER_PAGE; j++) {
Record r = (Record) cache.find(page * BLOCKS_PER_PAGE + j);
if (r != null) {
cache.remove(r.getPos());
}
}
deleted.setRange(page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE, true);
setUnused(session, page * BLOCKS_PER_PAGE, BLOCKS_PER_PAGE);
}
}
}
public void sync() {
synchronized (database) {
if (file != null) {
file.sync();
}
}
}
public boolean isDataFile() {
return dataFile;
}
public void setLogChanges(boolean b) {
synchronized (database) {
this.logChanges = b;
}
}
/**
* Add a redo-log entry to the redo buffer.
*
* @param storage the storage
* @param recordId the record id of the entry
* @param blockCount the number of blocks
* @param rec the record
*/
public void addRedoLog(Storage storage, int recordId, int blockCount, DataPage rec) throws SQLException {
synchronized (database) {
byte[] data = null;
if (rec != null) {
DataPage all = rowBuff;
all.reset();
all.writeInt(blockCount);
all.writeInt(storage.getId());
all.writeDataPageNoSize(rec);
// the buffer may have some additional fillers - just ignore them
all.fill(blockCount * BLOCK_SIZE);
all.updateChecksum();
if (SysProperties.CHECK && all.length() != BLOCK_SIZE * blockCount) {
throw Message.getInternalError("blockCount:" + blockCount + " length: " + all.length() * BLOCK_SIZE);
}
data = new byte[all.length()];
System.arraycopy(all.getBytes(), 0, data, 0, all.length());
}
for (int i = 0; i < blockCount; i++) {
RedoLogRecord log = new RedoLogRecord();
log.recordId = recordId + i;
log.offset = i * BLOCK_SIZE;
log.storage = storage;
log.data = data;
log.sequenceId = redoBuffer.size();
redoBuffer.add(log);
redoBufferSize += log.getSize();
}
if (redoBufferSize > SysProperties.REDO_BUFFER_SIZE) {
flushRedoLog();
}
}
}
public void flushRedoLog() throws SQLException {
synchronized (database) {
if (redoBuffer.size() == 0) {
return;
}
redoBuffer.sort(new Comparator() {
public int compare(Object o1, Object o2) {
RedoLogRecord e1 = (RedoLogRecord) o1;
RedoLogRecord e2 = (RedoLogRecord) o2;
int comp = e1.recordId - e2.recordId;
if (comp == 0) {
comp = e1.sequenceId - e2.sequenceId;
}
return comp;
}
});
// first write all deleted entries
RedoLogRecord last = null;
for (int i = 0; i < redoBuffer.size(); i++) {
RedoLogRecord entry = (RedoLogRecord) redoBuffer.get(i);
if (entry.data != null) {
continue;
}
if (last != null && entry.recordId != last.recordId) {
writeRedoLog(last);
}
last = entry;
}
if (last != null) {
writeRedoLog(last);
}
// now write the last entry, skipping deleted entries
last = null;
for (int i = 0; i < redoBuffer.size(); i++) {
RedoLogRecord entry = (RedoLogRecord) redoBuffer.get(i);
if (last != null && entry.recordId != last.recordId) {
if (last.data != null) {
writeRedoLog(last);
}
}
last = entry;
}
if (last != null && last.data != null) {
writeRedoLog(last);
}
redoBuffer.clear();
redoBufferSize = 0;
}
}
private void writeRedoLog(RedoLogRecord entry) throws SQLException {
if (entry.data == null) {
writeDirectDeleted(entry.recordId, 1);
} else {
writeDirect(entry.storage, entry.recordId, entry.data, entry.offset);
}
}
public int getWriteCount() {
return writeCount;
}
public int getReadCount() {
return readCount;
}
public void flushLog() throws SQLException {
if (log != null) {
log.flush();
}
}
public String toString() {
return getClass().getName() + ":" + fileName;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -