/** * Checks if the table of the specified database is locked. * * @param db name of database * @param ctx database context * @return result of check */ public static boolean locked(final String db, final Context ctx) { final IOFile table = MetaData.file(ctx.globalopts.dbpath(db), DATATBL); if (!table.exists()) return false; try (final RandomAccessFile file = new RandomAccessFile(table.file(), "rw")) { return file.getChannel().tryLock() == null; } catch (final ClosedChannelException ex) { return false; } catch (final OverlappingFileLockException | IOException ex) { return true; } }
/** * Reads a block from disk. * * @param b block to fetch */ private void readBlock(final int b) { if (!bm.cursor(b)) return; final Buffer bf = bm.current(); try { if (bf.dirty) writeBlock(bf); bf.pos = b; if (b >= blocks) { blocks = b + 1; } else { file.seek(bf.pos * IO.BLOCKSIZE); file.readFully(bf.data); } } catch (final IOException ex) { Util.stack(ex); } }
/** * Writes the specified block to disk and resets the dirty flag. * * @param bf buffer to write * @throws IOException I/O exception */ private void writeBlock(final Buffer bf) throws IOException { file.seek(bf.pos * IO.BLOCKSIZE); file.write(bf.data); bf.dirty = false; }
/** * Acquires a lock on the file. Does nothing if the correct lock has already been acquired. * Otherwise, releases an existing lock. * * @param shared shared/exclusive lock * @return success flag * @throws IOException I/O exception */ private boolean lck(final boolean shared) throws IOException { if (fl != null && shared == fl.isShared()) return true; if (fl != null) fl.release(); fl = file.getChannel().tryLock(0, Long.MAX_VALUE, shared); return fl != null; }
@Override public synchronized void close() throws IOException { flush(); file.close(); }