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 ValueSource, but takes care when composite (multi-segment) are
passed to not double RAM usage in the FieldCache. (Chris passed to not double RAM usage in the FieldCache. (Chris
Hostetter, Mark Miller, Mike McCandless) 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 Optimizations

View File

@ -25,6 +25,7 @@ import org.apache.lucene.analysis.NumericTokenStream; // for javadocs
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.io.PrintStream;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@ -615,5 +616,13 @@ public interface FieldCache {
*/ */
public abstract void purgeAllCaches(); 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.IOException;
import java.io.PrintStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap; 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.IndexReader;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs; import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum; import org.apache.lucene.index.TermEnum;
import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.FieldCacheSanityChecker;
/** /**
* Expert: The default cache implementation, storing all values in memory. * Expert: The default cache implementation, storing all values in memory.
@ -208,12 +209,39 @@ class FieldCacheImpl implements ExtendedFieldCache {
synchronized (readerCache) { synchronized (readerCache) {
innerCache.put(key, progress.value); 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 progress.value;
} }
} }
return 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. */ /** Expert: Every composite-key in the internal cache is of this type. */
@ -811,6 +839,15 @@ class FieldCacheImpl implements ExtendedFieldCache {
return retArray; 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 org.apache.lucene.util.LuceneTestCase;
import java.io.IOException; import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class TestFieldCache extends LuceneTestCase { public class TestFieldCache extends LuceneTestCase {
protected IndexReader reader; protected IndexReader reader;
@ -58,6 +60,18 @@ public class TestFieldCache extends LuceneTestCase {
reader = IndexReader.open(directory); 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 { public void test() throws IOException {
FieldCache cache = FieldCache.DEFAULT; FieldCache cache = FieldCache.DEFAULT;