📄 datafilecache.java
字号:
Trace.printSystemOut("closed old cache"); // first attemp to delete fa.removeElement(fileName); if (wasNio) { System.gc(); if (fa.isStreamElement(fileName)) { fa.removeElement(fileName); if (fa.isStreamElement(fileName)) { fa.renameElement(fileName, fileName + ".old"); File oldfile = new File(fileName + ".old"); FileUtil.deleteOnExit(oldfile); } } }// oj@openofice.org - change to file access api fa.renameElement(fileName + ".new", fileName); backup(); database.getProperties().setProperty( HsqlDatabaseProperties.hsqldb_cache_version, HsqlDatabaseProperties.VERSION_STRING_1_7_0); database.getProperties().save(); initParams(); cache.clear(); cache = new Cache(this); open(cacheReadonly); dfd.updateTableIndexRoots(); dfd.updateTransactionRowIDs(); Trace.printSystemOut("opened cache"); } catch (Throwable e) { database.logger.appLog.logContext(e); throw new HsqlException( e, Trace.getMessage(Trace.GENERAL_IO_ERROR), Trace.GENERAL_IO_ERROR); } } /** * Used when a row is deleted as a result of some DML or DDL command. * Removes the row from the cache data structures. * Adds the file space for the row to the list of free positions. */ 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); } /** * Allocates file space for the row. <p> * * Free space is requested from the block manager 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 void add(CachedObject object) throws IOException { int size = object.getRealSize(rowOut); size = ((size + cachedRowPadding - 1) / cachedRowPadding) * cachedRowPadding; object.setStorageSize(size); int i = setFilePos(object); cache.put(i, object); // was previously used for text tables if (storeOnInsert) { saveRow(object); } } /** * For a CacheObject that had been previously released from the cache. * A new version is introduced, using the preallocated space for the object. */ public void restore(CachedObject object) throws IOException { int i = object.getPos(); cache.put(i, object); // was previously used for text tables if (storeOnInsert) { saveRow(object); } } public synchronized int getStorageSize(int i) throws HsqlException { try { CachedObject value = cache.get(i); if (value != null) { return value.getStorageSize(); } return readSize(i); } catch (IOException e) { database.logger.appLog.logContext(e); throw Trace.error(Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] { e, fileName }); } } public synchronized CachedObject get(int i, PersistentStore store, boolean keep) throws HsqlException { if (i < 0) { return null; } try { CachedObject object = cache.get(i); if (object == null) { RowInputInterface rowInput = readObject(i); if (rowInput == null) { return null; } object = store.get(rowInput); // for text tables with empty rows at the beginning, // pos may move forward in readObject i = object.getPos(); cache.put(i, object); } if (keep) { object.keepInMemory(true); } return object; } catch (IOException e) { database.logger.appLog.logContext("" + cache + " pos: " + i); database.logger.appLog.logContext(e); throw Trace.error(Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] { e, fileName }); } } RowInputInterface getRaw(int i) throws IOException { return readObject(i); } protected int readSize(int pos) throws IOException { dataFile.seek((long) pos * cacheFileScale); return dataFile.readInt(); } protected RowInputInterface readObject(int pos) throws IOException { dataFile.seek((long) pos * cacheFileScale); int size = dataFile.readInt(); rowIn.resetRow(pos, size); dataFile.read(rowIn.getBuffer(), 4, size - 4); return rowIn; } public CachedObject release(int i) { return cache.release(i); } /** * This is called internally when old rows need to be removed from the * cache. */ protected void saveRows(CachedObject[] rows, int offset, int count) throws IOException { for (int i = offset; i < offset + count; i++) { CachedObject r = rows[i]; saveRow(r); rows[i] = null; } initBuffers(); } /** * Writes out the specified Row. Will write only the Nodes or both Nodes * and table row data depending on what is not already persisted to disk. */ public void saveRow(CachedObject row) throws IOException { setFileModified(); rowOut.reset(); row.write(rowOut); dataFile.seek((long) row.getPos() * cacheFileScale); dataFile.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.getOutputStream().size()); } /** * Saves the *.data file as compressed *.backup. * * @throws HsqlException */ public void backup() throws IOException { try { ZipUnzipFile.compressFile(fileName, backupFileName + ".new", database.getFileAccess()); fa.renameElement(backupFileName + ".new", backupFileName); } catch (IOException e) { database.logger.appLog.logContext(e); throw e; } } /** * This method deletes a data file or resets its free position. * this is used only for nio files - not OOo files */ public static void deleteOrResetFreePos(Database database, String filename) { ScaledRAFile raFile = null; try { database.getFileAccess().removeElement(filename); } catch (IOException e) { database.logger.appLog.logContext(e); } if (database.isStoredFileAccess()) { return; } if (!database.getFileAccess().isStreamElement(filename)) { return; } try { raFile = new ScaledRAFile(filename, false); raFile.seek(LONG_FREE_POS_POS); raFile.writeLong(INITIAL_FREE_POS); } catch (IOException e) { database.logger.appLog.logContext(e); } finally { if (raFile != null) { try { raFile.close(); } catch (IOException e) { database.logger.appLog.logContext(e); } } } } public static int getFlags(String filename) throws HsqlException { try { ScaledRAFile raFile = (ScaledRAFile) ScaledRAFile.newScaledRAFile(filename, true, ScaledRAFile.DATA_FILE_RAF, null, null); raFile.seek(FLAGS_POS); int flags = raFile.readInt(); raFile.close(); return flags; } catch (IOException e) { throw Trace.error(Trace.DATA_FILE_ERROR); } } public int capacity() { return maxCacheSize; } public long bytesCapacity() { return maxCacheBytes; } public long getTotalCachedBlockSize() { return cache.getTotalCachedBlockSize(); } public int getFreeBlockCount() { return freeBlocks.size(); } public int getTotalFreeBlockSize() { return 0; } public long getFileFreePos() { return fileFreePosition; } public int getCachedObjectCount() { return cache.size(); } public String getFileName() { return fileName; } public boolean hasRowInfo() { return hasRowInfo; } public boolean isFileModified() { return fileModified; } protected void setFileModified() throws IOException { if (!fileModified) { // unset saved flag; dataFile.seek(FLAGS_POS); int flag = BitMap.set(0, FLAG_ISSAVED); if (hasRowInfo) { flag = BitMap.set(flag, FLAG_ROWINFO); } dataFile.writeInt(flag); fileModified = true; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -