mirror of https://github.com/apache/druid.git
Merge pull request #2002 from navis/DRUID-2001
fixed #2001 GenericIndexed.fromIterable compares all values even when it's not sorted
This commit is contained in:
commit
9015a68c03
|
@ -66,48 +66,42 @@ public class GenericIndexed<T> implements Indexed<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allowReverseLookup = true;
|
boolean allowReverseLookup = true;
|
||||||
int count = 1;
|
int count = 0;
|
||||||
T prevVal = objects.next();
|
|
||||||
while (objects.hasNext()) {
|
|
||||||
T next = objects.next();
|
|
||||||
if (!(strategy.compare(prevVal, next) < 0)) {
|
|
||||||
allowReverseLookup = false;
|
|
||||||
}
|
|
||||||
if (prevVal instanceof Closeable) {
|
|
||||||
CloseQuietly.close((Closeable) prevVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
prevVal = next;
|
ByteArrayOutputStream headerBytes = new ByteArrayOutputStream();
|
||||||
++count;
|
|
||||||
}
|
|
||||||
if (prevVal instanceof Closeable) {
|
|
||||||
CloseQuietly.close((Closeable) prevVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteArrayOutputStream headerBytes = new ByteArrayOutputStream(4 + (count * 4));
|
|
||||||
ByteArrayOutputStream valueBytes = new ByteArrayOutputStream();
|
ByteArrayOutputStream valueBytes = new ByteArrayOutputStream();
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
headerBytes.write(Ints.toByteArray(count));
|
int offset = 0;
|
||||||
|
T prevVal = null;
|
||||||
|
do {
|
||||||
|
count++;
|
||||||
|
T next = objects.next();
|
||||||
|
if (allowReverseLookup && prevVal != null && !(strategy.compare(prevVal, next) < 0)) {
|
||||||
|
allowReverseLookup = false;
|
||||||
|
}
|
||||||
|
|
||||||
for (T object : objectsIterable) {
|
final byte[] bytes = strategy.toBytes(next);
|
||||||
final byte[] bytes = strategy.toBytes(object);
|
|
||||||
offset += 4 + bytes.length;
|
offset += 4 + bytes.length;
|
||||||
headerBytes.write(Ints.toByteArray(offset));
|
headerBytes.write(Ints.toByteArray(offset));
|
||||||
valueBytes.write(Ints.toByteArray(bytes.length));
|
valueBytes.write(Ints.toByteArray(bytes.length));
|
||||||
valueBytes.write(bytes);
|
valueBytes.write(bytes);
|
||||||
|
|
||||||
if (object instanceof Closeable) {
|
if (prevVal instanceof Closeable) {
|
||||||
CloseQuietly.close((Closeable) object);
|
CloseQuietly.close((Closeable) prevVal);
|
||||||
}
|
}
|
||||||
|
prevVal = next;
|
||||||
|
} while (objects.hasNext());
|
||||||
|
|
||||||
|
if (prevVal instanceof Closeable) {
|
||||||
|
CloseQuietly.close((Closeable) prevVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer theBuffer = ByteBuffer.allocate(headerBytes.size() + valueBytes.size());
|
ByteBuffer theBuffer = ByteBuffer.allocate(Ints.BYTES + headerBytes.size() + valueBytes.size());
|
||||||
|
theBuffer.put(Ints.toByteArray(count));
|
||||||
theBuffer.put(headerBytes.toByteArray());
|
theBuffer.put(headerBytes.toByteArray());
|
||||||
theBuffer.put(valueBytes.toByteArray());
|
theBuffer.put(valueBytes.toByteArray());
|
||||||
theBuffer.flip();
|
theBuffer.flip();
|
||||||
|
|
|
@ -57,19 +57,7 @@ public class GenericIndexedTest
|
||||||
final String[] strings = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"};
|
final String[] strings = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"};
|
||||||
Indexed<String> indexed = GenericIndexed.fromArray(strings, GenericIndexed.STRING_STRATEGY);
|
Indexed<String> indexed = GenericIndexed.fromArray(strings, GenericIndexed.STRING_STRATEGY);
|
||||||
|
|
||||||
Assert.assertEquals(strings.length, indexed.size());
|
checkBasicAPIs(strings, indexed, true);
|
||||||
for (int i = 0; i < strings.length; i++) {
|
|
||||||
Assert.assertEquals(strings[i], indexed.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, Integer> mixedUp = Maps.newHashMap();
|
|
||||||
for (int i = 0; i < strings.length; i++) {
|
|
||||||
mixedUp.put(strings[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : mixedUp.entrySet()) {
|
|
||||||
Assert.assertEquals(entry.getValue().intValue(), indexed.indexOf(entry.getKey()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals(-13, indexed.indexOf("q"));
|
Assert.assertEquals(-13, indexed.indexOf("q"));
|
||||||
Assert.assertEquals(-9, indexed.indexOf("howdydo"));
|
Assert.assertEquals(-9, indexed.indexOf("howdydo"));
|
||||||
|
@ -87,25 +75,52 @@ public class GenericIndexedTest
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.assertEquals(strings.length, deserialized.size());
|
checkBasicAPIs(strings, deserialized, true);
|
||||||
for (int i = 0; i < strings.length; i++) {
|
|
||||||
Assert.assertEquals(strings[i], deserialized.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, Integer> mixedUp = Maps.newHashMap();
|
|
||||||
for (int i = 0; i < strings.length; i++) {
|
|
||||||
mixedUp.put(strings[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : mixedUp.entrySet()) {
|
|
||||||
Assert.assertEquals(entry.getValue().intValue(), deserialized.indexOf(entry.getKey()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals(-13, deserialized.indexOf("q"));
|
Assert.assertEquals(-13, deserialized.indexOf("q"));
|
||||||
Assert.assertEquals(-9, deserialized.indexOf("howdydo"));
|
Assert.assertEquals(-9, deserialized.indexOf("howdydo"));
|
||||||
Assert.assertEquals(-1, deserialized.indexOf("1111"));
|
Assert.assertEquals(-1, deserialized.indexOf("1111"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotSortedSerialization() throws Exception
|
||||||
|
{
|
||||||
|
final String[] strings = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "k", "j", "l"};
|
||||||
|
|
||||||
|
GenericIndexed<String> deserialized = serializeAndDeserialize(
|
||||||
|
GenericIndexed.fromArray(
|
||||||
|
strings, GenericIndexed.STRING_STRATEGY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
checkBasicAPIs(strings, deserialized, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBasicAPIs(String[] strings, Indexed<String> index, boolean allowReverseLookup)
|
||||||
|
{
|
||||||
|
Assert.assertEquals(strings.length, index.size());
|
||||||
|
for (int i = 0; i < strings.length; i++) {
|
||||||
|
Assert.assertEquals(strings[i], index.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowReverseLookup) {
|
||||||
|
HashMap<String, Integer> mixedUp = Maps.newHashMap();
|
||||||
|
for (int i = 0; i < strings.length; i++) {
|
||||||
|
mixedUp.put(strings[i], i);
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Integer> entry : mixedUp.entrySet()) {
|
||||||
|
Assert.assertEquals(entry.getValue().intValue(), index.indexOf(entry.getKey()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
index.indexOf("xxx");
|
||||||
|
Assert.fail("should throw exception");
|
||||||
|
}
|
||||||
|
catch (UnsupportedOperationException e) {
|
||||||
|
// not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private GenericIndexed<String> serializeAndDeserialize(GenericIndexed<String> indexed) throws IOException
|
private GenericIndexed<String> serializeAndDeserialize(GenericIndexed<String> indexed) throws IOException
|
||||||
{
|
{
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
Loading…
Reference in New Issue