/** * Closes this store. This will cause all buffers and channels to be closed. Requesting an * operation from after this method has been invoked is illegal and an exception will be thrown. * * <p>This method will start by invoking the {@link #closeStorage} method giving the implementing * store way to do anything that it needs to do before the fileChannel is closed. */ public void close() { if (fileChannel == null) { return; } closeStorage(); if (windowPool != null) { windowPool.close(); windowPool = null; } if ((isReadOnly() && !isBackupSlave()) || idGenerator == null || !storeOk) { releaseFileLockAndCloseFileChannel(); return; } long highId = idGenerator.getHighId(); int recordSize = -1; if (this instanceof AbstractDynamicStore) { recordSize = ((AbstractDynamicStore) this).getBlockSize(); } else if (this instanceof AbstractStore) { recordSize = ((AbstractStore) this).getRecordSize(); } idGenerator.close(); boolean success = false; IOException storedIoe = null; // hack for WINBLOWS if (!readOnly || backupSlave) { for (int i = 0; i < 10; i++) { try { fileChannel.position(highId * recordSize); ByteBuffer buffer = ByteBuffer.wrap(UTF8.encode(getTypeAndVersionDescriptor())); fileChannel.write(buffer); stringLogger.debug( "Closing " + storageFileName + ", truncating at " + fileChannel.position() + " vs file size " + fileChannel.size()); fileChannel.truncate(fileChannel.position()); fileChannel.force(false); releaseFileLockAndCloseFileChannel(); success = true; break; } catch (IOException e) { storedIoe = e; System.gc(); } } } else { releaseFileLockAndCloseFileChannel(); success = true; } if (!success) { throw new UnderlyingStorageException( "Unable to close store " + getStorageFileName(), storedIoe); } }
/** * Acquires a {@link PersistenceWindow} for <CODE>position</CODE> and operation <CODE>type</CODE>. * Window must be released after operation has been performed via {@link * #releaseWindow(PersistenceWindow)}. * * @param position The record position * @param type The operation type * @return a persistence window encapsulating the record */ protected PersistenceWindow acquireWindow(long position, OperationType type) { if (!isInRecoveryMode() && (position > getHighId() || !storeOk)) { throw new InvalidRecordException( "Position[" + position + "] requested for high id[" + getHighId() + "], store is ok[" + storeOk + "] recovery[" + isInRecoveryMode() + "]", causeOfStoreNotOk); } return windowPool.acquire(position, type); }
public WindowPoolStats getWindowPoolStats() { return windowPool.getStats(); }
public void flushAll() { windowPool.flushAll(); }
/** * Releases the window and writes the data (async) if the <CODE>window</CODE> was a {@link * PersistenceRow}. * * @param window The window to be released */ protected void releaseWindow(PersistenceWindow window) { windowPool.release(window); }