/** * Used when a row is deleted as a result of some DML or DDL command. Adds the file space for the * row to the list of free positions. If there exists more than MAX_FREE_COUNT free positions, * then they are probably all too small, so we start a new list. * * <p>todo: This is wrong when deleting lots of records * * <p>Then remove the row from the cache data structures. */ public void remove(int i, PersistentStore store) throws HsqlException { CachedObject r = release(i); int size = r == null ? getStorageSize(i) : r.getStorageSize(); freeBlocks.add(i, size); }
/** * Parameter write indicates either an orderly close, or a fast close without backup. * * <p>When false, just closes the file. * * <p>When true, writes out all cached rows that have been modified and the free position pointer * for the *.data file and then closes the file. */ public void close(boolean write) throws HsqlException { try { if (cacheReadonly) { dataFile.close(); return; } StopWatch sw = new StopWatch(); if (write) { cache.saveAll(); Trace.printSystemOut("saveAll: " + sw.elapsedTime()); // set empty dataFile.seek(LONG_EMPTY_SIZE); dataFile.writeLong(freeBlocks.getLostBlocksSize()); // set end dataFile.seek(LONG_FREE_POS_POS); dataFile.writeLong(fileFreePosition); // set saved flag; dataFile.seek(FLAGS_POS); int flag = BitMap.set(0, FLAG_ISSAVED); if (hasRowInfo) { flag = BitMap.set(flag, FLAG_ROWINFO); } dataFile.writeInt(flag); // dataFile.seek(fileFreePosition); Trace.printSystemOut("pos and flags: " + sw.elapsedTime()); } if (dataFile != null) { dataFile.close(); dataFile = null; Trace.printSystemOut("close: " + sw.elapsedTime()); } boolean empty = fileFreePosition == INITIAL_FREE_POS; if (empty) { fa.removeElement(fileName); fa.removeElement(backupFileName); } } catch (Exception e) { database.logger.appLog.logContext(e); throw Trace.error(Trace.FILE_IO_ERROR, Trace.DataFileCache_close, new Object[] {e, fileName}); } }
/** * Allocates file space for the row. * * <p>A Row is added by walking the list of CacheFree objects to see if there is available space * to store it, reusing space if it exists. Otherwise the file is grown to accommodate it. */ private int setFilePos(CachedObject r) throws IOException { int rowSize = r.getStorageSize(); int i = freeBlocks == null ? -1 : freeBlocks.get(rowSize); if (i == -1) { i = (int) (fileFreePosition / cacheFileScale); long newFreePosition = fileFreePosition + rowSize; if (newFreePosition > maxDataFileSize) { throw new IOException(Trace.getMessage(Trace.DATA_FILE_IS_FULL)); } fileFreePosition = newFreePosition; } r.setPos(i); return i; }
public int getFreeBlockCount() { return freeBlocks.size(); }
/** * Parameter write indicates either an orderly close, or a fast close without backup. * * <p>When false, just closes the file. * * <p>When true, writes out all cached rows that have been modified and the free position pointer * for the *.data file and then closes the file. */ public void close(boolean write) throws HsqlException { SimpleLog appLog = database.logger.appLog; try { if (cacheReadonly) { if (dataFile != null) { dataFile.close(); } return; } StopWatch sw = new StopWatch(); appLog.sendLine(SimpleLog.LOG_NORMAL, "DataFileCache.close(" + write + ") : start"); if (write) { cache.saveAll(); Trace.printSystemOut("saveAll: " + sw.elapsedTime()); appLog.sendLine(SimpleLog.LOG_NORMAL, "DataFileCache.close() : save data"); if (fileModified || freeBlocks.isModified()) { // set empty dataFile.seek(LONG_EMPTY_SIZE); dataFile.writeLong(freeBlocks.getLostBlocksSize()); // set end dataFile.seek(LONG_FREE_POS_POS); dataFile.writeLong(fileFreePosition); // set saved flag; dataFile.seek(FLAGS_POS); int flag = BitMap.set(0, FLAG_ISSAVED); if (hasRowInfo) { flag = BitMap.set(flag, FLAG_ROWINFO); } dataFile.writeInt(flag); appLog.sendLine(SimpleLog.LOG_NORMAL, "DataFileCache.close() : flags"); // if (dataFile.length() != fileFreePosition) { dataFile.seek(fileFreePosition); } appLog.sendLine(SimpleLog.LOG_NORMAL, "DataFileCache.close() : seek end"); Trace.printSystemOut("pos and flags: " + sw.elapsedTime()); } } if (dataFile != null) { dataFile.close(); appLog.sendLine(SimpleLog.LOG_NORMAL, "DataFileCache.close() : close"); dataFile = null; Trace.printSystemOut("close: " + sw.elapsedTime()); } boolean empty = fileFreePosition == INITIAL_FREE_POS; if (empty) { fa.removeElement(fileName); fa.removeElement(backupFileName); } } catch (Throwable e) { appLog.logContext(e); throw Trace.error(Trace.FILE_IO_ERROR, Trace.DataFileCache_close, new Object[] {e, fileName}); } }