From 65784eb656f618f07948fc0c6003b71c441ca06c Mon Sep 17 00:00:00 2001 From: orbiter Date: Sat, 14 Mar 2009 00:07:37 +0000 Subject: [PATCH] - more efficient comparator calls - fix for http://forum.yacy-websuche.de/viewtopic.php?p=13331#p13331 git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@5714 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- .../de/anomic/kelondro/blob/ObjectBuffer.java | 12 ++-- source/de/anomic/kelondro/index/Row.java | 6 +- .../de/anomic/kelondro/index/RowSetArray.java | 24 ++++++-- .../de/anomic/kelondro/order/Base64Order.java | 55 +++++++++++++++++-- .../de/anomic/kelondro/order/ByteOrder.java | 6 ++ .../anomic/kelondro/order/NaturalOrder.java | 49 ++++++++++++++--- 6 files changed, 127 insertions(+), 25 deletions(-) diff --git a/source/de/anomic/kelondro/blob/ObjectBuffer.java b/source/de/anomic/kelondro/blob/ObjectBuffer.java index a2def6b3d..196bfbfa6 100644 --- a/source/de/anomic/kelondro/blob/ObjectBuffer.java +++ b/source/de/anomic/kelondro/blob/ObjectBuffer.java @@ -110,7 +110,7 @@ public class ObjectBuffer { public void put(final byte[] key, final Object value) { if ((key == null) || (value == null)) return; synchronized(this) { - if (NaturalOrder.equal(this.key, key)){ + if (NaturalOrder.naturalOrder.equal(this.key, key)){ this.writeDouble++; } else { this.writeUnique++; @@ -123,7 +123,7 @@ public class ObjectBuffer { public void put(final String key, final Object value) { if ((key == null) || (value == null)) return; synchronized(this) { - if (NaturalOrder.equal(this.key, key.getBytes())){ + if (NaturalOrder.naturalOrder.equal(this.key, key.getBytes())){ this.writeDouble++; } else { this.writeUnique++; @@ -136,7 +136,7 @@ public class ObjectBuffer { public Object get(final byte[] key) { if (key == null) return null; synchronized(this) { - if (NaturalOrder.equal(this.key, key)){ + if (NaturalOrder.naturalOrder.equal(this.key, key)){ this.readHit++; return this.value; } else { @@ -149,7 +149,7 @@ public class ObjectBuffer { public Object get(final String key) { if (key == null) return null; synchronized(this) { - if (NaturalOrder.equal(this.key, key.getBytes())){ + if (NaturalOrder.naturalOrder.equal(this.key, key.getBytes())){ this.readHit++; return this.value; } else { @@ -162,7 +162,7 @@ public class ObjectBuffer { public void remove(final byte[] key) { if (key == null) return; synchronized(this) { - if (NaturalOrder.equal(this.key, key)){ + if (NaturalOrder.naturalOrder.equal(this.key, key)){ this.key = null; this.value = null; } @@ -172,7 +172,7 @@ public class ObjectBuffer { public void remove(final String key) { if (key == null) return; synchronized(this) { - if (NaturalOrder.equal(this.key, key.getBytes())){ + if (NaturalOrder.naturalOrder.equal(this.key, key.getBytes())){ this.key = null; this.value = null; } diff --git a/source/de/anomic/kelondro/index/Row.java b/source/de/anomic/kelondro/index/Row.java index c42163511..77d818b85 100644 --- a/source/de/anomic/kelondro/index/Row.java +++ b/source/de/anomic/kelondro/index/Row.java @@ -208,7 +208,7 @@ public final class Row { } public long cardinal(final Entry key) { - return base.cardinal(key.getPrimaryKeyBytes()); + return base.cardinal(key.bytes(), 0, key.getPrimaryKeyLength()); } public String signature() { @@ -565,6 +565,10 @@ public final class Row { return c; } + public final int getPrimaryKeyLength() { + return primaryKeyLength; + } + public final byte[] getColBytes(final int column) { assert offset + colstart[column] + row[column].cellwidth <= rowinstance.length : "column = " + column + ", offset = " + offset + ", colstart[column] = " + colstart[column] + ", row[column].cellwidth() = " + row[column].cellwidth + ", rowinstance.length = " + rowinstance.length; diff --git a/source/de/anomic/kelondro/index/RowSetArray.java b/source/de/anomic/kelondro/index/RowSetArray.java index 37da24e73..7c5197406 100644 --- a/source/de/anomic/kelondro/index/RowSetArray.java +++ b/source/de/anomic/kelondro/index/RowSetArray.java @@ -51,7 +51,7 @@ public class RowSetArray implements ObjectIndex, Iterable { } private int indexFor(Entry row) { - return indexFor(row.getPrimaryKeyBytes()); + return (int) (this.rowdef.objectOrder.cardinal(row.bytes(), 0, row.getPrimaryKeyLength()) % ((long) array.length)); } private RowSet accessArray(int i) { @@ -64,7 +64,9 @@ public class RowSetArray implements ObjectIndex, Iterable { } public void addUnique(Entry row) { - accessArray(indexFor(row)).addUnique(row); + int i = indexFor(row); + if (i < 0) return; + accessArray(i).addUnique(row); } public void addUnique(List rows) { @@ -95,6 +97,7 @@ public class RowSetArray implements ObjectIndex, Iterable { public Entry get(byte[] key) { int i = indexFor(key); + if (i < 0) return null; RowSet r = this.array[i]; if (r == null) return null; return r.get(key); @@ -102,6 +105,7 @@ public class RowSetArray implements ObjectIndex, Iterable { public boolean has(byte[] key) { int i = indexFor(key); + if (i < 0) return false; RowSet r = this.array[i]; if (r == null) return false; return r.has(key); @@ -121,7 +125,9 @@ public class RowSetArray implements ObjectIndex, Iterable { } public void put(Entry row) { - accessArray(indexFor(row)).put(row); + int i = indexFor(row); + if (i < 0) return; + accessArray(i).put(row); } public void put(List rows) { @@ -129,7 +135,9 @@ public class RowSetArray implements ObjectIndex, Iterable { } public Entry remove(byte[] key) { - return accessArray(indexFor(key)).remove(key); + int i = indexFor(key); + if (i < 0) return null; + return accessArray(i).remove(key); } public ArrayList removeDoubles() { @@ -159,7 +167,9 @@ public class RowSetArray implements ObjectIndex, Iterable { } public Entry replace(Entry row) { - return accessArray(indexFor(row)).replace(row); + int i = indexFor(row); + if (i < 0) return null; + return accessArray(i).replace(row); } public Row row() { @@ -200,6 +210,8 @@ public class RowSetArray implements ObjectIndex, Iterable { } public long inc(byte[] key, int col, long add, Entry initrow) { - return accessArray(indexFor(key)).inc(key, col, add, initrow); + int i = indexFor(key); + if (i < 0) return -1; + return accessArray(i).inc(key, col, add, initrow); } } diff --git a/source/de/anomic/kelondro/order/Base64Order.java b/source/de/anomic/kelondro/order/Base64Order.java index 755cdbfb6..c8c31709c 100644 --- a/source/de/anomic/kelondro/order/Base64Order.java +++ b/source/de/anomic/kelondro/order/Base64Order.java @@ -253,6 +253,19 @@ public class Base64Order extends AbstractOrder implements ByteOrder, Cod } } + private final long cardinalI(final byte[] key, int off, int len) { + // returns a cardinal number in the range of 0 .. Long.MAX_VALUE + long c = 0; + int lim = off + Math.min(10, len); + int lim10 = off + 10; + while (off < lim) c = (c << 6) | ahpla[key[off++]]; + while (off++ < lim10) c = (c << 6); + c = c << 3; + assert c >= 0; + return c; + } + + /* private final long cardinalI(final byte[] key) { // returns a cardinal number in the range of 0 .. Long.MAX_VALUE long c = 0; @@ -260,9 +273,10 @@ public class Base64Order extends AbstractOrder implements ByteOrder, Cod while ((p < 10) && (p < key.length)) c = (c << 6) | ahpla[key[p++]]; while (p++ < 10) c = (c << 6); c = c << 3; + assert c >= 0; return c; } - + */ private final long cardinalI(final String key) { // returns a cardinal number in the range of 0 .. Long.MAX_VALUE long c = 0; @@ -270,6 +284,7 @@ public class Base64Order extends AbstractOrder implements ByteOrder, Cod while ((p < 10) && (p < key.length())) c = (c << 6) | ahpla[key.charAt(p++)]; while (p++ < 10) c = (c << 6); c = c << 3; + assert c >= 0; return c; } @@ -284,16 +299,24 @@ public class Base64Order extends AbstractOrder implements ByteOrder, Cod } public final long cardinal(final byte[] key) { - if (this.zero == null) return cardinalI(key); - final long zeroCardinal = cardinalI(this.zero); - final long keyCardinal = cardinalI(key); + if (this.zero == null) return cardinalI(key, 0, key.length); + final long zeroCardinal = cardinalI(this.zero, 0, zero.length); + final long keyCardinal = cardinalI(key, 0, key.length); + if (keyCardinal > zeroCardinal) return keyCardinal - zeroCardinal; + return Long.MAX_VALUE - keyCardinal + zeroCardinal; + } + + public final long cardinal(final byte[] key, int off, int len) { + if (this.zero == null) return cardinalI(key, off, len); + final long zeroCardinal = cardinalI(this.zero, 0, zero.length); + final long keyCardinal = cardinalI(key, off, len); if (keyCardinal > zeroCardinal) return keyCardinal - zeroCardinal; return Long.MAX_VALUE - keyCardinal + zeroCardinal; } public final long cardinal(final String key) { if (this.zero == null) return cardinalI(key); - final long zeroCardinal = cardinalI(this.zero); + final long zeroCardinal = cardinalI(this.zero, 0, zero.length); final long keyCardinal = cardinalI(key); if (keyCardinal > zeroCardinal) return keyCardinal - zeroCardinal; return Long.MAX_VALUE - keyCardinal + zeroCardinal; @@ -303,6 +326,28 @@ public class Base64Order extends AbstractOrder implements ByteOrder, Cod return (x > 0) ? 1 : (x < 0) ? -1 : 0; } + public final boolean equal(final byte[] a, final byte[] b) { + if ((a == null) && (b == null)) return true; + if ((a == null) || (b == null)) return false; + if (a.length != b.length) return false; + int astart = 0; + int bstart = 0; + int length = a.length; + while (length-- != 0) { + if (a[astart++] != b[bstart++]) return false; + } + return true; + } + + public final boolean equal(final byte[] a, int astart, final byte[] b, int bstart, int length) { + if ((a == null) && (b == null)) return true; + if ((a == null) || (b == null)) return false; + while (length-- != 0) { + if (a[astart++] != b[bstart++]) return false; + } + return true; + } + public final int compare(final byte[] a, final byte[] b) { return (asc) ? compare0(a, 0, a.length, b, 0, b.length) : compare0(b, 0, b.length, a, 0, a.length); } diff --git a/source/de/anomic/kelondro/order/ByteOrder.java b/source/de/anomic/kelondro/order/ByteOrder.java index 42384aacd..7b5767a10 100644 --- a/source/de/anomic/kelondro/order/ByteOrder.java +++ b/source/de/anomic/kelondro/order/ByteOrder.java @@ -36,6 +36,12 @@ public interface ByteOrder extends Order { public int compare(byte[] a, int astart, int alen, byte[] b, int bstart, int blen); + public boolean equal(final byte[] a, final byte[] b); + + public boolean equal(final byte[] a, int astart, final byte[] b, int bstart, int length); + + public long cardinal(final byte[] a, int off, int len); + public final static class StringOrder implements Comparator { public ByteOrder baseOrder; diff --git a/source/de/anomic/kelondro/order/NaturalOrder.java b/source/de/anomic/kelondro/order/NaturalOrder.java index 41a9ec078..253077f3c 100644 --- a/source/de/anomic/kelondro/order/NaturalOrder.java +++ b/source/de/anomic/kelondro/order/NaturalOrder.java @@ -70,7 +70,7 @@ public final class NaturalOrder extends AbstractOrder implements ByteOrd if ( asc) return "nu"; return null; } - + /* private final static long cardinalI(final byte[] key) { // returns a cardinal number in the range of 0 .. Long.MAX_VALUE long c = 0; @@ -80,15 +80,34 @@ public final class NaturalOrder extends AbstractOrder implements ByteOrd c = c >>> 1; return c; } + */ + private final static long cardinalI(final byte[] key, int off, int len) { + // returns a cardinal number in the range of 0 .. Long.MAX_VALUE + long c = 0; + int lim = off + Math.min(8, len); + int lim8 = off + 8; + while (off < lim) c = (c << 8) | ((long) key[off++] & 0xFF); + while (off++ < lim8) c = (c << 8); + c = c >>> 1; + return c; + } public final long cardinal(final byte[] key) { - if (this.zero == null) return cardinalI(key); - final long zeroCardinal = cardinalI(this.zero); - final long keyCardinal = cardinalI(key); + if (this.zero == null) return cardinalI(key, 0, key.length); + final long zeroCardinal = cardinalI(this.zero, 0, this.zero.length); + final long keyCardinal = cardinalI(key, 0, key.length); if (keyCardinal > zeroCardinal) return keyCardinal - zeroCardinal; return Long.MAX_VALUE - keyCardinal + zeroCardinal; } - + + public long cardinal(final byte[] key, int off, int len) { + if (this.zero == null) return cardinalI(key, off, len); + final long zeroCardinal = cardinalI(this.zero, 0, this.zero.length); + final long keyCardinal = cardinalI(key, off, len); + if (keyCardinal > zeroCardinal) return keyCardinal - zeroCardinal; + return Long.MAX_VALUE - keyCardinal + zeroCardinal; + } + public final static byte[] encodeLong(long c, int length) { final byte[] b = new byte[length]; while (length > 0) { @@ -148,10 +167,26 @@ public final class NaturalOrder extends AbstractOrder implements ByteOrd return sig(az - bz); } - public static final boolean equal(final byte[] a, final byte[] b) { + public final boolean equal(final byte[] a, final byte[] b) { + if ((a == null) && (b == null)) return true; + if ((a == null) || (b == null)) return false; + if (a.length != b.length) return false; + int astart = 0; + int bstart = 0; + int length = a.length; + while (length-- != 0) { + if (a[astart++] != b[bstart++]) return false; + } + return true; + } + + public final boolean equal(final byte[] a, int astart, final byte[] b, int bstart, int length) { if ((a == null) && (b == null)) return true; if ((a == null) || (b == null)) return false; - return compares(a, 0, a.length, b, 0, b.length) == 0; + while (length-- != 0) { + if (a[astart++] != b[bstart++]) return false; + } + return true; } public static final int compares(final byte[] a, final int aoffset, final int alength, final byte[] b, final int boffset, final int blength) {