You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by yo...@apache.org on 2015/03/28 01:10:19 UTC
svn commit: r1669713 - in /lucene/dev/branches/branch_5x/solr: ./ core/
core/src/java/org/apache/solr/search/facet/
core/src/test/org/apache/solr/search/facet/
Author: yonik
Date: Sat Mar 28 00:10:19 2015
New Revision: 1669713
URL: http://svn.apache.org/r1669713
Log:
SOLR-7214: optimize multi-valued counts-only case
Modified:
lucene/dev/branches/branch_5x/solr/ (props changed)
lucene/dev/branches/branch_5x/solr/core/ (props changed)
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/FacetField.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/FacetField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/FacetField.java?rev=1669713&r1=1669712&r2=1669713&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/FacetField.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/FacetField.java Sat Mar 28 00:10:19 2015
@@ -134,10 +134,12 @@ public class FacetField extends FacetReq
abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
SchemaField sf;
SlotAcc sortAcc;
+ int effectiveMincount;
FacetFieldProcessor(FacetContext fcontext, FacetField freq, SchemaField sf) {
super(fcontext, freq);
this.sf = sf;
+ this.effectiveMincount = (int)(fcontext.isShard() ? Math.min(1 , freq.mincount) : freq.mincount);
}
@Override
@@ -252,7 +254,6 @@ abstract class FacetFieldProcessorFCBase
};
Slot bottom = null;
- int effectiveMincount = (int)(fcontext.isShard() ? Math.min(1 , freq.mincount) : freq.mincount);
for (int i = (startTermIndex == -1) ? 1 : 0; i < nTerms; i++) {
if (countAcc.getCount(i) < effectiveMincount) {
continue;
@@ -304,8 +305,8 @@ abstract class FacetFieldProcessorFCBase
if (freq.allBuckets) {
SimpleOrderedMap<Object> allBuckets = new SimpleOrderedMap<>();
+ countAcc.setValues(allBuckets, allBucketsSlot);
for (SlotAcc acc : accs) {
- countAcc.setValues(allBuckets, allBucketsSlot);
acc.setValues(allBuckets, allBucketsSlot);
}
res.add("allBuckets", allBuckets);
@@ -648,7 +649,6 @@ class FacetFieldProcessorStream extends
}
public SimpleOrderedMap<Object> _nextBucket() throws IOException {
- int effectiveMincount = (int)(fcontext.isShard() ? Math.min(1 , freq.mincount) : freq.mincount);
DocSet termSet = null;
try {
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java?rev=1669713&r1=1669712&r2=1669713&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java Sat Mar 28 00:10:19 2015
@@ -290,6 +290,11 @@ class CountSlotAcc extends IntSlotAcc {
return result[slot];
}
+ // internal and expert
+ int[] getCountArray() {
+ return result;
+ }
+
@Override
public void reset() {
super.reset();
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java?rev=1669713&r1=1669712&r2=1669713&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java Sat Mar 28 00:10:19 2015
@@ -28,37 +28,23 @@ import java.util.concurrent.atomic.Atomi
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.SlowCompositeReaderWrapper;
-import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.uninverting.DocTermOrds;
-import org.apache.lucene.uninverting.UninvertingReader;
import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRefBuilder;
import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.UnicodeUtil;
import org.apache.solr.common.SolrException;
-import org.apache.solr.common.params.FacetParams;
-import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
-import org.apache.solr.handler.component.FieldFacetStats;
-import org.apache.solr.handler.component.StatsField;
-import org.apache.solr.handler.component.StatsValues;
-import org.apache.solr.handler.component.StatsValuesFactory;
-import org.apache.solr.request.SimpleFacets;
import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieField;
import org.apache.solr.search.BitDocSet;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocSet;
import org.apache.solr.search.SolrCache;
import org.apache.solr.search.SolrIndexSearcher;
-import org.apache.solr.util.LongPriorityQueue;
-import org.apache.solr.util.PrimUtils;
/**
*
@@ -94,6 +80,7 @@ public class UnInvertedField extends Doc
private static int TNUM_OFFSET=2;
static class TopTerm {
+ Query termQuery;
BytesRef term;
int termNum;
@@ -127,7 +114,7 @@ public class UnInvertedField extends Doc
if (termNum >= maxTermCounts.length) {
// resize by doubling - for very large number of unique terms, expanding
// by 4K and resultant GC will dominate uninvert times. Resize at end if material
- int[] newMaxTermCounts = new int[maxTermCounts.length*2];
+ int[] newMaxTermCounts = new int[ Math.min(Integer.MAX_VALUE-16, maxTermCounts.length*2) ];
System.arraycopy(maxTermCounts, 0, newMaxTermCounts, 0, termNum);
maxTermCounts = newMaxTermCounts;
}
@@ -138,6 +125,8 @@ public class UnInvertedField extends Doc
TopTerm topTerm = new TopTerm();
topTerm.term = BytesRef.deepCopyOf(term);
topTerm.termNum = termNum;
+ topTerm.termQuery = new TermQuery(new Term(field, topTerm.term));
+
bigTerms.put(topTerm.termNum, topTerm);
if (deState == null) {
@@ -188,7 +177,6 @@ public class UnInvertedField extends Doc
// small.
searcher.maxDoc()/20 + 2,
DEFAULT_INDEX_INTERVAL_BITS);
- //System.out.println("maxTermDocFreq=" + maxTermDocFreq + " maxDoc=" + searcher.maxDoc());
final String prefix = TrieField.getMainValuePrefix(searcher.getSchema().getFieldType(field));
this.searcher = searcher;
@@ -235,7 +223,7 @@ public class UnInvertedField extends Doc
bigTermNums = new int[bigTerms.size()];
int i=0;
for (TopTerm tt : bigTerms.values()) {
- bigTermSets[i] = searcher.getDocSet(new TermQuery(new Term(field, tt.term)));
+ bigTermSets[i] = searcher.getDocSet(tt.termQuery);
bigTermNums[i] = tt.termNum;
i++;
}
@@ -315,271 +303,148 @@ public class UnInvertedField extends Doc
}
- public NamedList<Integer> getCounts(SolrIndexSearcher searcher, DocSet baseDocs, int offset, int limit, Integer mincount, boolean missing, String sort, String prefix) throws IOException {
- use.incrementAndGet();
-
- FieldType ft = searcher.getSchema().getFieldType(field);
- NamedList<Integer> res = new NamedList<>(); // order is important
-
- DocSet docs = baseDocs;
+ private void getCountsInArray(FacetFieldProcessorUIF processor, int[] counts) throws IOException {
+ DocSet docs = processor.fcontext.base;
int baseSize = docs.size();
int maxDoc = searcher.maxDoc();
- //System.out.println("GET COUNTS field=" + field + " baseSize=" + baseSize + " minCount=" + mincount + " maxDoc=" + maxDoc + " numTermsInField=" + numTermsInField);
- if (baseSize >= mincount) {
+ if (baseSize < processor.effectiveMincount) {
+ return;
+ }
- final int[] index = this.index;
- // tricky: we add more more element than we need because we will reuse this array later
- // for ordering term ords before converting to term labels.
- final int[] counts = new int[numTermsInField + 1];
-
- //
- // If there is prefix, find its start and end term numbers
- //
- int startTerm = 0;
- int endTerm = numTermsInField; // one past the end
-
- TermsEnum te = getOrdTermsEnum(searcher.getLeafReader());
- if (te != null && prefix != null && prefix.length() > 0) {
- final BytesRefBuilder prefixBr = new BytesRefBuilder();
- prefixBr.copyChars(prefix);
- if (te.seekCeil(prefixBr.get()) == TermsEnum.SeekStatus.END) {
- startTerm = numTermsInField;
- } else {
- startTerm = (int) te.ord();
- }
- prefixBr.append(UnicodeUtil.BIG_TERM);
- if (te.seekCeil(prefixBr.get()) == TermsEnum.SeekStatus.END) {
- endTerm = numTermsInField;
- } else {
- endTerm = (int) te.ord();
- }
- }
+ final int[] index = this.index;
- /***********
- // Alternative 2: get the docSet of the prefix (could take a while) and
- // then do the intersection with the baseDocSet first.
- if (prefix != null && prefix.length() > 0) {
- docs = searcher.getDocSet(new ConstantScorePrefixQuery(new Term(field, ft.toInternal(prefix))), docs);
- // The issue with this method are problems of returning 0 counts for terms w/o
- // the prefix. We can't just filter out those terms later because it may
- // mean that we didn't collect enough terms in the queue (in the sorted case).
- }
- ***********/
-
- boolean doNegative = baseSize > maxDoc >> 1 && termInstances > 0
- && startTerm==0 && endTerm==numTermsInField
- && docs instanceof BitDocSet;
-
- if (doNegative) {
- FixedBitSet bs = ((BitDocSet)docs).getBits().clone();
- bs.flip(0, maxDoc);
- // TODO: when iterator across negative elements is available, use that
- // instead of creating a new bitset and inverting.
- docs = new BitDocSet(bs, maxDoc - baseSize);
- // simply negating will mean that we have deleted docs in the set.
- // that should be OK, as their entries in our table should be empty.
- //System.out.println(" NEG");
- }
+ boolean doNegative = baseSize > maxDoc >> 1 && termInstances > 0 && docs instanceof BitDocSet;
- // For the biggest terms, do straight set intersections
- for (TopTerm tt : bigTerms.values()) {
- //System.out.println(" do big termNum=" + tt.termNum + " term=" + tt.term.utf8ToString());
- // TODO: counts could be deferred if sorted==false
- if (tt.termNum >= startTerm && tt.termNum < endTerm) {
- counts[tt.termNum] = searcher.numDocs(new TermQuery(new Term(field, tt.term)), docs);
- //System.out.println(" count=" + counts[tt.termNum]);
- } else {
- //System.out.println("SKIP term=" + tt.termNum);
- }
- }
+ if (doNegative) {
+ FixedBitSet bs = ((BitDocSet) docs).getBits().clone();
+ bs.flip(0, maxDoc);
+ // TODO: when iterator across negative elements is available, use that
+ // instead of creating a new bitset and inverting.
+ docs = new BitDocSet(bs, maxDoc - baseSize);
+ // simply negating will mean that we have deleted docs in the set.
+ // that should be OK, as their entries in our table should be empty.
+ }
+
+ // For the biggest terms, do straight set intersections
+ for (TopTerm tt : bigTerms.values()) {
+ // TODO: counts could be deferred if sorting by index order
+ counts[tt.termNum] = searcher.numDocs(tt.termQuery, docs);
+ }
- // TODO: we could short-circuit counting altogether for sorted faceting
- // where we already have enough terms from the bigTerms
+ // TODO: we could short-circuit counting altogether for sorted faceting
+ // where we already have enough terms from the bigTerms
- // TODO: we could shrink the size of the collection array, and
- // additionally break when the termNumber got above endTerm, but
- // it would require two extra conditionals in the inner loop (although
- // they would be predictable for the non-prefix case).
- // Perhaps a different copy of the code would be warranted.
+ if (termInstances > 0) {
+ DocIterator iter = docs.iterator();
+ while (iter.hasNext()) {
+ int doc = iter.nextDoc();
+ int code = index[doc];
- if (termInstances > 0) {
- DocIterator iter = docs.iterator();
- while (iter.hasNext()) {
- int doc = iter.nextDoc();
- //System.out.println("iter doc=" + doc);
- int code = index[doc];
-
- if ((code & 0xff)==1) {
- //System.out.println(" ptr");
- int pos = code>>>8;
- int whichArray = (doc >>> 16) & 0xff;
- byte[] arr = tnums[whichArray];
- int tnum = 0;
- for(;;) {
- int delta = 0;
- for(;;) {
- byte b = arr[pos++];
- delta = (delta << 7) | (b & 0x7f);
- if ((b & 0x80) == 0) break;
- }
+ if ((code & 0xff) == 1) {
+ int pos = code >>> 8;
+ int whichArray = (doc >>> 16) & 0xff;
+ byte[] arr = tnums[whichArray];
+ int tnum = 0;
+ for (; ; ) {
+ int delta = 0;
+ for (; ; ) {
+ byte b = arr[pos++];
+ delta = (delta << 7) | (b & 0x7f);
+ if ((b & 0x80) == 0) break;
+ }
+ if (delta == 0) break;
+ tnum += delta - TNUM_OFFSET;
+ counts[tnum]++;
+ }
+ } else {
+ int tnum = 0;
+ int delta = 0;
+ for (; ; ) {
+ delta = (delta << 7) | (code & 0x7f);
+ if ((code & 0x80) == 0) {
if (delta == 0) break;
tnum += delta - TNUM_OFFSET;
- //System.out.println(" tnum=" + tnum);
counts[tnum]++;
+ delta = 0;
}
- } else {
- //System.out.println(" inlined");
- int tnum = 0;
- int delta = 0;
- for (;;) {
- delta = (delta << 7) | (code & 0x7f);
- if ((code & 0x80)==0) {
- if (delta==0) break;
- tnum += delta - TNUM_OFFSET;
- //System.out.println(" tnum=" + tnum);
- counts[tnum]++;
- delta = 0;
- }
- code >>>= 8;
- }
+ code >>>= 8;
}
}
}
- final CharsRefBuilder charsRef = new CharsRefBuilder();
-
- int off=offset;
- int lim=limit>=0 ? limit : Integer.MAX_VALUE;
-
- if (sort.equals(FacetParams.FACET_SORT_COUNT) || sort.equals(FacetParams.FACET_SORT_COUNT_LEGACY)) {
- int maxsize = limit>0 ? offset+limit : Integer.MAX_VALUE-1;
- maxsize = Math.min(maxsize, numTermsInField);
- LongPriorityQueue queue = new LongPriorityQueue(Math.min(maxsize,1000), maxsize, Long.MIN_VALUE);
-
- int min=mincount-1; // the smallest value in the top 'N' values
- //System.out.println("START=" + startTerm + " END=" + endTerm);
- for (int i=startTerm; i<endTerm; i++) {
- int c = doNegative ? maxTermCounts[i] - counts[i] : counts[i];
- if (c>min) {
- // NOTE: we use c>min rather than c>=min as an optimization because we are going in
- // index order, so we already know that the keys are ordered. This can be very
- // important if a lot of the counts are repeated (like zero counts would be).
-
- // smaller term numbers sort higher, so subtract the term number instead
- long pair = (((long)c)<<32) + (Integer.MAX_VALUE - i);
- boolean displaced = queue.insert(pair);
- if (displaced) min=(int)(queue.top() >>> 32);
- }
- }
-
- // now select the right page from the results
-
- // if we are deep paging, we don't have to order the highest "offset" counts.
- int collectCount = Math.max(0, queue.size() - off);
- assert collectCount <= lim;
-
- // the start and end indexes of our list "sorted" (starting with the highest value)
- int sortedIdxStart = queue.size() - (collectCount - 1);
- int sortedIdxEnd = queue.size() + 1;
- final long[] sorted = queue.sort(collectCount);
-
- final int[] indirect = counts; // reuse the counts array for the index into the tnums array
- assert indirect.length >= sortedIdxEnd;
-
- for (int i=sortedIdxStart; i<sortedIdxEnd; i++) {
- long pair = sorted[i];
- int c = (int)(pair >>> 32);
- int tnum = Integer.MAX_VALUE - (int)pair;
-
- indirect[i] = i; // store the index for indirect sorting
- sorted[i] = tnum; // reuse the "sorted" array to store the term numbers for indirect sorting
-
- // add a null label for now... we'll fill it in later.
- res.add(null, c);
- }
+ }
- // now sort the indexes by the term numbers
- PrimUtils.sort(sortedIdxStart, sortedIdxEnd, indirect, new PrimUtils.IntComparator() {
- @Override
- public int compare(int a, int b) {
- return (int)sorted[a] - (int)sorted[b];
- }
+ if (doNegative) {
+ for (int i=0; i<numTermsInField; i++) {
+ counts[i] = maxTermCounts[i] - counts[i];
+ }
+ }
- @Override
- public boolean lessThan(int a, int b) {
- return sorted[a] < sorted[b];
- }
+ if (processor.allBucketsSlot >= 0) {
+ int all = 0; // overflow potential
+ for (int i=0; i<numTermsInField; i++) {
+ all += counts[i];
+ }
+ counts[processor.allBucketsSlot] = all;
+ }
+ }
- @Override
- public boolean equals(int a, int b) {
- return sorted[a] == sorted[b];
- }
- });
- // convert the term numbers to term values and set
- // as the label
- //System.out.println("sortStart=" + sortedIdxStart + " end=" + sortedIdxEnd);
- for (int i=sortedIdxStart; i<sortedIdxEnd; i++) {
- int idx = indirect[i];
- int tnum = (int)sorted[idx];
- final String label = getReadableValue(getTermValue(te, tnum), ft, charsRef);
- //System.out.println(" label=" + label);
- res.setName(idx - sortedIdxStart, label);
- }
- } else {
- // add results in index order
- int i=startTerm;
- if (mincount<=0) {
- // if mincount<=0, then we won't discard any terms and we know exactly
- // where to start.
- i=startTerm+off;
- off=0;
- }
+ public void collectDocs(FacetFieldProcessorUIF processor) throws IOException {
+ if (processor.accs.length == 0 && processor.startTermIndex == 0 && processor.endTermIndex >= numTermsInField)
+ {
+ int[] arr = processor.countAcc.getCountArray();
+ getCountsInArray(processor, arr);
- for (; i<endTerm; i++) {
- int c = doNegative ? maxTermCounts[i] - counts[i] : counts[i];
- if (c<mincount || --off>=0) continue;
- if (--lim<0) break;
+ /*** debugging
+ int sz = processor.countAcc.getCountArray().length;
+ CountSlotAcc acc = processor.countAcc;
+ CountSlotAcc acc2 = new CountSlotAcc(processor.fcontext, sz);
+ processor.countAcc = acc2;
+ collectDocsGeneric(processor); // hopefully we can call this again?
- final String label = getReadableValue(getTermValue(te, i), ft, charsRef);
- res.add(label, c);
+ for (int i=0; i<sz; i++) {
+ if (acc.getCount(i) != acc2.getCount(i)) {
+ System.out.println("ERROR! ERROR! i=" + i + " counts=" + acc.getCount(i) + " " + acc2.getCount(i));
+ CountSlotAcc acc3 = new CountSlotAcc(processor.fcontext, sz); // put breakpoint here and re-execute
+ processor.countAcc = acc3;
+ int[] arr3 = processor.countAcc.getCountArray();
+ getCountsInArray(processor, arr3);
}
}
- }
-
+ ***/
- if (missing) {
- // TODO: a faster solution for this?
- res.add(null, SimpleFacets.getFieldMissingCount(searcher, baseDocs, field));
+ return;
}
- //System.out.println(" res=" + res);
-
- return res;
+ collectDocsGeneric(processor);
}
-
// called from FieldFacetProcessor
// TODO: do a callback version that can be specialized!
- public void collectDocs(FacetFieldProcessorUIF processor) throws IOException {
+ public void collectDocsGeneric(FacetFieldProcessorUIF processor) throws IOException {
use.incrementAndGet();
- DocSet docs = processor.fcontext.base;
int startTermIndex = processor.startTermIndex;
int endTermIndex = processor.endTermIndex;
int nTerms = processor.nTerms;
+ DocSet docs = processor.fcontext.base;
int uniqueTerms = 0;
for (TopTerm tt : bigTerms.values()) {
if (tt.termNum >= startTermIndex && tt.termNum < endTermIndex) {
// handle the biggest terms
- try ( DocSet intersection = searcher.getDocSet(new TermQuery(new Term(field, tt.term)), docs); )
+ try ( DocSet intersection = searcher.getDocSet(tt.termQuery, docs); )
{
int collected = processor.collect(intersection, tt.termNum - startTermIndex);
processor.countAcc.incrementCount(tt.termNum - startTermIndex, collected);
+ if (processor.allBucketsSlot >= 0) {
+ processor.collect(intersection, processor.allBucketsSlot);
+ processor.countAcc.incrementCount(processor.allBucketsSlot, collected);
+ }
if (collected > 0) {
uniqueTerms++;
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java?rev=1669713&r1=1669712&r2=1669713&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java Sat Mar 28 00:10:19 2015
@@ -27,6 +27,8 @@ import java.util.Random;
import com.tdunning.math.stats.AVLTreeDigest;
import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.packed.GrowableWriter;
+import org.apache.lucene.util.packed.PackedInts;
import org.apache.solr.JSONTestUtil;
import org.apache.solr.SolrTestCaseHS;
import org.apache.solr.common.SolrInputDocument;
@@ -619,6 +621,14 @@ public class TestJsonFacets extends Solr
" }"
);
+ // test allBucket multi-valued
+ client.testJQ(params(p, "q", "*:*"
+ , "json.facet", "{x:{terms:{field:'${multi_ss}',allBuckets:true}}}"
+ )
+ , "facets=={ count:6, " +
+ "x:{ buckets:[{val:a, count:3}, {val:b, count:3}] , allBuckets:{count:6} } }"
+ );
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// test converting legacy facets
@@ -697,8 +707,8 @@ public class TestJsonFacets extends Solr
doStats( client, params() );
}
- /***
- public void testPercentiles() {
+
+ public void XtestPercentiles() {
AVLTreeDigest catA = new AVLTreeDigest(100);
catA.add(4);
catA.add(2);
@@ -728,11 +738,10 @@ public class TestJsonFacets extends Solr
}
return sb.toString();
}
- ***/
- /*** test code to ensure TDigest is working as we expect.
- @Test
- public void testTDigest() throws Exception {
+ /*** test code to ensure TDigest is working as we expect. */
+
+ public void XtestTDigest() throws Exception {
AVLTreeDigest t1 = new AVLTreeDigest(100);
t1.add(10, 1);
t1.add(90, 1);
@@ -779,5 +788,4 @@ public class TestJsonFacets extends Solr
System.out.println(top.quantile(0.5));
System.out.println(top.quantile(0.9));
}
- ******/
}