throws IOException {
String field = fieldName.intern();
int maxDoc = reader.maxDoc();
int dictValueCount = getDictValueCount(reader, fieldName);
BigSegmentedArray order = newInstance(dictValueCount, maxDoc);
this.orderArray = order;
IntArrayList minIDList = new IntArrayList();
IntArrayList maxIDList = new IntArrayList();
IntArrayList freqList = new IntArrayList();
int length = maxDoc + 1;
@SuppressWarnings("unchecked")
TermValueList<T> list = listFactory == null ? (TermValueList<T>) new TermStringList()
: listFactory.createTermList();
int negativeValueCount = getNegativeValueCount(reader, field);
int t = 1; // valid term id starts from 1
list.add(null);
minIDList.add(-1);
maxIDList.add(-1);
freqList.add(0);
int totalFreq = 0;
Terms terms = reader.terms(field);
if (terms != null) {
TermsEnum termsEnum = terms.iterator(null);
BytesRef text;
while ((text = termsEnum.next()) != null) {
// store term text
// we expect that there is at most one term per document
if (t >= length) throw new RuntimeException("there are more terms than "
+ "documents in field \"" + field + "\", but it's impossible to sort on "
+ "tokenized fields");
String strText = text.utf8ToString();
list.add(strText);
Term term = new Term(field, strText);
DocsEnum docsEnum = reader.termDocsEnum(term);
int minID = -1;
int maxID = -1;
int docID;
int df = 0;
int valId = (t - 1 < negativeValueCount) ? (negativeValueCount - t + 1) : t;
while ((docID = docsEnum.nextDoc()) != DocsEnum.NO_MORE_DOCS) {
df++;
order.add(docID, valId);
minID = docID;
while (docsEnum.nextDoc() != DocsEnum.NO_MORE_DOCS) {
docID = docsEnum.docID();
df++;
order.add(docID, valId);
}
maxID = docID;
}
freqList.add(df);
totalFreq += df;
minIDList.add(minID);
maxIDList.add(maxID);
t++;
}
}
list.seal();
// Process minIDList and maxIDList for negative number
for (int i = 1; i < negativeValueCount/2 + 1; ++i) {
int top = i;
int tail = negativeValueCount - i + 1;
int topValue = minIDList.getInt(top);
int tailValue = minIDList.getInt(tail);
minIDList.set(top, tailValue);
minIDList.set(tail, topValue);
topValue = maxIDList.getInt(top);
tailValue = maxIDList.getInt(tail);
maxIDList.set(top, tailValue);
maxIDList.set(tail, topValue);
}
this.valArray = list;
this.freqs = freqList.toIntArray();
this.minIDs = minIDList.toIntArray();
this.maxIDs = maxIDList.toIntArray();
int doc = 0;
while (doc < maxDoc && order.get(doc) != 0) {
++doc;
}
if (doc < maxDoc) {
this.minIDs[0] = doc;
// Try to get the max
doc = maxDoc - 1;
while (doc >= 0 && order.get(doc) != 0) {
--doc;
}
this.maxIDs[0] = doc;
}
this.freqs[0] = reader.numDocs() - totalFreq;