if (offset == HashtableOfIntValues.NO_VALUE) {
return null;
}
if (this.categoryTables == null) {
this.categoryTables = new HashtableOfObject(3);
} else {
HashtableOfObject cachedTable = (HashtableOfObject) this.categoryTables.get(categoryName);
if (cachedTable != null) {
if (readDocNumbers) { // must cache remaining document number arrays
Object[] arrayOffsets = cachedTable.valueTable;
for (int i = 0, l = arrayOffsets.length; i < l; i++)
if (arrayOffsets[i] instanceof Integer)
arrayOffsets[i] = readDocumentNumbers(arrayOffsets[i]);
}
return cachedTable;
}
}
InputStream stream = this.indexLocation.getInputStream();
HashtableOfObject categoryTable = null;
char[][] matchingWords = null;
int count = 0;
int firstOffset = -1;
this.streamBuffer = new byte[BUFFER_READ_SIZE];
try {
stream.skip(offset);
this.bufferIndex = 0;
this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
int size = readStreamInt(stream);
try {
if (size < 0) { // DEBUG
System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
System.err.println("offset = "+offset); //$NON-NLS-1$
System.err.println("size = "+size); //$NON-NLS-1$
System.err.println("-------------------- END --------------------"); //$NON-NLS-1$
}
categoryTable = new HashtableOfObject(size);
} catch (OutOfMemoryError oom) {
// DEBUG
oom.printStackTrace();
System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
System.err.println("offset = "+offset); //$NON-NLS-1$
System.err.println("size = "+size); //$NON-NLS-1$
System.err.println("-------------------- END --------------------"); //$NON-NLS-1$
throw oom;
}
int largeArraySize = 256;
for (int i = 0; i < size; i++) {
char[] word = readStreamChars(stream);
int arrayOffset = readStreamInt(stream);
// if arrayOffset is:
// <= 0 then the array size == 1 with the value -> -arrayOffset
// > 1 & < 256 then the size of the array is > 1 & < 256, the document array follows immediately
// 256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table)
if (arrayOffset <= 0) {
categoryTable.putUnsafely(word, new int[] {-arrayOffset}); // store 1 element array by negating documentNumber
} else if (arrayOffset < largeArraySize) {
categoryTable.putUnsafely(word, readStreamDocumentArray(stream, arrayOffset)); // read in-lined array providing size
} else {
arrayOffset = readStreamInt(stream); // read actual offset
if (readDocNumbers) {
if (matchingWords == null)
matchingWords = new char[size][];
if (count == 0)
firstOffset = arrayOffset;
matchingWords[count++] = word;
}
categoryTable.putUnsafely(word, new Integer(arrayOffset)); // offset to array in the file
}
}
this.categoryTables.put(INTERNED_CATEGORY_NAMES.get(categoryName), categoryTable);
// cache the table as long as its not too big
// in practice, some tables can be greater than 500K when they contain more than 10K elements
this.cachedCategoryName = categoryTable.elementSize < 20000 ? categoryName : null;
} catch (IOException ioe) {
this.streamBuffer = null;
throw ioe;
} finally {
stream.close();
}
if (matchingWords != null && count > 0) {
stream = this.indexLocation.getInputStream();
try {
stream.skip(firstOffset);
this.bufferIndex = 0;
this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
for (int i = 0; i < count; i++) { // each array follows the previous one
categoryTable.put(matchingWords[i], readStreamDocumentArray(stream, readStreamInt(stream)));
}
} catch (IOException ioe) {
this.streamBuffer = null;
throw ioe;
} finally {