package org.apache.solr.request.uninverted; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; public class TermIndex { // public static Logger log = LoggerFactory.getLogger(TermIndex.class); final static int intervalBits = 7; // decrease to a low number like 2 for testing public final static int intervalMask = 0xffffffff >>> (32-intervalBits); public final static int interval = 1 << intervalBits; final Term fterm; // prototype to be used in term construction w/o String.intern overhead final String prefix; int nTerms; long sizeOfStrings; String field; IndexSearch index; public static class IndexSearch { String[] index; @Override public String toString() { return "IndexSearch [index=" + Arrays.toString(index) + "]"; } public String get(int i) throws IOException { if (index == null || i >= index.length) { return "null"; } return index[i]; } public int search(String s) throws IOException { return Arrays.binarySearch(index, s); } } public TermIndex(String field) { this(field, null); } public TermIndex(String _field, String prefix) { this.field=_field; this.fterm = new Term(_field, ""); this.prefix = prefix; } public Term createTerm(String termVal) { return fterm.createTerm(termVal); } public TermNumEnumerator getEnumerator(IndexReader reader, int termNumber) throws IOException { TermNumEnumerator te = new TermNumEnumerator(reader, this); te.skipTo(termNumber); return te; } /* The first time an enumerator is requested, it should be used with next() to fully traverse all of the terms so the index will be built. */ public TermNumEnumerator getEnumerator(IndexReader reader) throws IOException { if (index==null) return new TermNumEnumerator(reader,this, prefix==null?"":prefix, 0) { ArrayList<String> lst; @Override protected boolean setTerm() { boolean b = super.setTerm(); if (b && (pos & intervalMask)==0) { String text = term().text(); sizeOfStrings += text.length() << 1; if (lst==null) { lst = new ArrayList<String>(); } lst.add(text); } return b; } @Override public boolean skipTo(Term target) throws IOException { throw new UnsupportedOperationException(); } @Override public boolean skipTo(int termNumber) throws IOException { throw new UnsupportedOperationException(); } @Override public void close() throws IOException { nTerms=pos; super.close(); index=new IndexSearch(); index.index = lst!=null ? lst.toArray(new String[lst.size()]) : new String[0]; } }; else return new TermNumEnumerator(reader,this,"",0); } public long memSize() { long size=0l; if(index.index!=null) { size+=index.index.length<<3; } return 8+8+8+8+size+sizeOfStrings; } }