mirror of https://github.com/apache/lucene.git
LUCENE-4074: FST Sorter BufferSize causes int overflow if BufferSize > 2048MB
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1341995 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8a0f7f9af6
commit
1d6b468822
|
@ -1,6 +1,6 @@
|
|||
package org.apache.lucene.search.suggest.fst;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
|
@ -37,18 +37,18 @@ import org.apache.lucene.util.PriorityQueue;
|
|||
* @lucene.internal
|
||||
*/
|
||||
public final class Sort {
|
||||
public final static int MB = 1024 * 1024;
|
||||
public final static int GB = MB * 1024;
|
||||
public final static long MB = 1024 * 1024;
|
||||
public final static long GB = MB * 1024;
|
||||
|
||||
/**
|
||||
* Minimum recommended buffer size for sorting.
|
||||
*/
|
||||
public final static int MIN_BUFFER_SIZE_MB = 32;
|
||||
public final static long MIN_BUFFER_SIZE_MB = 32;
|
||||
|
||||
/**
|
||||
* Absolute minimum required buffer size for sorting.
|
||||
*/
|
||||
public static final int ABSOLUTE_MIN_SORT_BUFFER_SIZE = MB / 2;
|
||||
public static final long ABSOLUTE_MIN_SORT_BUFFER_SIZE = MB / 2;
|
||||
private static final String MIN_BUFFER_SIZE_MSG = "At least 0.5MB RAM buffer is needed";
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,7 @@ public final class Sort {
|
|||
* A bit more descriptive unit for constructors.
|
||||
*
|
||||
* @see #automatic()
|
||||
* @see #megabytes(int)
|
||||
* @see #megabytes(long)
|
||||
*/
|
||||
public static final class BufferSize {
|
||||
final int bytes;
|
||||
|
@ -70,11 +70,19 @@ public final class Sort {
|
|||
throw new IllegalArgumentException("Buffer too large for Java ("
|
||||
+ (Integer.MAX_VALUE / MB) + "mb max): " + bytes);
|
||||
}
|
||||
|
||||
if (bytes < ABSOLUTE_MIN_SORT_BUFFER_SIZE) {
|
||||
throw new IllegalArgumentException(MIN_BUFFER_SIZE_MSG + ": " + bytes);
|
||||
}
|
||||
|
||||
this.bytes = (int) bytes;
|
||||
}
|
||||
|
||||
public static BufferSize megabytes(int mb) {
|
||||
|
||||
/**
|
||||
* Creates a {@link BufferSize} in MB. The given
|
||||
* values must be $gt; 0 and < 2048.
|
||||
*/
|
||||
public static BufferSize megabytes(long mb) {
|
||||
return new BufferSize(mb * MB);
|
||||
}
|
||||
|
||||
|
@ -105,7 +113,7 @@ public final class Sort {
|
|||
sortBufferByteSize = Math.max(ABSOLUTE_MIN_SORT_BUFFER_SIZE, sortBufferByteSize);
|
||||
}
|
||||
}
|
||||
return new BufferSize(Math.min(Integer.MAX_VALUE, sortBufferByteSize));
|
||||
return new BufferSize(Math.min((long)Integer.MAX_VALUE, sortBufferByteSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class TestSort extends LuceneTestCase {
|
|||
public void testIntermediateMerges() throws Exception {
|
||||
// Sort 20 mb worth of data with 1mb buffer, binary merging.
|
||||
SortInfo info = checkSort(new Sort(Sort.DEFAULT_COMPARATOR, BufferSize.megabytes(1), Sort.defaultTempDir(), 2),
|
||||
generateRandom(Sort.MB * 20));
|
||||
generateRandom((int)Sort.MB * 20));
|
||||
assertTrue(info.mergeRounds > 10);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class TestSort extends LuceneTestCase {
|
|||
public void testSmallRandom() throws Exception {
|
||||
// Sort 20 mb worth of data with 1mb buffer.
|
||||
SortInfo sortInfo = checkSort(new Sort(Sort.DEFAULT_COMPARATOR, BufferSize.megabytes(1), Sort.defaultTempDir(), Sort.MAX_TEMPFILES),
|
||||
generateRandom(Sort.MB * 20));
|
||||
generateRandom((int)Sort.MB * 20));
|
||||
assertEquals(1, sortInfo.mergeRounds);
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class TestSort extends LuceneTestCase {
|
|||
public void testLargerRandom() throws Exception {
|
||||
// Sort 100MB worth of data with 15mb buffer.
|
||||
checkSort(new Sort(Sort.DEFAULT_COMPARATOR, BufferSize.megabytes(16), Sort.defaultTempDir(), Sort.MAX_TEMPFILES),
|
||||
generateRandom(Sort.MB * 100));
|
||||
generateRandom((int)Sort.MB * 100));
|
||||
}
|
||||
|
||||
private byte[][] generateRandom(int howMuchData) {
|
||||
|
@ -152,4 +152,31 @@ public class TestSort extends LuceneTestCase {
|
|||
w.close();
|
||||
return file;
|
||||
}
|
||||
|
||||
public void testRamBuffer() {
|
||||
int numIters = atLeast(10000);
|
||||
for (int i = 0; i < numIters; i++) {
|
||||
BufferSize.megabytes(1+random().nextInt(2047));
|
||||
}
|
||||
BufferSize.megabytes(2047);
|
||||
BufferSize.megabytes(1);
|
||||
|
||||
try {
|
||||
BufferSize.megabytes(2048);
|
||||
fail("max mb is 2047");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
BufferSize.megabytes(0);
|
||||
fail("min mb is 0.5");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
BufferSize.megabytes(-1);
|
||||
fail("min mb is 0.5");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue