diff --git a/core/java/src/net/metanotion/io/block/FreeListBlock.java b/core/java/src/net/metanotion/io/block/FreeListBlock.java index 5a1360c8406663496a21fd91af797fa0212c8120..7c840adcd7dc1bdc5b9dda6e839042a10da8af8d 100644 --- a/core/java/src/net/metanotion/io/block/FreeListBlock.java +++ b/core/java/src/net/metanotion/io/block/FreeListBlock.java @@ -34,15 +34,19 @@ import net.metanotion.io.RandomAccessInterface; /** * On-disk format: + *<pre> * Magic number (long) * next freelist block page (unsigned int) * size (unsigned int) * that many free pages (unsigned ints) + *</pre> * * Always fits on one page. * * Free page format: + *<pre> * Magic number (long) + *</pre> */ class FreeListBlock { private static final long MAGIC = 0x2366724c69737423l; // "#frList#" diff --git a/core/java/src/net/metanotion/io/block/index/BSkipLevels.java b/core/java/src/net/metanotion/io/block/index/BSkipLevels.java index 0288fc45ffd73f9008df9b788c263af496c0e6f0..b204f4d8dc778a306f8ea1b42c20da36fb8d5162 100644 --- a/core/java/src/net/metanotion/io/block/index/BSkipLevels.java +++ b/core/java/src/net/metanotion/io/block/index/BSkipLevels.java @@ -40,11 +40,13 @@ import net.i2p.util.Log; /** * On-disk format: + *<pre> * Magic number (long) * max height (unsigned short) * non-null height (unsigned short) * span page (unsigned int) * height number of level pages (unsigned ints) + *</pre> * * Always fits on one page. */ @@ -113,6 +115,7 @@ public class BSkipLevels extends SkipLevels { bf.file.writeInt(spanPage); } + @Override public void flush() { if (isKilled) { BlockFile.log.error("Already killed!! " + this, new Exception()); @@ -135,6 +138,7 @@ public class BSkipLevels extends SkipLevels { } catch (IOException ioe) { throw new RuntimeException("Error writing to database", ioe); } } + @Override public void killInstance() { if (isKilled) { BlockFile.log.error("Already killed!! " + this, new Exception()); @@ -143,10 +147,11 @@ public class BSkipLevels extends SkipLevels { if (BlockFile.log.shouldLog(Log.INFO)) BlockFile.log.info("Killing " + this); isKilled = true; - bsl.levelHash.remove(levelPage); + bsl.levelHash.remove(Integer.valueOf(levelPage)); bf.freePage(levelPage); } + @Override public SkipLevels newInstance(int levels, SkipSpan ss, SkipList sl) { try { BSkipSpan bss = (BSkipSpan) ss; diff --git a/core/java/src/net/metanotion/io/block/index/BSkipList.java b/core/java/src/net/metanotion/io/block/index/BSkipList.java index ba11dc50555e2bdc1565c117d5a777cf48601275..c510107f7aeeeac4251192402013645a1932a275 100644 --- a/core/java/src/net/metanotion/io/block/index/BSkipList.java +++ b/core/java/src/net/metanotion/io/block/index/BSkipList.java @@ -37,14 +37,18 @@ import net.metanotion.io.Serializer; import net.metanotion.io.block.BlockFile; import net.metanotion.util.skiplist.*; +import net.i2p.util.Log; + /** * On-disk format: + *<pre> * Magic number (long) * first span page (unsigned int) * first level page (unsigned int) * size (unsigned int) * spans (unsigned int) * levels (unsigned int) + *</pre> * * Always fits on one page. */ @@ -88,6 +92,8 @@ public class BSkipList extends SkipList { else first = new BSkipSpan(bf, this, firstSpanPage, key, val); stack = new BSkipLevels(bf, firstLevelPage, this); + if (BlockFile.log.shouldLog(Log.DEBUG)) + BlockFile.log.debug("Loaded " + this + " cached " + levelHash.size() + " levels and " + spanHash.size() + " spans"); //rng = new Random(System.currentTimeMillis()); } @@ -99,6 +105,7 @@ public class BSkipList extends SkipList { isClosed = true; } + @Override public void flush() { if (isClosed) { BlockFile.log.error("Already closed!! " + this, new Exception()); @@ -116,22 +123,31 @@ public class BSkipList extends SkipList { } catch (IOException ioe) { throw new RuntimeException("Error writing to database", ioe); } } + /** must be open (do not call close() first) */ public void delete() throws IOException { - SkipLevels curLevel = stack, nextLevel; + if (isClosed) { + BlockFile.log.error("Already closed!! " + this, new Exception()); + return; + } + SkipLevels curLevel = stack; while(curLevel != null) { - nextLevel = curLevel.levels[0]; + SkipLevels nextLevel = curLevel.levels[0]; curLevel.killInstance(); curLevel = nextLevel; } + stack.killInstance(); - SkipSpan curSpan = first, nextSpan; + SkipSpan curSpan = first; while(curSpan != null) { - nextSpan = curSpan.next; + SkipSpan nextSpan = curSpan.next; curSpan.killInstance(); curSpan = nextSpan; } bf.freePage(skipPage); + spanHash.clear(); + levelHash.clear(); + isClosed = true; } public static void init(BlockFile bf, int page, int spanSize) throws IOException { @@ -148,6 +164,7 @@ public class BSkipList extends SkipList { BSkipLevels.init(bf, firstLevel, firstSpan, 4); } + @Override public int maxLevels() { int max = super.maxLevels(); int cells = (BlockFile.PAGESIZE - BSkipLevels.HEADER_LEN) / 4; @@ -204,7 +221,7 @@ public class BSkipList extends SkipList { BlockFile.log.warn(" Item " + key + " page " + sz); } else { String cls= iter.next().getClass().getSimpleName(); - BlockFile.log.warn(" Item " + key + " size " + cls); + BlockFile.log.warn(" Item " + key + " class " + cls); } items++; } diff --git a/core/java/src/net/metanotion/io/block/index/BSkipSpan.java b/core/java/src/net/metanotion/io/block/index/BSkipSpan.java index 452e8c6c686a93697b4a6757dd82d55a6b4ab5b6..e63edc10958661a332cc90f5eaa8664f714cb052 100644 --- a/core/java/src/net/metanotion/io/block/index/BSkipSpan.java +++ b/core/java/src/net/metanotion/io/block/index/BSkipSpan.java @@ -41,6 +41,7 @@ import net.i2p.util.Log; /** * On-disk format: * + *<pre> * First Page: * Magic number (int) * overflow page (unsigned int) @@ -57,6 +58,7 @@ import net.i2p.util.Log; * Overflow pages: * Magic number (int) * next overflow page (unsigned int) + *</pre> */ public class BSkipSpan extends SkipSpan { protected static final int MAGIC = 0x5370616e; // "Span" @@ -86,6 +88,7 @@ public class BSkipSpan extends SkipSpan { bf.file.writeShort(0); } + @Override public SkipSpan newInstance(SkipList sl) { try { int newPage = bf.allocPage(); @@ -94,6 +97,7 @@ public class BSkipSpan extends SkipSpan { } catch (IOException ioe) { throw new RuntimeException("Error creating database page", ioe); } } + @Override public void killInstance() { if (isKilled) { BlockFile.log.error("Already killed!! " + this, new Exception()); @@ -108,7 +112,7 @@ public class BSkipSpan extends SkipSpan { } catch (IOException ioe) { BlockFile.log.error("Error freeing " + this, ioe); } - bsl.spanHash.remove(this.page); + bsl.spanHash.remove(Integer.valueOf(this.page)); } /** @@ -131,6 +135,7 @@ public class BSkipSpan extends SkipSpan { return rv; } + @Override public void flush() { fflush(); } @@ -242,7 +247,7 @@ public class BSkipSpan extends SkipSpan { */ protected static void loadInit(BSkipSpan bss, BlockFile bf, BSkipList bsl, int spanPage, Serializer key, Serializer val) throws IOException { if (bss.isKilled) - BlockFile.log.error("Already killed!! " + bss, new Exception()); + throw new IOException("Already killed!! " + bss); bss.page = spanPage; bss.keySer = key; bss.valSer = val; @@ -278,7 +283,7 @@ public class BSkipSpan extends SkipSpan { */ protected void loadData(boolean flushOnError) throws IOException { if (isKilled) - BlockFile.log.error("Already killed!! " + this, new Exception()); + throw new IOException("Already killed!! " + this); this.keys = new Comparable[this.spanSize]; this.vals = new Object[this.spanSize];