public void delIndex(String name) throws IOException { Integer page = (Integer) metaIndex.remove(name); if (page == null) { return; } Serializer nb = new IdentityBytes(); BSkipList bsl = new BSkipList(spanSize, this, page.intValue(), nb, nb, true); bsl.delete(); }
public BSkipList makeIndex(String name, Serializer key, Serializer val) throws IOException { if (metaIndex.get(name) != null) { throw new IOException("Index already exists"); } int page = allocPage(); metaIndex.put(name, Integer.valueOf(page)); BSkipList.init(this, page, spanSize); BSkipList bsl = new BSkipList(spanSize, this, page, key, val, true); openIndices.put(name, bsl); return bsl; }
/** * Run an integrity check on the blockfile and all the skiplists in it * * @return true if the levels were modified. */ public boolean bfck(boolean fix) { if (log.shouldLog(Log.INFO)) { log.info("magic bytes " + magicBytes); log.info("fileLen " + fileLen); log.info("freeListStart " + freeListStart); log.info("mounted " + mounted); log.info("spanSize " + spanSize); log.info("Metaindex"); log.info("Checking meta index in blockfile " + file); } boolean rv = metaIndex.bslck(fix, true); if (rv) { if (log.shouldLog(Log.WARN)) log.warn("Repaired meta index in blockfile " + file); } else { if (log.shouldLog(Log.INFO)) log.info("No errors in meta index in blockfile " + file); } int items = 0; for (SkipIterator iter = metaIndex.iterator(); iter.hasNext(); ) { String slname = (String) iter.nextKey(); Integer page = (Integer) iter.next(); if (log.shouldLog(Log.INFO)) log.info("List " + slname + " page " + page); try { // This uses IdentityBytes, so the value class won't be right, but at least // it won't fail the out-of-order check Serializer keyser = slname.equals("%%__REVERSE__%%") ? new IntBytes() : new UTF8StringBytes(); BSkipList bsl = getIndex(slname, keyser, new IdentityBytes()); if (bsl == null) { log.error("Can't find list? " + slname); continue; } // The check is now done in getIndex(), no need to do here... // but we can't get the return value of the check here. items++; } catch (IOException ioe) { log.error("Error with list " + slname, ioe); } } log.info("Checked meta index and " + items + " skiplists"); if (freeListStart != 0) { try { if (flb == null) flb = new FreeListBlock(file, freeListStart); flb.flbck(true); } catch (IOException ioe) { log.error("Free list error", ioe); } } else { if (log.shouldLog(Log.INFO)) log.info("No freelist"); } return rv; }
/** If the file is writable, this runs an integrity check and repair on first open. */ public BSkipList getIndex(String name, Serializer key, Serializer val) throws IOException { // added I2P BSkipList bsl = (BSkipList) openIndices.get(name); if (bsl != null) return bsl; Integer page = (Integer) metaIndex.get(name); if (page == null) { return null; } bsl = new BSkipList(spanSize, this, page.intValue(), key, val, true); if (file.canWrite()) { log.info("Checking skiplist " + name + " in blockfile " + file); if (bsl.bslck(true, false)) log.logAlways(Log.WARN, "Repaired skiplist " + name + " in blockfile " + file); else log.info("No errors in skiplist " + name + " in blockfile " + file); } openIndices.put(name, bsl); return bsl; }
/** Note (I2P) Does NOT close the RAF / RAI. */ public void close() throws IOException { // added I2P if (_isClosed) return; _isClosed = true; metaIndex.close(); Set<String> oi = openIndices.keySet(); Iterator<String> i = oi.iterator(); Object k; while (i.hasNext()) { k = i.next(); BSkipList bsl = openIndices.get(k); bsl.close(); } // Unmount. if (file.canWrite()) { file.seek(BlockFile.OFFSET_MOUNTED); file.writeShort(0); } }
/** Use this constructor with a readonly RAI and init = false for a readonly blockfile */ public BlockFile(RandomAccessInterface rai, boolean init) throws IOException { if (rai == null) { throw new NullPointerException(); } file = rai; if (init) { file.setLength(fileLen); writeSuperBlock(); BSkipList.init(this, METAINDEX_PAGE, spanSize); } readSuperBlock(); if (magicBytes != MAGIC) { if ((magicBytes & MAGIC_BASE) == MAGIC_BASE) { throw new IOException( "Expected " + MAJOR + '.' + MINOR + " but got " + (magicBytes >> 8 & 0xff) + '.' + (magicBytes & 0xff)); } else { throw new IOException("Bad magic number"); } } _wasMounted = mounted != 0; if (_wasMounted) log.warn("Warning - file was not previously closed"); if (fileLen != file.length()) throw new IOException("Expected file length " + fileLen + " but actually " + file.length()); if (rai.canWrite()) mount(); metaIndex = new BSkipList(spanSize, this, METAINDEX_PAGE, new StringBytes(), new IntBytes()); }
/** Added I2P */ public void closeIndex(String name) { BSkipList bsl = (BSkipList) openIndices.remove(name); if (bsl != null) bsl.flush(); }