LUCENE-1798: add infoStream to FieldCache to print any increase in insanity when it happens

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@807572 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2009-08-25 11:44:45 +00:00
parent e8caefdb7d
commit 53dab68854
4 changed files with 68 additions and 3 deletions

View File

@ -729,6 +729,11 @@ New features
ValueSource, but takes care when composite (multi-segment) are
passed to not double RAM usage in the FieldCache. (Chris
Hostetter, Mark Miller, Mike McCandless)
37. LUCENE-1798: Added FieldCache.set/getInfoStream, which uses
FieldCacheSanityChecker to detect when a new cache entry has
caused additional insanity, printing the details at the time that
it happens. (Chris Hostetter, Mike McCandless)
Optimizations

View File

@ -25,6 +25,7 @@ import org.apache.lucene.analysis.NumericTokenStream; // for javadocs
import java.io.IOException;
import java.io.Serializable;
import java.io.PrintStream;
import java.text.DecimalFormat;
@ -615,5 +616,13 @@ public interface FieldCache {
*/
public abstract void purgeAllCaches();
/**
* If non-null, FieldCacheImpl will warn whenever
* entries are created that are not sane according to
* {@link FieldCacheSanityChecker}.
*/
public void setInfoStream(PrintStream stream);
/** @see setInfoStream */
public PrintStream getInfoStream();
}

View File

@ -18,21 +18,22 @@ package org.apache.lucene.search;
*/
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.document.NumericField; // javadoc
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.FieldCacheSanityChecker;
/**
* Expert: The default cache implementation, storing all values in memory.
@ -208,12 +209,39 @@ class FieldCacheImpl implements ExtendedFieldCache {
synchronized (readerCache) {
innerCache.put(key, progress.value);
}
// Only check if key.custom (the parser) is
// non-null; else, we check twice for a single
// call to FieldCache.getXXX
if (key.custom != null && wrapper != null) {
final PrintStream infoStream = wrapper.getInfoStream();
if (infoStream != null) {
printNewInsanity(infoStream, progress.value);
}
}
}
return progress.value;
}
}
return value;
}
private void printNewInsanity(PrintStream infoStream, Object value) {
final FieldCacheSanityChecker.Insanity[] insanities = FieldCacheSanityChecker.checkSanity(wrapper);
for(int i=0;i<insanities.length;i++) {
final FieldCacheSanityChecker.Insanity insanity = insanities[i];
final CacheEntry[] entries = insanity.getCacheEntries();
for(int j=0;j<entries.length;j++) {
if (entries[j].getValue() == value) {
// OK this insanity involves our entry
infoStream.println("WARNING: new FieldCache insanity created\nDetails: " + insanity.toString());
infoStream.println("\nStack:\n");
new Throwable().printStackTrace(infoStream);
break;
}
}
}
}
}
/** Expert: Every composite-key in the internal cache is of this type. */
@ -811,6 +839,15 @@ class FieldCacheImpl implements ExtendedFieldCache {
return retArray;
}
};
private volatile PrintStream infoStream;
public void setInfoStream(PrintStream stream) {
infoStream = stream;
}
public PrintStream getInfoStream() {
return infoStream;
}
}

View File

@ -25,6 +25,8 @@ import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.LuceneTestCase;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class TestFieldCache extends LuceneTestCase {
protected IndexReader reader;
@ -58,6 +60,18 @@ public class TestFieldCache extends LuceneTestCase {
reader = IndexReader.open(directory);
}
public void testInfoStream() throws Exception {
try {
FieldCache cache = FieldCache.DEFAULT;
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
cache.setInfoStream(new PrintStream(bos));
double [] doubles = cache.getDoubles(reader, "theDouble");
float [] floats = cache.getFloats(reader, "theDouble");
assertTrue(bos.toString().indexOf("WARNING") != -1);
} finally {
FieldCache.DEFAULT.purgeAllCaches();
}
}
public void test() throws IOException {
FieldCache cache = FieldCache.DEFAULT;