diff --git a/source/de/anomic/kelondro/kelondroDyn.java b/source/de/anomic/kelondro/kelondroDyn.java index 2b14ac549..86a40c7d7 100644 --- a/source/de/anomic/kelondro/kelondroDyn.java +++ b/source/de/anomic/kelondro/kelondroDyn.java @@ -66,6 +66,7 @@ public class kelondroDyn extends kelondroTree { private int reclen; private int segmentCount; private char fillChar; + private kelondroObjectBuffer buffer; public kelondroDyn(File file, long buffersize /*bytes*/, int key, int nodesize, char fillChar, boolean exitOnFail) { this(file, buffersize, key, nodesize, fillChar, new kelondroNaturalOrder(true), exitOnFail); @@ -81,6 +82,7 @@ public class kelondroDyn extends kelondroTree { this.fillChar = fillChar; this.segmentCount = 0; writeSegmentCount(); + buffer = new kelondroObjectBuffer(file.toString()); } public kelondroDyn(File file, long buffersize, char fillChar) throws IOException { @@ -90,6 +92,7 @@ public class kelondroDyn extends kelondroTree { this.reclen = columnSize(1); this.fillChar = fillChar; this.segmentCount = 0; + buffer = new kelondroObjectBuffer(file.toString()); } private void writeSegmentCount() { @@ -187,6 +190,10 @@ public class kelondroDyn extends kelondroTree { private byte[] getValueCached(byte[] key) throws IOException { + // read from buffer + byte[] buffered = (byte[]) buffer.get(key); + if (buffered != null) return buffered; + // read from db byte[][] result = get(key); if (result == null) return null; @@ -197,7 +204,10 @@ public class kelondroDyn extends kelondroTree { private synchronized void setValueCached(byte[] key, byte[] value) throws IOException { // update storage - put(key, value); + synchronized (this) { + put(key, value); + buffer.put(key, value); + } } public synchronized int getDyn(String key, int pos) throws IOException { @@ -302,6 +312,7 @@ public class kelondroDyn extends kelondroTree { byte[] k; while (super.get(k = dynKey(key, recpos)) != null) { super.remove(k); + buffer.remove(k); recpos++; } //segmentCount--; writeSegmentCount(); diff --git a/source/de/anomic/kelondro/kelondroNaturalOrder.java b/source/de/anomic/kelondro/kelondroNaturalOrder.java index c7c12e075..b8cdce5c2 100644 --- a/source/de/anomic/kelondro/kelondroNaturalOrder.java +++ b/source/de/anomic/kelondro/kelondroNaturalOrder.java @@ -130,6 +130,12 @@ public class kelondroNaturalOrder extends kelondroAbstractOrder implements kelon return bz; } + public static final boolean equal(byte[] a, byte[] b) { + if ((a == null) && (b == null)) return true; + if ((a == null) || (b == null)) return false; + return compares(a, b) == 0; + } + public static final int compares(byte[] a, byte[] b) { int i = 0; final int al = a.length; diff --git a/source/de/anomic/kelondro/kelondroObjectBuffer.java b/source/de/anomic/kelondro/kelondroObjectBuffer.java new file mode 100644 index 000000000..23d33bef7 --- /dev/null +++ b/source/de/anomic/kelondro/kelondroObjectBuffer.java @@ -0,0 +1,177 @@ +// kelondroObjectBuffer.java +// ------------------------ +// (C) by Michael Peter Christen; mc@anomic.de +// first published on http://www.anomic.de +// Frankfurt, Germany, 2006 +// +// This is a part of the kelondro database, which is a part of YaCy +// +// $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $ +// $LastChangedRevision: 1986 $ +// $LastChangedBy: orbiter $ +// +// +// LICENSE +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// +// A NOTE FROM THE AUTHOR TO THE USERS: +// +// Using this software in any meaning (reading, learning, copying, compiling, +// running) means that you agree that the Author(s) is (are) not responsible +// for cost, loss of data or any harm that may be caused directly or indirectly +// by usage of this softare or this documentation. The usage of this software +// is on your own risk. The installation and usage (starting/running) of this +// software may allow other people or application to access your computer and +// any attached devices and is highly dependent on the configuration of the +// software which must be done by the user of the software; the author(s) is +// (are) also not responsible for proper configuration and usage of the +// software, even if provoked by documentation provided together with +// the software. +// +// +// A NOTE FROM THE AUTHOR TO DEVELOPERS: +// +// Contributions and changes to the program code should be marked as such: +// Please enter your own (C) notice below; they must be compatible with the GPL. +// Please mark also all changes in the code; if you don't mark them then they +// can't be identified; thus all unmarked code belong to the copyright holder +// as mentioned above. A good documentation of code authorities will also help +// to maintain the code and the project. +// A re-distribution must contain the intact and unchanged copyright statement. + + +package de.anomic.kelondro; + +public class kelondroObjectBuffer { + + private int readHit, readMiss, writeUnique, writeDouble; + private String name; + private byte[] key; + private Object value; + + public kelondroObjectBuffer(String name) { + this.name = name; + this.readHit = 0; + this.readMiss = 0; + this.writeUnique = 0; + this.writeDouble = 0; + this.key = null; + this.value = null; + } + + public String getName() { + return name; + } + + public String[] status() { + return new String[]{ + Integer.toString(readHit), + Integer.toString(readMiss), + Integer.toString(writeUnique), + Integer.toString(writeDouble) + }; + } + + private static String[] combinedStatus(String[] a, String[] b) { + return new String[]{ + Integer.toString(Integer.parseInt(a[0]) + Integer.parseInt(b[0])), + Integer.toString(Integer.parseInt(a[1]) + Integer.parseInt(b[1])), + Integer.toString(Integer.parseInt(a[2]) + Integer.parseInt(b[2])), + Integer.toString(Integer.parseInt(a[3]) + Integer.parseInt(b[3])) + }; + } + + public static String[] combinedStatus(String[][] a, int l) { + if ((a == null) || (a.length == 0) || (l == 0)) return null; + if ((a.length >= 1) && (l == 1)) return a[0]; + if ((a.length >= 2) && (l == 2)) return combinedStatus(a[0], a[1]); + return combinedStatus(combinedStatus(a, l - 1), a[l - 1]); + } + + public void put(byte[] key, Object value) { + if ((key == null) || (value == null)) return; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key)){ + this.writeDouble++; + } else { + this.writeUnique++; + } + this.key = key; + this.value = value; + } + } + + public void put(String key, Object value) { + if ((key == null) || (value == null)) return; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key.getBytes())){ + this.writeDouble++; + } else { + this.writeUnique++; + } + this.key = key.getBytes(); + this.value = value; + } + } + + public Object get(byte[] key) { + if (key == null) return null; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key)){ + this.readHit++; + return this.value; + } else { + this.readMiss++; + return null; + } + } + } + + public Object get(String key) { + if (key == null) return null; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key.getBytes())){ + this.readHit++; + return this.value; + } else { + this.readMiss++; + return null; + } + } + } + + public void remove(byte[] key) { + if (key == null) return; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key)){ + this.key = null; + this.value = null; + } + } + } + + public void remove(String key) { + if (key == null) return; + synchronized(this) { + if (kelondroNaturalOrder.equal(this.key, key.getBytes())){ + this.key = null; + this.value = null; + } + } + } + +}