Index: solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java =================================================================== --- solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java (revision 1206547) +++ solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java (working copy) @@ -23,6 +23,7 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.OpenBitSet; +import org.apache.lucene.util.StringHelper; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; @@ -301,7 +302,7 @@ toDeState.minSetSizeCached = minDocFreqTo; while (term != null) { - if (prefix != null && !term.startsWith(prefix)) + if (prefix != null && !StringHelper.startsWith(term, prefix)) break; fromTermCount++; Index: solr/core/src/java/org/apache/solr/request/SimpleFacets.java =================================================================== --- solr/core/src/java/org/apache/solr/request/SimpleFacets.java (revision 1206547) +++ solr/core/src/java/org/apache/solr/request/SimpleFacets.java (working copy) @@ -656,7 +656,7 @@ if (docs.size() >= mincount) { while (term != null) { - if (startTermBytes != null && !term.startsWith(startTermBytes)) + if (startTermBytes != null && !StringHelper.startsWith(term, startTermBytes)) break; int df = termsEnum.docFreq(); Index: solr/core/src/java/org/apache/solr/handler/component/TermsComponent.java =================================================================== --- solr/core/src/java/org/apache/solr/handler/component/TermsComponent.java (revision 1206547) +++ solr/core/src/java/org/apache/solr/handler/component/TermsComponent.java (working copy) @@ -19,6 +19,7 @@ import org.apache.lucene.index.*; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CharsRef; +import org.apache.lucene.util.StringHelper; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.*; import org.apache.solr.common.util.NamedList; @@ -183,7 +184,7 @@ boolean externalized = false; // did we fill in "external" yet for this term? // stop if the prefix doesn't match - if (prefixBytes != null && !term.startsWith(prefixBytes)) break; + if (prefixBytes != null && !StringHelper.startsWith(term, prefixBytes)) break; if (pattern != null) { // indexed text or external text? Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndTruncQuery.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndTruncQuery.java (revision 1206547) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndTruncQuery.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.Terms; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiFields; @@ -106,7 +107,7 @@ } while(text != null) { - if (text != null && text.startsWith(prefixRef)) { + if (text != null && StringHelper.startsWith(text, prefixRef)) { String textString = text.utf8ToString(); matcher.reset(textString.substring(prefixLength)); if (matcher.matches()) { Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndPrefixQuery.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndPrefixQuery.java (revision 1206547) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SrndPrefixQuery.java (working copy) @@ -19,6 +19,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.Terms; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiFields; @@ -67,7 +68,7 @@ if (status == TermsEnum.SeekStatus.FOUND) { mtv.visitMatchingTerm(getLucenePrefixTerm(fieldName)); } else if (status == TermsEnum.SeekStatus.NOT_FOUND) { - if (termsEnum.term().startsWith(prefixRef)) { + if (StringHelper.startsWith(termsEnum.term(), prefixRef)) { mtv.visitMatchingTerm(new Term(fieldName, termsEnum.term().utf8ToString())); } else { skip = true; @@ -80,7 +81,7 @@ if (!skip) { while(true) { BytesRef text = termsEnum.next(); - if (text != null && text.startsWith(prefixRef)) { + if (text != null && StringHelper.startsWith(text, prefixRef)) { mtv.visitMatchingTerm(new Term(fieldName, text.utf8ToString())); } else { break; Index: lucene/contrib/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexTermsEnum.java =================================================================== --- lucene/contrib/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexTermsEnum.java (revision 1206547) +++ lucene/contrib/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexTermsEnum.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.StringHelper; import java.io.IOException; @@ -53,7 +54,7 @@ @Override protected AcceptStatus accept(BytesRef term) { - if (term.startsWith(prefixRef)) { + if (StringHelper.startsWith(term, prefixRef)) { // TODO: set BoostAttr based on distance of // searchTerm.text() and term().text() return regexImpl.match(term) ? AcceptStatus.YES : AcceptStatus.NO; Index: lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java =================================================================== --- lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java (revision 1206547) +++ lucene/src/test/org/apache/lucene/search/TestPrefixRandom.java (working copy) @@ -35,6 +35,7 @@ import org.apache.lucene.util.AttributeSource; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util._TestUtil; /** @@ -104,7 +105,7 @@ @Override protected AcceptStatus accept(BytesRef term) throws IOException { - return term.startsWith(prefix) ? AcceptStatus.YES : AcceptStatus.NO; + return StringHelper.startsWith(term, prefix) ? AcceptStatus.YES : AcceptStatus.NO; } } Index: lucene/src/test/org/apache/lucene/index/TestDocTermOrds.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestDocTermOrds.java (revision 1206547) +++ lucene/src/test/org/apache/lucene/index/TestDocTermOrds.java (working copy) @@ -37,6 +37,7 @@ import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util._TestUtil; // TODO: @@ -262,7 +263,7 @@ final int[] docOrds = idToOrds[id]; final List newOrds = new ArrayList(); for(int ord : idToOrds[id]) { - if (termsArray[ord].startsWith(prefixRef)) { + if (StringHelper.startsWith(termsArray[ord], prefixRef)) { newOrds.add(ord); } } @@ -332,7 +333,7 @@ TermsEnum termsEnum = terms.iterator(null); TermsEnum.SeekStatus result = termsEnum.seekCeil(prefixRef, false); if (result != TermsEnum.SeekStatus.END) { - assertFalse("term=" + termsEnum.term().utf8ToString() + " matches prefix=" + prefixRef.utf8ToString(), termsEnum.term().startsWith(prefixRef)); + assertFalse("term=" + termsEnum.term().utf8ToString() + " matches prefix=" + prefixRef.utf8ToString(), StringHelper.startsWith(termsEnum.term(), prefixRef)); } else { // ok } Index: lucene/src/java/org/apache/lucene/search/PrefixTermsEnum.java =================================================================== --- lucene/src/java/org/apache/lucene/search/PrefixTermsEnum.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/search/PrefixTermsEnum.java (working copy) @@ -22,6 +22,7 @@ import org.apache.lucene.index.FilteredTermsEnum; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.StringHelper; /** * Subclass of FilteredTermEnum for enumerating all terms that match the @@ -41,7 +42,7 @@ @Override protected AcceptStatus accept(BytesRef term) { - if (term.startsWith(prefixRef)) { + if (StringHelper.startsWith(term, prefixRef)) { return AcceptStatus.YES; } else { return AcceptStatus.END; Index: lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java =================================================================== --- lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java (working copy) @@ -35,6 +35,7 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IntsRef; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; import org.apache.lucene.util.automaton.Automaton; import org.apache.lucene.util.automaton.BasicAutomata; @@ -428,7 +429,7 @@ */ @Override protected final AcceptStatus accept(BytesRef term) { - if (term.startsWith(prefixBytesRef)) { + if (StringHelper.startsWith(term, prefixBytesRef)) { UnicodeUtil.UTF8toUTF32(term, utf32); final float similarity = similarity(utf32.ints, realPrefixLength, utf32.length - realPrefixLength); if (similarity > minSimilarity) { Index: lucene/src/java/org/apache/lucene/index/DocTermOrds.java =================================================================== --- lucene/src/java/org/apache/lucene/index/DocTermOrds.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/DocTermOrds.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.util.PagedBytes; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.StringHelper; import java.io.IOException; import java.util.ArrayList; @@ -278,7 +279,7 @@ // seek above): for (;;) { final BytesRef t = te.term(); - if (t == null || (termPrefix != null && !t.startsWith(termPrefix))) { + if (t == null || (termPrefix != null && !StringHelper.startsWith(t, termPrefix))) { break; } //System.out.println("visit term=" + t.utf8ToString() + " " + t + " termNum=" + termNum); @@ -785,7 +786,7 @@ private BytesRef setTerm() throws IOException { term = termsEnum.term(); //System.out.println(" setTerm() term=" + term.utf8ToString() + " vs prefix=" + (prefix == null ? "null" : prefix.utf8ToString())); - if (prefix != null && !term.startsWith(prefix)) { + if (prefix != null && !StringHelper.startsWith(term, prefix)) { term = null; } return term; Index: lucene/src/java/org/apache/lucene/index/AutomatonTermsEnum.java =================================================================== --- lucene/src/java/org/apache/lucene/index/AutomatonTermsEnum.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/AutomatonTermsEnum.java (working copy) @@ -22,6 +22,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IntsRef; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.automaton.ByteRunAutomaton; import org.apache.lucene.util.automaton.CompiledAutomaton; import org.apache.lucene.util.automaton.Transition; @@ -94,7 +95,7 @@ */ @Override protected AcceptStatus accept(final BytesRef term) { - if (commonSuffixRef == null || term.endsWith(commonSuffixRef)) { + if (commonSuffixRef == null || StringHelper.endsWith(term, commonSuffixRef)) { if (runAutomaton.run(term.bytes, term.offset, term.length)) return linear ? AcceptStatus.YES : AcceptStatus.YES_AND_SEEK; else Index: lucene/src/java/org/apache/lucene/index/codecs/DefaultTermVectorsWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/DefaultTermVectorsWriter.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/DefaultTermVectorsWriter.java (working copy) @@ -125,8 +125,7 @@ @Override public void startTerm(BytesRef term, int freq) throws IOException { - final int prefix = StringHelper.bytesDifference(lastTerm.bytes, lastTerm.offset, lastTerm.length, - term.bytes, term.offset, term.length); + final int prefix = StringHelper.bytesDifference(lastTerm, term); final int suffix = term.length - prefix; tvf.writeVInt(prefix); tvf.writeVInt(suffix); Index: lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextSegmentInfosReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextSegmentInfosReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextSegmentInfosReader.java (working copy) @@ -32,6 +32,7 @@ import org.apache.lucene.store.IOContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; +import org.apache.lucene.util.StringHelper; import static org.apache.lucene.index.codecs.simpletext.SimpleTextSegmentInfosWriter.*; @@ -48,35 +49,35 @@ final BytesRef scratch = new BytesRef(); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(VERSION); + assert StringHelper.startsWith(scratch, VERSION); infos.version = Long.parseLong(readString(VERSION.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(COUNTER); + assert StringHelper.startsWith(scratch, COUNTER); infos.counter = Integer.parseInt(readString(COUNTER.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(FNX_VERSION); + assert StringHelper.startsWith(scratch, FNX_VERSION); infos.setGlobalFieldMapVersion(Long.parseLong(readString(FNX_VERSION.length, scratch))); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NUM_USERDATA); + assert StringHelper.startsWith(scratch, NUM_USERDATA); int numUserData = Integer.parseInt(readString(NUM_USERDATA.length, scratch)); infos.userData = new HashMap(); for (int i = 0; i < numUserData; i++) { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(USERDATA_KEY); + assert StringHelper.startsWith(scratch, USERDATA_KEY); String key = readString(USERDATA_KEY.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(USERDATA_VALUE); + assert StringHelper.startsWith(scratch, USERDATA_VALUE); String value = readString(USERDATA_VALUE.length, scratch); infos.userData.put(key, value); } SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NUM_SEGMENTS); + assert StringHelper.startsWith(scratch, NUM_SEGMENTS); int numSegments = Integer.parseInt(readString(NUM_SEGMENTS.length, scratch)); for (int i = 0; i < numSegments; i++) { @@ -86,55 +87,55 @@ public SegmentInfo readSegmentInfo(Directory directory, DataInput input, BytesRef scratch) throws IOException { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_NAME); + assert StringHelper.startsWith(scratch, SI_NAME); final String name = readString(SI_NAME.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_CODEC); + assert StringHelper.startsWith(scratch, SI_CODEC); final Codec codec = Codec.forName(readString(SI_CODEC.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_VERSION); + assert StringHelper.startsWith(scratch, SI_VERSION); final String version = readString(SI_VERSION.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DOCCOUNT); + assert StringHelper.startsWith(scratch, SI_DOCCOUNT); final int docCount = Integer.parseInt(readString(SI_DOCCOUNT.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DELCOUNT); + assert StringHelper.startsWith(scratch, SI_DELCOUNT); final int delCount = Integer.parseInt(readString(SI_DELCOUNT.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_HASPROX); + assert StringHelper.startsWith(scratch, SI_HASPROX); final int hasProx = readTernary(SI_HASPROX.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_HASVECTORS); + assert StringHelper.startsWith(scratch, SI_HASVECTORS); final int hasVectors = readTernary(SI_HASVECTORS.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_USECOMPOUND); + assert StringHelper.startsWith(scratch, SI_USECOMPOUND); final boolean isCompoundFile = Boolean.parseBoolean(readString(SI_USECOMPOUND.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DSOFFSET); + assert StringHelper.startsWith(scratch, SI_DSOFFSET); final int dsOffset = Integer.parseInt(readString(SI_DSOFFSET.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DSSEGMENT); + assert StringHelper.startsWith(scratch, SI_DSSEGMENT); final String dsSegment = readString(SI_DSSEGMENT.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DSCOMPOUND); + assert StringHelper.startsWith(scratch, SI_DSCOMPOUND); final boolean dsCompoundFile = Boolean.parseBoolean(readString(SI_DSCOMPOUND.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DELGEN); + assert StringHelper.startsWith(scratch, SI_DELGEN); final long delGen = Long.parseLong(readString(SI_DELGEN.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_NUM_NORMGEN); + assert StringHelper.startsWith(scratch, SI_NUM_NORMGEN); final int numNormGen = Integer.parseInt(readString(SI_NUM_NORMGEN.length, scratch)); final Map normGen; if (numNormGen == 0) { @@ -143,28 +144,28 @@ normGen = new HashMap(); for (int i = 0; i < numNormGen; i++) { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_NORMGEN_KEY); + assert StringHelper.startsWith(scratch, SI_NORMGEN_KEY); int key = Integer.parseInt(readString(SI_NORMGEN_KEY.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_NORMGEN_VALUE); + assert StringHelper.startsWith(scratch, SI_NORMGEN_VALUE); long value = Long.parseLong(readString(SI_NORMGEN_VALUE.length, scratch)); normGen.put(key, value); } } SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_NUM_DIAG); + assert StringHelper.startsWith(scratch, SI_NUM_DIAG); int numDiag = Integer.parseInt(readString(SI_NUM_DIAG.length, scratch)); Map diagnostics = new HashMap(); for (int i = 0; i < numDiag; i++) { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DIAG_KEY); + assert StringHelper.startsWith(scratch, SI_DIAG_KEY); String key = readString(SI_DIAG_KEY.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(SI_DIAG_VALUE); + assert StringHelper.startsWith(scratch, SI_DIAG_VALUE); String value = readString(SI_DIAG_VALUE.length, scratch); diagnostics.put(key, value); } Index: lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java (working copy) @@ -32,6 +32,7 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.OpenBitSet; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; import org.apache.lucene.util.fst.Builder; import org.apache.lucene.util.fst.BytesRefFSTEnum; @@ -80,7 +81,7 @@ current = null; return null; } - if (scratch.startsWith(FIELD)) { + if (StringHelper.startsWith(scratch, FIELD)) { return current = new String(scratch.bytes, scratch.offset + FIELD.length, scratch.length - FIELD.length, "UTF-8"); } } @@ -270,7 +271,7 @@ while(true) { final long lineStart = in.getFilePointer(); SimpleTextUtil.readLine(in, scratch); - if (scratch.startsWith(DOC)) { + if (StringHelper.startsWith(scratch, DOC)) { if (!first && (liveDocs == null || liveDocs.get(docID))) { in.seek(lineStart); if (!omitTF) { @@ -282,15 +283,15 @@ docID = ArrayUtil.parseInt(scratchUTF16.chars, 0, scratchUTF16.length); termFreq = 0; first = false; - } else if (scratch.startsWith(FREQ)) { + } else if (StringHelper.startsWith(scratch, FREQ)) { UnicodeUtil.UTF8toUTF16(scratch.bytes, scratch.offset+FREQ.length, scratch.length-FREQ.length, scratchUTF16); termFreq = ArrayUtil.parseInt(scratchUTF16.chars, 0, scratchUTF16.length); - } else if (scratch.startsWith(POS)) { + } else if (StringHelper.startsWith(scratch, POS)) { // skip termFreq++; - } else if (scratch.startsWith(PAYLOAD)) { + } else if (StringHelper.startsWith(scratch, PAYLOAD)) { // skip } else { - assert scratch.startsWith(TERM) || scratch.startsWith(FIELD) || scratch.startsWith(END): "scratch=" + scratch.utf8ToString(); + assert StringHelper.startsWith(scratch, TERM) || StringHelper.startsWith(scratch, FIELD) || StringHelper.startsWith(scratch, END): "scratch=" + scratch.utf8ToString(); if (!first && (liveDocs == null || liveDocs.get(docID))) { in.seek(lineStart); if (!omitTF) { @@ -358,7 +359,7 @@ while(true) { final long lineStart = in.getFilePointer(); SimpleTextUtil.readLine(in, scratch); - if (scratch.startsWith(DOC)) { + if (StringHelper.startsWith(scratch, DOC)) { if (!first && (liveDocs == null || liveDocs.get(docID))) { nextDocStart = lineStart; in.seek(posStart); @@ -368,16 +369,16 @@ docID = ArrayUtil.parseInt(scratchUTF16.chars, 0, scratchUTF16.length); tf = 0; first = false; - } else if (scratch.startsWith(FREQ)) { + } else if (StringHelper.startsWith(scratch, FREQ)) { UnicodeUtil.UTF8toUTF16(scratch.bytes, scratch.offset+FREQ.length, scratch.length-FREQ.length, scratchUTF16); tf = ArrayUtil.parseInt(scratchUTF16.chars, 0, scratchUTF16.length); posStart = in.getFilePointer(); - } else if (scratch.startsWith(POS)) { + } else if (StringHelper.startsWith(scratch, POS)) { // skip - } else if (scratch.startsWith(PAYLOAD)) { + } else if (StringHelper.startsWith(scratch, PAYLOAD)) { // skip } else { - assert scratch.startsWith(TERM) || scratch.startsWith(FIELD) || scratch.startsWith(END); + assert StringHelper.startsWith(scratch, TERM) || StringHelper.startsWith(scratch, FIELD) || StringHelper.startsWith(scratch, END); if (!first && (liveDocs == null || liveDocs.get(docID))) { nextDocStart = lineStart; in.seek(posStart); @@ -398,12 +399,12 @@ @Override public int nextPosition() throws IOException { SimpleTextUtil.readLine(in, scratch); - assert scratch.startsWith(POS): "got line=" + scratch.utf8ToString(); + assert StringHelper.startsWith(scratch, POS): "got line=" + scratch.utf8ToString(); UnicodeUtil.UTF8toUTF16(scratch.bytes, scratch.offset+POS.length, scratch.length-POS.length, scratchUTF16_2); final int pos = ArrayUtil.parseInt(scratchUTF16_2.chars, 0, scratchUTF16_2.length); final long fp = in.getFilePointer(); SimpleTextUtil.readLine(in, scratch); - if (scratch.startsWith(PAYLOAD)) { + if (StringHelper.startsWith(scratch, PAYLOAD)) { final int len = scratch.length - PAYLOAD.length; if (scratch2.bytes.length < len) { scratch2.grow(len); @@ -477,7 +478,7 @@ OpenBitSet visitedDocs = new OpenBitSet(); while(true) { SimpleTextUtil.readLine(in, scratch); - if (scratch.equals(END) || scratch.startsWith(FIELD)) { + if (scratch.equals(END) || StringHelper.startsWith(scratch, FIELD)) { if (lastDocsStart != -1) { b.add(lastTerm, new PairOutputs.Pair>(lastDocsStart, new PairOutputs.Pair((long) docFreq, @@ -485,15 +486,15 @@ sumTotalTermFreq += totalTermFreq; } break; - } else if (scratch.startsWith(DOC)) { + } else if (StringHelper.startsWith(scratch, DOC)) { docFreq++; sumDocFreq++; UnicodeUtil.UTF8toUTF16(scratch.bytes, scratch.offset+DOC.length, scratch.length-DOC.length, scratchUTF16); int docID = ArrayUtil.parseInt(scratchUTF16.chars, 0, scratchUTF16.length); visitedDocs.set(docID); - } else if (scratch.startsWith(POS)) { + } else if (StringHelper.startsWith(scratch, POS)) { totalTermFreq++; - } else if (scratch.startsWith(TERM)) { + } else if (StringHelper.startsWith(scratch, TERM)) { if (lastDocsStart != -1) { b.add(lastTerm, new PairOutputs.Pair>(lastDocsStart, new PairOutputs.Pair((long) docFreq, Index: lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextTermVectorsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextTermVectorsReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextTermVectorsReader.java (working copy) @@ -46,6 +46,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.IOUtils; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; import static org.apache.lucene.index.codecs.simpletext.SimpleTextTermVectorsWriter.*; @@ -88,7 +89,7 @@ offsets = new ArrayList(); while (!scratch.equals(END)) { readLine(); - if (scratch.startsWith(DOC)) { + if (StringHelper.startsWith(scratch, DOC)) { offsets.add(in.getFilePointer()); } } @@ -105,30 +106,30 @@ SortedMap fields = new TreeMap(); in.seek(offsets.get(doc)); readLine(); - assert scratch.startsWith(NUMFIELDS); + assert StringHelper.startsWith(scratch, NUMFIELDS); int numFields = parseIntAt(NUMFIELDS.length); if (numFields == 0) { return null; // no vectors for this doc } for (int i = 0; i < numFields; i++) { readLine(); - assert scratch.startsWith(FIELD); + assert StringHelper.startsWith(scratch, FIELD); int fieldNumber = parseIntAt(FIELD.length); readLine(); - assert scratch.startsWith(FIELDNAME); + assert StringHelper.startsWith(scratch, FIELDNAME); String fieldName = readString(FIELDNAME.length, scratch); readLine(); - assert scratch.startsWith(FIELDPOSITIONS); + assert StringHelper.startsWith(scratch, FIELDPOSITIONS); boolean positions = Boolean.parseBoolean(readString(FIELDPOSITIONS.length, scratch)); readLine(); - assert scratch.startsWith(FIELDOFFSETS); + assert StringHelper.startsWith(scratch, FIELDOFFSETS); boolean offsets = Boolean.parseBoolean(readString(FIELDOFFSETS.length, scratch)); readLine(); - assert scratch.startsWith(FIELDTERMCOUNT); + assert StringHelper.startsWith(scratch, FIELDTERMCOUNT); int termCount = parseIntAt(FIELDTERMCOUNT.length); SimpleTVTerms terms = new SimpleTVTerms(); @@ -136,7 +137,7 @@ for (int j = 0; j < termCount; j++) { readLine(); - assert scratch.startsWith(TERMTEXT); + assert StringHelper.startsWith(scratch, TERMTEXT); BytesRef term = new BytesRef(); int termLength = scratch.length - TERMTEXT.length; term.grow(termLength); @@ -147,7 +148,7 @@ terms.terms.put(term, postings); readLine(); - assert scratch.startsWith(TERMFREQ); + assert StringHelper.startsWith(scratch, TERMFREQ); postings.freq = parseIntAt(TERMFREQ.length); if (positions || offsets) { @@ -163,17 +164,17 @@ for (int k = 0; k < postings.freq; k++) { if (positions) { readLine(); - assert scratch.startsWith(POSITION); + assert StringHelper.startsWith(scratch, POSITION); postings.positions[k] = parseIntAt(POSITION.length); } if (offsets) { readLine(); - assert scratch.startsWith(STARTOFFSET); + assert StringHelper.startsWith(scratch, STARTOFFSET); postings.startOffsets[k] = parseIntAt(STARTOFFSET.length); readLine(); - assert scratch.startsWith(ENDOFFSET); + assert StringHelper.startsWith(scratch, ENDOFFSET); postings.endOffsets[k] = parseIntAt(ENDOFFSET.length); } } Index: lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldInfosReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldInfosReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldInfosReader.java (working copy) @@ -33,6 +33,7 @@ import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; +import org.apache.lucene.util.StringHelper; import static org.apache.lucene.index.codecs.simpletext.SimpleTextFieldInfosWriter.*; @@ -57,45 +58,45 @@ try { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NUMFIELDS); + assert StringHelper.startsWith(scratch, NUMFIELDS); final int size = Integer.parseInt(readString(NUMFIELDS.length, scratch)); FieldInfo infos[] = new FieldInfo[size]; for (int i = 0; i < size; i++) { SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NAME); + assert StringHelper.startsWith(scratch, NAME); String name = readString(NAME.length, scratch); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NUMBER); + assert StringHelper.startsWith(scratch, NUMBER); int fieldNumber = Integer.parseInt(readString(NUMBER.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(ISINDEXED); + assert StringHelper.startsWith(scratch, ISINDEXED); boolean isIndexed = Boolean.parseBoolean(readString(ISINDEXED.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(STORETV); + assert StringHelper.startsWith(scratch, STORETV); boolean storeTermVector = Boolean.parseBoolean(readString(STORETV.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(STORETVPOS); + assert StringHelper.startsWith(scratch, STORETVPOS); boolean storePositionsWithTermVector = Boolean.parseBoolean(readString(STORETVPOS.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(STORETVOFF); + assert StringHelper.startsWith(scratch, STORETVOFF); boolean storeOffsetWithTermVector = Boolean.parseBoolean(readString(STORETVOFF.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(PAYLOADS); + assert StringHelper.startsWith(scratch, PAYLOADS); boolean storePayloads = Boolean.parseBoolean(readString(PAYLOADS.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(NORMS); + assert StringHelper.startsWith(scratch, NORMS); boolean omitNorms = !Boolean.parseBoolean(readString(NORMS.length, scratch)); SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(DOCVALUES); + assert StringHelper.startsWith(scratch, DOCVALUES); String dvType = readString(DOCVALUES.length, scratch); final ValueType docValuesType; @@ -106,7 +107,7 @@ } SimpleTextUtil.readLine(input, scratch); - assert scratch.startsWith(INDEXOPTIONS); + assert StringHelper.startsWith(scratch, INDEXOPTIONS); IndexOptions indexOptions = IndexOptions.valueOf(readString(INDEXOPTIONS.length, scratch)); hasVectors |= storeTermVector; Index: lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextStoredFieldsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextStoredFieldsReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextStoredFieldsReader.java (working copy) @@ -36,6 +36,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.IOUtils; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; import static org.apache.lucene.index.codecs.simpletext.SimpleTextStoredFieldsWriter.*; @@ -81,7 +82,7 @@ offsets = new ArrayList(); while (!scratch.equals(END)) { readLine(); - if (scratch.startsWith(DOC)) { + if (StringHelper.startsWith(scratch, DOC)) { offsets.add(in.getFilePointer()); } } @@ -91,18 +92,18 @@ public void visitDocument(int n, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { in.seek(offsets.get(n)); readLine(); - assert scratch.startsWith(NUM); + assert StringHelper.startsWith(scratch, NUM); int numFields = parseIntAt(NUM.length); for (int i = 0; i < numFields; i++) { readLine(); - assert scratch.startsWith(FIELD); + assert StringHelper.startsWith(scratch, FIELD); int fieldNumber = parseIntAt(FIELD.length); FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); readLine(); - assert scratch.startsWith(NAME); + assert StringHelper.startsWith(scratch, NAME); readLine(); - assert scratch.startsWith(TYPE); + assert StringHelper.startsWith(scratch, TYPE); final BytesRef type; if (equalsAt(TYPE_STRING, scratch, TYPE.length)) { @@ -127,7 +128,7 @@ break; case NO: readLine(); - assert scratch.startsWith(VALUE); + assert StringHelper.startsWith(scratch, VALUE); break; case STOP: return; } @@ -136,7 +137,7 @@ private void readField(BytesRef type, FieldInfo fieldInfo, StoredFieldVisitor visitor) throws IOException { readLine(); - assert scratch.startsWith(VALUE); + assert StringHelper.startsWith(scratch, VALUE); if (type == TYPE_STRING) { visitor.stringField(fieldInfo, new String(scratch.bytes, scratch.offset+VALUE.length, scratch.length-VALUE.length, "UTF-8")); } else if (type == TYPE_BINARY) { Index: lucene/src/java/org/apache/lucene/index/codecs/BlockTreeTermsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/BlockTreeTermsReader.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/index/codecs/BlockTreeTermsReader.java (working copy) @@ -47,6 +47,7 @@ import org.apache.lucene.util.CodecUtil; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.RamUsageEstimator; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.automaton.CompiledAutomaton; import org.apache.lucene.util.automaton.RunAutomaton; import org.apache.lucene.util.automaton.Transition; @@ -929,7 +930,7 @@ } System.arraycopy(currentFrame.suffixBytes, currentFrame.startBytePos, term.bytes, currentFrame.prefix, currentFrame.suffix); - if (isSubBlock && target.startsWith(term)) { + if (isSubBlock && StringHelper.startsWith(target, term)) { // Recurse //if (DEBUG) System.out.println(" recurse!"); currentFrame = pushFrame(getState()); Index: lucene/src/java/org/apache/lucene/util/StringHelper.java =================================================================== --- lucene/src/java/org/apache/lucene/util/StringHelper.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/util/StringHelper.java (working copy) @@ -29,36 +29,24 @@ public abstract class StringHelper { /** - * Compares two byte[] arrays, element by element, and returns the + * Compares two {@link BytesRef}, element by element, and returns the * number of elements common to both arrays. * - * @param bytes1 The first byte[] to compare - * @param bytes2 The second byte[] to compare + * @param left The first {@link BytesRef} to compare + * @param right The second {@link BytesRef} to compare * @return The number of common elements. */ - public static int bytesDifference(byte[] bytes1, int len1, byte[] bytes2, int len2) { - int len = len1 < len2 ? len1 : len2; + public static int bytesDifference(BytesRef left, BytesRef right) { + int len = left.length < right.length ? left.length : right.length; + final byte[] bytesLeft = left.bytes; + final int offLeft = left.offset; + byte[] bytesRight = right.bytes; + final int offRight = right.offset; for (int i = 0; i < len; i++) - if (bytes1[i] != bytes2[i]) + if (bytesLeft[i+offLeft] != bytesRight[i+offRight]) return i; return len; } - - /** - * Compares two byte[] arrays, element by element, and returns the - * number of elements common to both arrays. - * - * @param bytes1 The first byte[] to compare - * @param bytes2 The second byte[] to compare - * @return The number of common elements. - */ - public static int bytesDifference(byte[] bytes1, int off1, int len1, byte[] bytes2, int off2, int len2) { - int len = len1 < len2 ? len1 : len2; - for (int i = 0; i < len; i++) - if (bytes1[i+off1] != bytes2[i+off2]) - return i; - return len; - } private StringHelper() { } @@ -108,4 +96,51 @@ return s1.equals(s2); } } + + /** + * Returns true iff the ref starts with the given prefix. + * Otherwise false. + * + * @param ref + * the {@link BytesRef} to test + * @param prefix + * the expected prefix + * @return Returns true iff the ref starts with the given prefix. + * Otherwise false. + */ + public static boolean startsWith(BytesRef ref, BytesRef prefix) { + return sliceEquals(ref, prefix, 0); + } + + /** + * Returns true iff the ref ends with the given suffix. Otherwise + * false. + * + * @param ref + * the {@link BytesRef} to test + * @param suffix + * the expected suffix + * @return Returns true iff the ref ends with the given suffix. + * Otherwise false. + */ + public static boolean endsWith(BytesRef ref, BytesRef suffix) { + return sliceEquals(ref, suffix, ref.length - suffix.length); + } + + private static boolean sliceEquals(BytesRef sliceToTest, BytesRef other, int pos) { + if (pos < 0 || sliceToTest.length - pos < other.length) { + return false; + } + int i = sliceToTest.offset + pos; + int j = other.offset; + final int k = other.offset + other.length; + + while (j < k) { + if (sliceToTest.bytes[i++] != other.bytes[j++]) { + return false; + } + } + + return true; + } } Index: lucene/src/java/org/apache/lucene/util/BytesRef.java =================================================================== --- lucene/src/java/org/apache/lucene/util/BytesRef.java (revision 1206547) +++ lucene/src/java/org/apache/lucene/util/BytesRef.java (working copy) @@ -104,31 +104,7 @@ return new BytesRef(bytes, offset, length); } - private boolean sliceEquals(BytesRef other, int pos) { - if (pos < 0 || length - pos < other.length) { - return false; - } - int i = offset + pos; - int j = other.offset; - final int k = other.offset + other.length; - - while (j < k) { - if (bytes[i++] != other.bytes[j++]) { - return false; - } - } - - return true; - } - public boolean startsWith(BytesRef other) { - return sliceEquals(other, 0); - } - - public boolean endsWith(BytesRef other) { - return sliceEquals(other, length - other.length); - } - /** Calculates the hash code as required by TermsHash during indexing. *

It is defined as: *