lucene 4: hashCode and equals for Text and BytesReference

now that we are going to use those more in places like facets, they need to implement equals and hasCode to be used in hashes
This commit is contained in:
Shay Banon 2012-10-26 02:33:00 +02:00
parent 15c9cd5142
commit ed03741353
8 changed files with 104 additions and 34 deletions

View File

@ -125,6 +125,16 @@ public class ByteBufferBytesReference implements BytesReference {
return buffer.arrayOffset() + buffer.position(); return buffer.arrayOffset() + buffer.position();
} }
@Override
public int hashCode() {
return Helper.bytesHashCode(this);
}
@Override
public boolean equals(Object obj) {
return Helper.bytesEqual(this, (BytesReference) obj);
}
@Override @Override
public String toUtf8() { public String toUtf8() {
if (!buffer.hasRemaining()) { if (!buffer.hasRemaining()) {

View File

@ -148,33 +148,12 @@ public class BytesArray implements BytesReference {
} }
@Override @Override
public boolean equals(Object obj) { public int hashCode() {
return bytesEquals((BytesArray) obj); return Helper.bytesHashCode(this);
}
public boolean bytesEquals(BytesArray other) {
if (length == other.length) {
int otherUpto = other.offset;
final byte[] otherBytes = other.bytes;
final int end = offset + length;
for (int upto = offset; upto < end; upto++, otherUpto++) {
if (bytes[upto] != otherBytes[otherUpto]) {
return false;
}
}
return true;
} else {
return false;
}
} }
@Override @Override
public int hashCode() { public boolean equals(Object obj) {
int result = 0; return Helper.bytesEqual(this, (BytesReference) obj);
final int end = offset + length;
for (int i = offset; i < end; i++) {
result = 31 * result + bytes[i];
}
return result;
} }
} }

View File

@ -31,6 +31,46 @@ import java.util.Comparator;
*/ */
public interface BytesReference { public interface BytesReference {
public static class Helper {
public static boolean bytesEqual(BytesReference a, BytesReference b) {
if (a == b) {
return true;
}
if (a.length() != b.length()) {
return false;
}
if (!a.hasArray()) {
a = a.toBytesArray();
}
if (!b.hasArray()) {
b = b.toBytesArray();
}
int bUpTo = b.arrayOffset();
final byte[] aArray = a.array();
final byte[] bArray = b.array();
final int end = a.arrayOffset() + a.length();
for (int aUpTo = a.arrayOffset(); aUpTo < end; aUpTo++, bUpTo++) {
if (aArray[aUpTo] != bArray[bUpTo]) {
return false;
}
}
return true;
}
public static int bytesHashCode(BytesReference a) {
if (!a.hasArray()) {
a = a.toBytesArray();
}
int result = 0;
final int end = a.arrayOffset() + a.length();
for (int i = a.arrayOffset(); i < end; i++) {
result = 31 * result + a.array()[i];
}
return result;
}
}
/** /**
* Returns the byte at the specified index. Need to be between 0 and length. * Returns the byte at the specified index. Need to be between 0 and length.
*/ */
@ -103,7 +143,8 @@ public interface BytesReference {
public static class UTF8SortedAsUnicodeComparator implements Comparator<BytesReference> { public static class UTF8SortedAsUnicodeComparator implements Comparator<BytesReference> {
// Only singleton // Only singleton
private UTF8SortedAsUnicodeComparator() {} private UTF8SortedAsUnicodeComparator() {
}
public int compare(BytesReference a, BytesReference b) { public int compare(BytesReference a, BytesReference b) {
if (a.hasArray() && b.hasArray()) { if (a.hasArray() && b.hasArray()) {
@ -113,7 +154,7 @@ public interface BytesReference {
int bUpto = b.arrayOffset(); int bUpto = b.arrayOffset();
final int aStop = aUpto + Math.min(a.length(), b.length()); final int aStop = aUpto + Math.min(a.length(), b.length());
while(aUpto < aStop) { while (aUpto < aStop) {
int aByte = aBytes[aUpto++] & 0xff; int aByte = aBytes[aUpto++] & 0xff;
int bByte = bBytes[bUpto++] & 0xff; int bByte = bBytes[bUpto++] & 0xff;
@ -132,7 +173,7 @@ public interface BytesReference {
int bUpto = 0; int bUpto = 0;
final int aStop = aUpto + Math.min(a.length(), b.length()); final int aStop = aUpto + Math.min(a.length(), b.length());
while(aUpto < aStop) { while (aUpto < aStop) {
int aByte = aBytes[aUpto++] & 0xff; int aByte = aBytes[aUpto++] & 0xff;
int bByte = bBytes[bUpto++] & 0xff; int bByte = bBytes[bUpto++] & 0xff;

View File

@ -106,4 +106,14 @@ public class ChannelBufferBytesReference implements BytesReference {
public String toUtf8() { public String toUtf8() {
return buffer.toString(Charsets.UTF_8); return buffer.toString(Charsets.UTF_8);
} }
@Override
public int hashCode() {
return Helper.bytesHashCode(this);
}
@Override
public boolean equals(Object obj) {
return Helper.bytesEqual(this, (BytesReference) obj);
}
} }

View File

@ -124,14 +124,12 @@ public class HashedBytesArray implements BytesReference {
} }
@Override @Override
public boolean equals(Object o) { public int hashCode() {
if (this == o) return true; return Helper.bytesHashCode(this);
HashedBytesArray bytesWrap = (HashedBytesArray) o;
return Arrays.equals(bytes, bytesWrap.bytes);
} }
@Override @Override
public int hashCode() { public boolean equals(Object obj) {
return hashCode; return Helper.bytesEqual(this, (BytesReference) obj);
} }
} }

View File

@ -61,4 +61,14 @@ public class BytesText implements Text {
public String toString() { public String toString() {
return string(); return string();
} }
@Override
public int hashCode() {
return bytes().hashCode();
}
@Override
public boolean equals(Object obj) {
return bytes().equals(((Text) obj).bytes());
}
} }

View File

@ -87,4 +87,14 @@ public class StringAndBytesText implements Text {
public String toString() { public String toString() {
return string(); return string();
} }
@Override
public int hashCode() {
return bytes().hashCode();
}
@Override
public boolean equals(Object obj) {
return bytes().equals(((Text) obj).bytes());
}
} }

View File

@ -71,4 +71,16 @@ public class StringText implements Text {
public String toString() { public String toString() {
return string(); return string();
} }
@Override
public int hashCode() {
// we use bytes here so we can be consistent with other text implementations
return bytes().hashCode();
}
@Override
public boolean equals(Object obj) {
// we use bytes here so we can be consistent with other text implementations
return bytes().equals(((Text) obj).bytes());
}
} }