Index: lucene/core/src/java/org/apache/lucene/util/BytesRefHash.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/BytesRefHash.java (revision 1457223) +++ lucene/core/src/java/org/apache/lucene/util/BytesRefHash.java (working copy) @@ -365,7 +365,47 @@ } return -(e + 1); } + + /** + * Returns the ord of the given {@link BytesRef}. + * + * @see #getOrd(BytesRef, int) + */ + public int getOrd(BytesRef bytes) { + return getOrd(bytes, bytes.hashCode()); + } + /** + * Returns the ord of the given {@link BytesRef} with a pre-calculated hash code. + * + * @param bytes + * the bytes to look for + * @param code + * the bytes hash code + * + * @return the ord of the given bytes, or {@code -1} if there is no mapping for the + * given bytes. + */ + public int getOrd(BytesRef bytes, int code) { + assert bytesStart != null : "Bytesstart is null - not initialized"; + // final position + int hashPos = code & hashMask; + int e = ords[hashPos]; + if (e != -1 && !equals(e, bytes)) { + // Conflict: keep searching different locations in + // the hash table. + final int inc = ((code >> 8) + code) | 1; + do { + code += inc; + hashPos = code & hashMask; + e = ords[hashPos]; + } while (e != -1 && !equals(e, bytes)); + } + + // 'e' is either -1 or the ord of the requested bytes. + return e; + } + public int addByPoolOffset(int offset) { assert bytesStart != null : "Bytesstart is null - not initialized"; // final position Index: lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java =================================================================== --- lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java (revision 1457223) +++ lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java (working copy) @@ -30,16 +30,11 @@ import org.junit.Before; import org.junit.Test; -/** - * - */ public class TestBytesRefHash extends LuceneTestCase { BytesRefHash hash; ByteBlockPool pool; - /** - */ @Override @Before public void setUp() throws Exception { @@ -248,6 +243,43 @@ hash.reinit(); } } + + @Test + public void testGetOrd() throws Exception { + BytesRef ref = new BytesRef(); + BytesRef scratch = new BytesRef(); + int num = atLeast(2); + for (int j = 0; j < num; j++) { + Set strings = new HashSet(); + int uniqueCount = 0; + for (int i = 0; i < 797; i++) { + String str; + do { + str = _TestUtil.randomRealisticUnicodeString(random(), 1000); + } while (str.length() == 0); + ref.copyChars(str); + int count = hash.size(); + int key = hash.getOrd(ref); //hash.add(ref); + if (key >= 0) { // string found in hash + assertFalse(strings.add(str)); + assertTrue(key < count); + assertEquals(str, hash.get(key, scratch).utf8ToString()); + assertEquals(count, hash.size()); + } else { + key = hash.add(ref); + assertTrue(strings.add(str)); + assertEquals(uniqueCount, key); + assertEquals(hash.size(), count + 1); + uniqueCount++; + } + } + + assertAllIn(strings, hash); + hash.clear(); + assertEquals(0, hash.size()); + hash.reinit(); + } + } @Test(expected = MaxBytesLengthExceededException.class) public void testLargeValue() {