diff --git a/source/de/anomic/kelondro/blob/BLOBArray.java b/source/de/anomic/kelondro/blob/BLOBArray.java index 9f4e5eef2..8244001b3 100755 --- a/source/de/anomic/kelondro/blob/BLOBArray.java +++ b/source/de/anomic/kelondro/blob/BLOBArray.java @@ -156,11 +156,44 @@ public class BLOBArray implements BLOB { if (b.location.equals(location)) { i.remove(); b.blob.close(writeIDX); + b.blob = null; + b.location = null; return; } } } + private File unmount(int idx) { + blobItem b = this.blobs.remove(idx); + b.blob.close(false); + b.blob = null; + File f = b.location; + b.location = null; + return f; + } + + public synchronized File[] unmountBestMatch(double maxq) { + double l, r, min = Double.MAX_VALUE; + int[] idx = new int[2]; + for (int i = 0; i < this.blobs.size() - 1; i++) { + for (int j = i + 1; j < this.blobs.size(); j++) { + l = this.blobs.get(i).location.length(); + r = this.blobs.get(j).location.length(); + double q = Math.max(l/r, r/l); + if (q < min) { + min = q; + idx[0] = i; + idx[1] = j; + } + } + } + if (min > maxq) return null; + File[] bestmatch = new File[]{this.blobs.get(idx[0]).location, this.blobs.get(idx[1]).location}; + unmount(idx[1]); + unmount(idx[0]); + return bestmatch; + } + public synchronized File unmountSmallestBLOB() { if (this.blobs.size() == 0) return null; int bestIndex = -1; @@ -171,20 +204,14 @@ public class BLOBArray implements BLOB { bestIndex = i; } } - blobItem b = this.blobs.remove(bestIndex); - b.blob.close(false); - b.blob = null; - return b.location; + return unmount(bestIndex); } public synchronized File unmountOldestBLOB(boolean smallestFromFirst2) { if (this.blobs.size() == 0) return null; int idx = 0; if (smallestFromFirst2 && this.blobs.get(1).location.length() < this.blobs.get(0).location.length()) idx = 1; - blobItem b = this.blobs.remove(idx); - b.blob.close(false); - b.blob = null; - return b.location; + return unmount(idx); } public synchronized File unmountSimilarSizeBLOB(long otherSize) { @@ -202,10 +229,7 @@ public class BLOBArray implements BLOB { bestIndex = i; } } - b = this.blobs.remove(bestIndex); - b.blob.close(false); - b.blob = null; - return b.location; + return unmount(bestIndex); } /** diff --git a/source/de/anomic/kelondro/blob/HeapReader.java b/source/de/anomic/kelondro/blob/HeapReader.java index e0305fb71..8d55c1b45 100644 --- a/source/de/anomic/kelondro/blob/HeapReader.java +++ b/source/de/anomic/kelondro/blob/HeapReader.java @@ -48,7 +48,7 @@ public class HeapReader { protected int keylength; // the length of the primary key protected LongHandleIndex index; // key/seek relation for used records protected Gap free; // set of {seek, size} pairs denoting space and position of free records - protected final File heapFile; // the file of the heap + protected File heapFile; // the file of the heap protected final ByteOrder ordering; // the ordering on keys protected CachedRandomAccess file; // a random access to the file @@ -280,6 +280,7 @@ public class HeapReader { public synchronized void close() { if (file != null) file.close(); file = null; + heapFile = null; free.clear(); free = null; index.close(); diff --git a/source/de/anomic/kelondro/io/CachedRandomAccess.java b/source/de/anomic/kelondro/io/CachedRandomAccess.java index a10af403d..6dbc23f7f 100644 --- a/source/de/anomic/kelondro/io/CachedRandomAccess.java +++ b/source/de/anomic/kelondro/io/CachedRandomAccess.java @@ -131,6 +131,7 @@ public final class CachedRandomAccess extends AbstractRandomAccess implements Ra } catch (IOException e) { e.printStackTrace(); } + this.file = null; this.cache = null; this.RAFile = null; } diff --git a/source/de/anomic/kelondro/text/IndexCell.java b/source/de/anomic/kelondro/text/IndexCell.java index 3e9c2f9d7..9b4e3cf00 100644 --- a/source/de/anomic/kelondro/text/IndexCell.java +++ b/source/de/anomic/kelondro/text/IndexCell.java @@ -281,8 +281,7 @@ public final class IndexCell extends AbstractBufferedIndex implements BufferedIn private synchronized void cacheCleanup() throws IOException { if (this.lastCleanup + cleanupCycle > System.currentTimeMillis()) return; - int c = 0; - if (this.array.entries() > this.maxArrayFiles && c++ < 3) { + if (this.array.entries() > this.maxArrayFiles) { this.array.shrink(true); } } diff --git a/source/de/anomic/kelondro/text/ReferenceContainerArray.java b/source/de/anomic/kelondro/text/ReferenceContainerArray.java index 0e27c2576..af3a3ba36 100644 --- a/source/de/anomic/kelondro/text/ReferenceContainerArray.java +++ b/source/de/anomic/kelondro/text/ReferenceContainerArray.java @@ -247,13 +247,30 @@ public final class ReferenceContainerArray { public synchronized boolean shrink(boolean similar) throws IOException { if (this.array.entries() < 2) return false; if (this.merger.queueLength() > 0) return false; - File f1 = this.array.unmountOldestBLOB(similar); - if (f1.length() == 0) { - FileUtils.deletedelete(f1); - return true; + File[] ff = this.array.unmountBestMatch(2.0); + if (ff == null) { + ff = new File[2]; + ff[0] = this.array.unmountSmallestBLOB(); + if (ff[0].length() == 0) { + FileUtils.deletedelete(ff[0]); + return true; + } + ff[1] = this.array.unmountSmallestBLOB(); + if (ff[1].length() == 0) { + this.array.mountBLOB(ff[0]); + FileUtils.deletedelete(ff[1]); + return true; + } + /* + ff[0] = this.array.unmountOldestBLOB(similar); + if (ff[0].length() == 0) { + FileUtils.deletedelete(ff[0]); + return true; + } + ff[1] = (similar) ? this.array.unmountSimilarSizeBLOB(ff[0].length()) : this.array.unmountOldestBLOB(false); + */ } - File f2 = (similar) ? this.array.unmountSimilarSizeBLOB(f1.length()) : this.array.unmountOldestBLOB(false); - merger.merge(f1, f2, this.array, this.payloadrow, newContainerBLOBFile()); + merger.merge(ff[0], ff[1], this.array, this.payloadrow, newContainerBLOBFile()); return true; }