public static void checkSanity() { long t = System.currentTimeMillis(); try { r.lock(); final int fileLength = (int) getRecords().length(); assert fileLength % RECORD_SIZE == 0; int recordCount = fileLength / RECORD_SIZE; IntArrayList usedAttributeRecordIds = new IntArrayList(); IntArrayList validAttributeIds = new IntArrayList(); for (int id = 2; id < recordCount; id++) { int flags = getFlags(id); LOG.assertTrue( (flags & ~ALL_VALID_FLAGS) == 0, "Invalid flags: 0x" + Integer.toHexString(flags) + ", id: " + id); if ((flags & FREE_RECORD_FLAG) != 0) { LOG.assertTrue( DbConnection.myFreeRecords.contains(id), "Record, marked free, not in free list: " + id); } else { LOG.assertTrue( !DbConnection.myFreeRecords.contains(id), "Record, not marked free, in free list: " + id); checkRecordSanity(id, recordCount, usedAttributeRecordIds, validAttributeIds); } } } finally { r.unlock(); } t = System.currentTimeMillis() - t; LOG.info("Sanity check took " + t + " ms"); }
public static Pair<String[], int[]> listAll(int parentId) { try { r.lock(); try { final DataInputStream input = readAttribute(parentId, CHILDREN_ATT); if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY); final int count = DataInputOutputUtil.readINT(input); final int[] ids = ArrayUtil.newIntArray(count); final String[] names = ArrayUtil.newStringArray(count); for (int i = 0; i < count; i++) { int id = DataInputOutputUtil.readINT(input); id = id >= 0 ? id + parentId : -id; ids[i] = id; names[i] = getName(id); } input.close(); return Pair.create(names, ids); } finally { r.unlock(); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static long getCreationTimestamp() { try { r.lock(); return DbConnection.getTimestamp(); } finally { r.unlock(); } }
public static int getModCount() { try { r.lock(); return getRecords().getInt(HEADER_GLOBAL_MOD_COUNT_OFFSET); } finally { r.unlock(); } }
public static int getFlags(int id) { try { r.lock(); return getRecordInt(id, FLAGS_OFFSET); } finally { r.unlock(); } }
public static long getLength(int id) { try { r.lock(); return getRecords().getLong(getOffset(id, LENGTH_OFFSET)); } finally { r.unlock(); } }
public static long getTimestamp(int id) { try { r.lock(); return getRecords().getLong(getOffset(id, TIMESTAMP_OFFSET)); } finally { r.unlock(); } }
public static int getModCount(int id) { try { r.lock(); return getRecordInt(id, MOD_COUNT_OFFSET); } finally { r.unlock(); } }
public static void setTimestamp(int id, long value) { try { w.lock(); incModCount(id); getRecords().putLong(getOffset(id, TIMESTAMP_OFFSET), value); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static void setLength(int id, long len) { try { w.lock(); incModCount(id); getRecords().putLong(getOffset(id, LENGTH_OFFSET), len); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static void setName(int id, String name) { try { w.lock(); incModCount(id); putRecordInt(id, NAME_OFFSET, getNames().enumerate(name)); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static void deleteRecordRecursively(int id) { try { w.lock(); incModCount(id); doDeleteRecursively(id); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static int acquireFileContent(int fileId) { try { w.lock(); int record = getContentRecordId(fileId); if (record > 0) getContentStorage().acquireRecord(record); return record; } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static boolean wereChildrenAccessed(int id) { try { r.lock(); try { return findAttributePage(id, CHILDREN_ATT, false) != 0; } finally { r.unlock(); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public void writeBytes(ByteSequence bytes, int fileId) throws IOException { final int page; try { w.lock(); incModCount(fileId); page = findOrCreatePage(); } finally { w.unlock(); } getStorage().writeBytes(page, bytes, myFixedSize); }
public static void dispose() { try { w.lock(); DbConnection.force(); DbConnection.closeFiles(); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { ourIsDisposed = true; w.unlock(); } }
public static int getContentId(int fileId) { try { r.lock(); try { return getContentRecordId(fileId); } finally { r.unlock(); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static void connect() { try { w.lock(); if (!ourInitialized) { init(); setupFlushing(); ourInitialized = true; } } finally { w.unlock(); } }
public static String getName(int id) { try { r.lock(); try { final int nameId = getRecordInt(id, NAME_OFFSET); return nameId != 0 ? getNames().valueOf(nameId) : ""; } finally { r.unlock(); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static void setFlags(int id, int flags, final boolean markAsChange) { try { w.lock(); if (markAsChange) { incModCount(id); } putRecordInt(id, FLAGS_OFFSET, flags); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static int findRootRecord(String rootUrl) throws IOException { try { w.lock(); DbConnection.markDirty(); final int root = getNames().enumerate(rootUrl); final DataInputStream input = readAttribute(1, CHILDREN_ATT); int[] names = ArrayUtil.EMPTY_INT_ARRAY; int[] ids = ArrayUtil.EMPTY_INT_ARRAY; if (input != null) { try { final int count = DataInputOutputUtil.readINT(input); names = ArrayUtil.newIntArray(count); ids = ArrayUtil.newIntArray(count); for (int i = 0; i < count; i++) { final int name = DataInputOutputUtil.readINT(input); final int id = DataInputOutputUtil.readINT(input); if (name == root) { return id; } names[i] = name; ids[i] = id; } } finally { input.close(); } } final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false); int id; try { id = createRecord(); DataInputOutputUtil.writeINT(output, names.length + 1); for (int i = 0; i < names.length; i++) { DataInputOutputUtil.writeINT(output, names[i]); DataInputOutputUtil.writeINT(output, ids[i]); } DataInputOutputUtil.writeINT(output, root); DataInputOutputUtil.writeINT(output, id); } finally { output.close(); } return id; } finally { w.unlock(); } }
private static void deleteRecord(final int id) { try { w.lock(); DbConnection.markDirty(); deleteContentAndAttributes(id); DbConnection.cleanRecord(id); addToFreeRecordsList(id); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
public static void setParent(int id, int parent) { if (id == parent) { LOG.error("Cyclic parent/child relations"); return; } try { w.lock(); incModCount(id); putRecordInt(id, PARENT_OFFSET, parent); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }
@Nullable public static DataInputStream readContent(int fileId) { try { int page; try { r.lock(); page = findContentPage(fileId, false); if (page == 0) return null; } finally { r.unlock(); } return getContentStorage().readStream(page); } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static void force() { try { w.lock(); if (myRecords != null) { markClean(); } if (myNames != null) { myNames.force(); myAttributes.force(); myContents.force(); myRecords.force(); } } finally { w.unlock(); } }
@Nullable public static DataInputStream readAttribute(int fileId, String attId) { try { synchronized (attId) { int page; try { r.lock(); page = findAttributePage(fileId, attId, false); if (page == 0) return null; } finally { r.unlock(); } return getAttributesStorage().readStream(page); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static int getParent(int id) { try { r.lock(); try { final int parentId = getRecordInt(id, PARENT_OFFSET); if (parentId == id) { LOG.error("Cyclic parent child relations in the database. id = " + id); return 0; } return parentId; } finally { r.unlock(); } } catch (Throwable e) { throw DbConnection.handleError(e); } }
public static void deleteRootRecord(int id) throws IOException { try { w.lock(); DbConnection.markDirty(); final DataInputStream input = readAttribute(1, CHILDREN_ATT); assert input != null; int count; int[] names; int[] ids; try { count = DataInputOutputUtil.readINT(input); names = ArrayUtil.newIntArray(count); ids = ArrayUtil.newIntArray(count); for (int i = 0; i < count; i++) { names[i] = DataInputOutputUtil.readINT(input); ids[i] = DataInputOutputUtil.readINT(input); } } finally { input.close(); } final int index = ArrayUtil.find(ids, id); assert index >= 0; names = ArrayUtil.remove(names, index); ids = ArrayUtil.remove(ids, index); final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false); try { DataInputOutputUtil.writeINT(output, count - 1); for (int i = 0; i < names.length; i++) { DataInputOutputUtil.writeINT(output, names[i]); DataInputOutputUtil.writeINT(output, ids[i]); } } finally { output.close(); } } finally { w.unlock(); } }
public static void flushSome() { if (!isDirty() || HeavyProcessLatch.INSTANCE.isRunning()) return; try { w.lock(); if (myFlushingFuture == null) { return; // avoid NPE when close has already taken place } myNames.force(); final boolean attribsFlushed = myAttributes.flushSome(); final boolean contentsFlushed = myContents.flushSome(); if (attribsFlushed && contentsFlushed) { markClean(); myRecords.force(); } } finally { w.unlock(); } }
public static void updateList(int id, @NotNull int[] children) { try { w.lock(); DbConnection.markDirty(); final DataOutputStream record = writeAttribute(id, CHILDREN_ATT, false); DataInputOutputUtil.writeINT(record, children.length); for (int child : children) { if (child == id) { LOG.error("Cyclic parent child relations"); } else { child = child > id ? child - id : -child; DataInputOutputUtil.writeINT(record, child); } } record.close(); } catch (Throwable e) { throw DbConnection.handleError(e); } finally { w.unlock(); } }