You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2012/08/22 23:29:37 UTC
svn commit: r1376261 - in /lucene/dev/trunk/lucene: CHANGES.txt
core/src/java/org/apache/lucene/document/Field.java
core/src/test/org/apache/lucene/document/TestField.java
Author: uschindler
Date: Wed Aug 22 21:29:36 2012
New Revision: 1376261
URL: http://svn.apache.org/viewvc?rev=1376261&view=rev
Log:
LUCENE-4315: Add ReusableStringReader to Field.java
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/document/Field.java
lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/document/TestField.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1376261&r1=1376260&r2=1376261&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Aug 22 21:29:36 2012
@@ -104,8 +104,8 @@ Bug Fixes
Optimizations
-* LUCENE-4317: Improve reuse of internal TokenStreams in oal.document.Field.
- (Uwe Schindler, Chris Male, Robert Muir)
+* LUCENE-4317: Improve reuse of internal TokenStreams and StringReader
+ in oal.document.Field. (Uwe Schindler, Chris Male, Robert Muir)
Build
Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/document/Field.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/document/Field.java?rev=1376261&r1=1376260&r2=1376261&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/document/Field.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/document/Field.java Wed Aug 22 21:29:36 2012
@@ -19,7 +19,6 @@ package org.apache.lucene.document;
import java.io.IOException;
import java.io.Reader;
-import java.io.StringReader;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.NumericTokenStream;
@@ -73,7 +72,8 @@ public class Field implements IndexableF
// customize how it's tokenized:
protected TokenStream tokenStream;
- protected transient TokenStream internalTokenStream;
+ private transient TokenStream internalTokenStream;
+ private transient ReusableStringReader internalReader;
protected float boost = 1.0f;
@@ -460,12 +460,56 @@ public class Field implements IndexableF
} else if (readerValue() != null) {
return analyzer.tokenStream(name(), readerValue());
} else if (stringValue() != null) {
- return analyzer.tokenStream(name(), new StringReader(stringValue()));
+ if (internalReader == null) {
+ internalReader = new ReusableStringReader();
+ }
+ internalReader.setValue(stringValue());
+ return analyzer.tokenStream(name(), internalReader);
}
throw new IllegalArgumentException("Field must have either TokenStream, String, Reader or Number value");
}
+ static final class ReusableStringReader extends Reader {
+ private int pos = 0, size = 0;
+ private String s = null;
+
+ void setValue(String s) {
+ this.s = s;
+ this.size = s.length();
+ this.pos = 0;
+ }
+
+ @Override
+ public int read() {
+ if (pos < size) {
+ return s.charAt(pos++);
+ } else {
+ s = null;
+ return -1;
+ }
+ }
+
+ @Override
+ public int read(char[] c, int off, int len) {
+ if (pos < size) {
+ len = Math.min(len, size-pos);
+ s.getChars(pos, pos+len, c, off);
+ pos += len;
+ return len;
+ } else {
+ s = null;
+ return -1;
+ }
+ }
+
+ @Override
+ public void close() {
+ pos = size; // this prevents NPE when reading after close!
+ s = null;
+ }
+ }
+
static final class StringTokenStream extends TokenStream {
private final CharTermAttribute termAttribute = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAttribute = addAttribute(OffsetAttribute.class);
@@ -506,6 +550,11 @@ public class Field implements IndexableF
public void reset() {
used = false;
}
+
+ @Override
+ public void close() {
+ value = null;
+ }
}
/** Specifies whether and how a field should be stored. */
Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/document/TestField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/document/TestField.java?rev=1376261&r1=1376260&r2=1376261&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/document/TestField.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/document/TestField.java Wed Aug 22 21:29:36 2012
@@ -18,9 +18,11 @@ package org.apache.lucene.document;
*/
import java.io.StringReader;
+import java.nio.CharBuffer;
import org.apache.lucene.analysis.CannedTokenStream;
import org.apache.lucene.analysis.Token;
+import org.apache.lucene.document.Field.ReusableStringReader;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
@@ -610,4 +612,40 @@ public class TestField extends LuceneTes
// expected
}
}
+
+ public void testReusableStringReader() throws Exception {
+ ReusableStringReader reader = new ReusableStringReader();
+ assertEquals(-1, reader.read());
+ assertEquals(-1, reader.read(new char[1]));
+ assertEquals(-1, reader.read(new char[2], 1, 1));
+ assertEquals(-1, reader.read(CharBuffer.wrap(new char[2])));
+
+ reader.setValue("foobar");
+ char[] buf = new char[4];
+ assertEquals(4, reader.read(buf));
+ assertEquals("foob", new String(buf));
+ assertEquals(2, reader.read(buf));
+ assertEquals("ar", new String(buf, 0, 2));
+ assertEquals(-1, reader.read(buf));
+ reader.close();
+
+ reader.setValue("foobar");
+ assertEquals(0, reader.read(buf, 1, 0));
+ assertEquals(3, reader.read(buf, 1, 3));
+ assertEquals("foo", new String(buf, 1, 3));
+ assertEquals(2, reader.read(CharBuffer.wrap(buf, 2, 2)));
+ assertEquals("ba", new String(buf, 2, 2));
+ assertEquals('r', (char) reader.read());
+ assertEquals(-1, reader.read(buf));
+ reader.close();
+
+ reader.setValue("foobar");
+ StringBuilder sb = new StringBuilder();
+ int ch;
+ while ((ch = reader.read()) != -1) {
+ sb.append((char) ch);
+ }
+ reader.close();
+ assertEquals("foobar", sb.toString());
+ }
}