diff --git a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java index 1fc158302a2..aab768406bb 100644 --- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java @@ -579,11 +579,11 @@ public class SimpleFacets { List> buckets = (List>)res.get("buckets"); for(NamedList b : buckets) { - counts.add(b.get("val").toString(), (Integer)b.get("count")); + counts.add(b.get("val").toString(), ((Number)b.get("count")).intValue()); } if(missing) { NamedList missingCounts = (NamedList) res.get("missing"); - counts.add(null, (Integer)missingCounts.get("count")); + counts.add(null, ((Number)missingCounts.get("count")).intValue()); } } break; diff --git a/solr/core/src/java/org/apache/solr/search/facet/AggValueSource.java b/solr/core/src/java/org/apache/solr/search/facet/AggValueSource.java index 645746768db..1678c6fa097 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/AggValueSource.java +++ b/solr/core/src/java/org/apache/solr/search/facet/AggValueSource.java @@ -50,7 +50,7 @@ public abstract class AggValueSource extends ValueSource { } // TODO: make abstract - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { throw new UnsupportedOperationException("NOT IMPLEMENTED " + name + " " + this); } diff --git a/solr/core/src/java/org/apache/solr/search/facet/AvgAgg.java b/solr/core/src/java/org/apache/solr/search/facet/AvgAgg.java index 716bb805e41..3b6cee03d56 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/AvgAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/AvgAgg.java @@ -37,7 +37,7 @@ public class AvgAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/CountAgg.java b/solr/core/src/java/org/apache/solr/search/facet/CountAgg.java index fc16917b2fa..491622d2afe 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/CountAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/CountAgg.java @@ -24,7 +24,7 @@ public class CountAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { return new CountSlotArrAcc(fcontext, numSlots); } diff --git a/solr/core/src/java/org/apache/solr/search/facet/CountValsAgg.java b/solr/core/src/java/org/apache/solr/search/facet/CountValsAgg.java index eebe9fc9909..81fa983b926 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/CountValsAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/CountValsAgg.java @@ -37,7 +37,7 @@ public class CountValsAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { String field = ((FieldNameValueSource)vs).getFieldName(); diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessor.java b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessor.java index 5caea4eca7b..fe418f1b385 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessor.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessor.java @@ -108,7 +108,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { /** This is used to create accs for second phase (or to create accs for all aggs) */ @Override - protected void createAccs(int docCount, int slotCount) throws IOException { + protected void createAccs(long docCount, int slotCount) throws IOException { if (accMap == null) { accMap = new LinkedHashMap<>(); } @@ -295,7 +295,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { IntFunction bucketValFromSlotNumFunc, Function fieldQueryValFunc) throws IOException { assert this.sortAcc != null; - int numBuckets = 0; + long numBuckets = 0; final int off = fcontext.isShard() ? 0 : (int) freq.offset; @@ -347,7 +347,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { // screen out buckets not matching mincount if (effectiveMincount > 0) { - int count = countAcc.getCount(slotNum); + long count = countAcc.getCount(slotNum); if (count < effectiveMincount) { if (count > 0) numBuckets++; // Still increment numBuckets as long as we have some count. This is for consistency between distrib and non-distrib mode. @@ -387,7 +387,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { } FacetDebugInfo fdebug = fcontext.getDebugInfo(); - if (fdebug != null) fdebug.putInfoItem("numBuckets", (long) numBuckets); + if (fdebug != null) fdebug.putInfoItem("numBuckets", numBuckets); if (freq.allBuckets) { SimpleOrderedMap allBuckets = new SimpleOrderedMap<>(); @@ -507,7 +507,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { /** Helper method used solely when looping over buckets to be returned in findTopSlots */ private void fillBucketFromSlot(SimpleOrderedMap target, Slot slot, SlotAcc resortAcc) throws IOException { - final int count = countAcc.getCount(slot.slot); + final long count = countAcc.getCount(slot.slot); target.add("count", count); if (count <= 0 && !freq.processEmpty) return; @@ -645,14 +645,14 @@ abstract class FacetFieldProcessor extends FacetProcessor { } @Override - protected void processStats(SimpleOrderedMap bucket, Query bucketQ, DocSet docs, int docCount) throws IOException { + protected void processStats(SimpleOrderedMap bucket, Query bucketQ, DocSet docs, long docCount) throws IOException { if (docCount == 0 && !freq.processEmpty || freq.getFacetStats().size() == 0) { bucket.add("count", docCount); return; } createAccs(docCount, 1); assert null != bucketQ; - int collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); }); + long collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); }); // countAcc.incrementCount(0, collected); // should we set the counton the acc instead of just passing it? @@ -661,7 +661,7 @@ abstract class FacetFieldProcessor extends FacetProcessor { } // overrides but with different signature! - private void addStats(SimpleOrderedMap target, int count, int slotNum) throws IOException { + private void addStats(SimpleOrderedMap target, long count, int slotNum) throws IOException { target.add("count", count); if (count > 0 || freq.processEmpty) { for (SlotAcc acc : accs) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByHashDV.java b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByHashDV.java index 42d23ef9aa7..966da872a6d 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByHashDV.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByHashDV.java @@ -57,8 +57,8 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor { static final float LOAD_FACTOR = 0.7f; long[] vals; - int[] counts; // maintain the counts here since we need them to tell if there was actually a value anyway - int[] oldToNewMapping; + long[] counts; // maintain the counts here since we need them to tell if there was actually a value anyway + long[] oldToNewMapping; int cardinality; int threshold; @@ -66,7 +66,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor { /** sz must be a power of two */ LongCounts(int sz) { vals = new long[sz]; - counts = new int[sz]; + counts = new long[sz]; threshold = (int) (sz * LOAD_FACTOR); } @@ -95,7 +95,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor { int h = hash(val); for (int slot = h & (vals.length-1); ;slot = (slot + ((h>>7)|1)) & (vals.length-1)) { - int count = counts[slot]; + long count = counts[slot]; if (count == 0) { counts[slot] = 1; vals[slot] = val; @@ -111,14 +111,14 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor { protected void rehash() { long[] oldVals = vals; - int[] oldCounts = counts; // after retrieving the count, this array is reused as a mapping to new array + long[] oldCounts = counts; // after retrieving the count, this array is reused as a mapping to new array int newCapacity = vals.length << 1; vals = new long[newCapacity]; - counts = new int[newCapacity]; + counts = new long[newCapacity]; threshold = (int) (newCapacity * LOAD_FACTOR); for (int i=0; i { return appliedFilters; } - protected void processStats(SimpleOrderedMap bucket, Query bucketQ, DocSet docs, int docCount) throws IOException { + protected void processStats(SimpleOrderedMap bucket, Query bucketQ, DocSet docs, long docCount) throws IOException { if (docCount == 0 && !freq.processEmpty || freq.getFacetStats().size() == 0) { bucket.add("count", docCount); return; } createAccs(docCount, 1); - int collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); }); + long collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); }); countAcc.incrementCount(0, collected); assert collected == docCount; addStats(bucket, 0); } - protected void createAccs(int docCount, int slotCount) throws IOException { + protected void createAccs(long docCount, int slotCount) throws IOException { accMap = new LinkedHashMap<>(); // allow a custom count acc to be used @@ -332,8 +332,8 @@ public abstract class FacetProcessor { } } - int collect(DocSet docs, int slot, IntFunction slotContext) throws IOException { - int count = 0; + long collect(DocSet docs, int slot, IntFunction slotContext) throws IOException { + long count = 0; SolrIndexSearcher searcher = fcontext.searcher; if (0 == docs.size()) { @@ -392,7 +392,7 @@ public abstract class FacetProcessor { } void addStats(SimpleOrderedMap target, int slotNum) throws IOException { - int count = countAcc.getCount(slotNum); + long count = countAcc.getCount(slotNum); target.add("count", count); if (count > 0 || freq.processEmpty) { for (SlotAcc acc : accs) { @@ -405,7 +405,7 @@ public abstract class FacetProcessor { boolean needDocSet = (skip==false && freq.getFacetStats().size() > 0) || freq.getSubFacets().size() > 0; - int count; + long count; if (result != null) { count = result.size(); diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetRange.java b/solr/core/src/java/org/apache/solr/search/facet/FacetRange.java index a74f35dea89..a93bc079e70 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetRange.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetRange.java @@ -578,7 +578,7 @@ class FacetRangeProcessor extends FacetProcessor { DocSet intersection = fcontext.searcher.getDocSet(rangeQ, fcontext.base); filters[slot] = rangeQ; intersections[slot] = intersection; // save for later // TODO: only save if number of slots is small enough? - int num = collect(intersection, slot, slotNum -> { return new SlotContext(rangeQ); }); + long num = collect(intersection, slot, slotNum -> { return new SlotContext(rangeQ); }); countAcc.incrementCount(slot, num); // TODO: roll this into collect() } diff --git a/solr/core/src/java/org/apache/solr/search/facet/HLLAgg.java b/solr/core/src/java/org/apache/solr/search/facet/HLLAgg.java index 32c1b1425e0..ff7b2a2a78f 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/HLLAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/HLLAgg.java @@ -50,7 +50,7 @@ public class HLLAgg extends StrAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { SchemaField sf = fcontext.qcontext.searcher().getSchema().getField(getArg()); if (sf.multiValued() || sf.getType().multiValuedFieldCache()) { if (sf.getType().isPointField()) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java index f369226e616..d036ee1c362 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java @@ -46,7 +46,7 @@ public class MinMaxAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); SchemaField sf = null; diff --git a/solr/core/src/java/org/apache/solr/search/facet/MissingAgg.java b/solr/core/src/java/org/apache/solr/search/facet/MissingAgg.java index 2bf25134369..4ff980f0ea9 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/MissingAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/MissingAgg.java @@ -37,7 +37,7 @@ public class MissingAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/PercentileAgg.java b/solr/core/src/java/org/apache/solr/search/facet/PercentileAgg.java index 24e3273cb7a..956b179b2dd 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/PercentileAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/PercentileAgg.java @@ -49,7 +49,7 @@ public class PercentileAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/RelatednessAgg.java b/solr/core/src/java/org/apache/solr/search/facet/RelatednessAgg.java index 662496f0650..81d0f3b9e82 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/RelatednessAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/RelatednessAgg.java @@ -122,7 +122,7 @@ public class RelatednessAgg extends AggValueSource { } - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { // TODO: Ideally this is where we should check fgQ/bgQ for 'null' and apply defaults... // // we want to walk up the fcontext and inherit the queries from any ancestor SKGAgg diff --git a/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java index 2a9234839dd..99387bebe36 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/SlotAcc.java @@ -578,17 +578,17 @@ abstract class CountSlotAcc extends SlotAcc { super(fcontext); } - public abstract void incrementCount(int slot, int count); + public abstract void incrementCount(int slot, long count); - public abstract int getCount(int slot); + public abstract long getCount(int slot); } class CountSlotArrAcc extends CountSlotAcc { - int[] result; + long[] result; public CountSlotArrAcc(FacetContext fcontext, int numSlots) { super(fcontext); - result = new int[numSlots]; + result = new long[numSlots]; } @Override @@ -600,7 +600,7 @@ class CountSlotArrAcc extends CountSlotAcc { @Override public int compare(int slotA, int slotB) { - return Integer.compare(result[slotA], result[slotB]); + return Long.compare(result[slotA], result[slotB]); } @Override @@ -608,16 +608,18 @@ class CountSlotArrAcc extends CountSlotAcc { return result[slotNum]; } - public void incrementCount(int slot, int count) { + @Override + public void incrementCount(int slot, long count) { result[slot] += count; } - public int getCount(int slot) { + @Override + public long getCount(int slot) { return result[slot]; } // internal and expert - int[] getCountArray() { + long[] getCountArray() { return result; } @@ -642,6 +644,7 @@ class SortSlotAcc extends SlotAcc { // no-op } + @Override public int compare(int slotA, int slotB) { return slotA - slotB; } diff --git a/solr/core/src/java/org/apache/solr/search/facet/StddevAgg.java b/solr/core/src/java/org/apache/solr/search/facet/StddevAgg.java index d7237d39108..d0fb90be588 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/StddevAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/StddevAgg.java @@ -32,7 +32,7 @@ public class StddevAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/SumAgg.java b/solr/core/src/java/org/apache/solr/search/facet/SumAgg.java index 7cd4b9d441d..5fe5aed70f6 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/SumAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/SumAgg.java @@ -34,7 +34,7 @@ public class SumAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/SumsqAgg.java b/solr/core/src/java/org/apache/solr/search/facet/SumsqAgg.java index 133e39c4b75..4bb9e67d7ca 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/SumsqAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/SumsqAgg.java @@ -33,7 +33,7 @@ public class SumsqAgg extends SimpleAggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { ValueSource vs = getArg(); if (vs instanceof FieldNameValueSource) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java b/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java index a29c41928f5..0161d079330 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java +++ b/solr/core/src/java/org/apache/solr/search/facet/UnInvertedField.java @@ -390,7 +390,7 @@ public class UnInvertedField extends DocTermOrds { if (doNegative) { for (int i=0; i STR_VALS = Arrays.asList("x0", "x1", "x2"); - // NOTE: in our test conversions EUR uses an asynetric echange rate + // NOTE: in our test conversions EUR uses an asynetric exchange rate // these are the equivalent values relative to: USD EUR GBP private static final List VALUES = Arrays.asList("10.00,USD", // 10.00,USD 25.00,EUR 5.00,GBP "15.00,EUR", // 7.50,USD 15.00,EUR 7.50,GBP @@ -176,9 +176,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { final NamedList foo = ((NamedList>)rsp.getResponse().get("facets")).get("foo"); - assertEqualsHACK("before", 3L, ((NamedList)foo.get("before")).get("count")); - assertEqualsHACK("after", 3L, ((NamedList)foo.get("after")).get("count")); - assertEqualsHACK("between", 9L, ((NamedList)foo.get("between")).get("count")); + assertEquals("before", 3L, ((NamedList)foo.get("before")).get("count")); + assertEquals("after", 3L, ((NamedList)foo.get("after")).get("count")); + assertEquals("between", 9L, ((NamedList)foo.get("between")).get("count")); final List buckets = (List) foo.get("buckets"); @@ -187,14 +187,14 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { for (int i = 0; i < 3; i++) { NamedList bucket = buckets.get(i); assertEquals((4 + (3 * i)) + ".00,USD", bucket.get("val")); - assertEqualsHACK("bucket #" + i, 3L, bucket.get("count")); + assertEquals("bucket #" + i, 3L, bucket.get("count")); } } else { assertEquals(7, buckets.size()); for (int i = 0; i < 7; i++) { NamedList bucket = buckets.get(i); assertEquals((4 + i) + ".00,USD", bucket.get("val")); - assertEqualsHACK("bucket #" + i, (i == 0 || i == 3 || i == 6) ? 3L : 0L, bucket.get("count")); + assertEquals("bucket #" + i, (i == 0 || i == 3 || i == 6) ? 3L : 0L, bucket.get("count")); } } } catch (AssertionError|RuntimeException ae) { @@ -268,9 +268,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { final NamedList foo = ((NamedList>)rsp.getResponse().get("facets")).get("foo"); - assertEqualsHACK("before", 6L, ((NamedList)foo.get("before")).get("count")); - assertEqualsHACK("after", 3L, ((NamedList)foo.get("after")).get("count")); - assertEqualsHACK("between", 6L, ((NamedList)foo.get("between")).get("count")); + assertEquals("before", 6L, ((NamedList)foo.get("before")).get("count")); + assertEquals("after", 3L, ((NamedList)foo.get("after")).get("count")); + assertEquals("between", 6L, ((NamedList)foo.get("between")).get("count")); final List buckets = (List) foo.get("buckets"); @@ -279,14 +279,14 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { for (int i = 0; i < 2; i++) { NamedList bucket = buckets.get(i); assertEquals((12 + (i * 2)) + ".00,EUR", bucket.get("val")); - assertEqualsHACK("bucket #" + i, 3L, bucket.get("count")); + assertEquals("bucket #" + i, 3L, bucket.get("count")); } } else { assertEquals(7, buckets.size()); for (int i = 0; i < 7; i++) { NamedList bucket = buckets.get(i); assertEquals((8 + (i * 2)) + ".00,EUR", bucket.get("val")); - assertEqualsHACK("bucket #" + i, (i == 2 || i == 3) ? 3L : 0L, bucket.get("count")); + assertEquals("bucket #" + i, (i == 2 || i == 3) ? 3L : 0L, bucket.get("count")); } } } catch (AssertionError|RuntimeException ae) { @@ -365,9 +365,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { // sanity check our high level expectations... assertEquals("bar num buckets", 2, bar_buckets.size()); - assertEqualsHACK("before count", 0L, before.get("count")); - assertEqualsHACK("between count", 8L, between.get("count")); - assertEqualsHACK("after count", 2L, after.get("count")); + assertEquals("before count", 0L, before.get("count")); + assertEquals("between count", 8L, between.get("count")); + assertEquals("after count", 2L, after.get("count")); // drill into the various buckets... @@ -378,15 +378,15 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { for (int i = 0; i < 2; i++) { final NamedList bucket = bar_buckets.get(i); assertEquals((i * 10) + ".00,EUR", bucket.get("val")); - assertEqualsHACK("bucket #" + i, 4L, bucket.get("count")); + assertEquals("bucket #" + i, 4L, bucket.get("count")); final List> foo_buckets = ((NamedList>>)bucket.get("foo")).get("buckets"); assertEquals("bucket #" + i + " foo num buckets", 2, foo_buckets.size()); assertEquals("bucket #" + i + " foo top term", (0==i ? "x2" : "x0"), foo_buckets.get(0).get("val")); - assertEqualsHACK("bucket #" + i + " foo top count", 2, foo_buckets.get(0).get("count")); + assertEquals("bucket #" + i + " foo top count", 2L, foo_buckets.get(0).get("count")); // NOTE: we can't make any assertions about the 2nd val.. // our limit + randomized sharding could result in either remaining term being picked. - // but for eiter term, the count should be exactly the same... - assertEqualsHACK("bucket #" + i + " foo 2nd count", 1, foo_buckets.get(1).get("count")); + // but for either term, the count should be exactly the same... + assertEquals("bucket #" + i + " foo 2nd count", 1L, foo_buckets.get(1).get("count")); } { // between... @@ -394,9 +394,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { assertEquals("between num buckets", 2, buckets.size()); // the counts should both be 3, and the term order should break the tie... assertEquals("between bucket top", "x0", buckets.get(0).get("val")); - assertEqualsHACK("between bucket top count", 3L, buckets.get(0).get("count")); + assertEquals("between bucket top count", 3L, buckets.get(0).get("count")); assertEquals("between bucket 2nd", "x2", buckets.get(1).get("val")); - assertEqualsHACK("between bucket 2nd count", 3L, buckets.get(1).get("count")); + assertEquals("between bucket 2nd count", 3L, buckets.get(1).get("count")); } { // after... @@ -404,9 +404,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { assertEquals("after num buckets", 2, buckets.size()); // the counts should both be 1, and the term order should break the tie... assertEquals("after bucket top", "x1", buckets.get(0).get("val")); - assertEqualsHACK("after bucket top count", 1L, buckets.get(0).get("count")); + assertEquals("after bucket top count", 1L, buckets.get(0).get("count")); assertEquals("after bucket 2nd", "x2", buckets.get(1).get("val")); - assertEqualsHACK("after bucket 2nd count", 1L, buckets.get(1).get("count")); + assertEquals("after bucket 2nd count", 1L, buckets.get(1).get("count")); } } catch (AssertionError|RuntimeException ae) { @@ -449,15 +449,15 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { final List> foo_buckets = (List>) foo.get("buckets"); assertEquals(1, foo_buckets.size()); assertEquals("x2", foo_buckets.get(0).get("val")); - assertEqualsHACK("foo bucket count", 5L, foo_buckets.get(0).get("count")); + assertEquals("foo bucket count", 5L, foo_buckets.get(0).get("count")); final NamedList bar = (NamedList)foo_buckets.get(0).get("bar"); // these are the 'x2' specific counts, based on our fq... - assertEqualsHACK("before", 2L, ((NamedList)bar.get("before")).get("count")); - assertEqualsHACK("after", 1L, ((NamedList)bar.get("after")).get("count")); - assertEqualsHACK("between", 2L, ((NamedList)bar.get("between")).get("count")); + assertEquals("before", 2L, ((NamedList)bar.get("before")).get("count")); + assertEquals("after", 1L, ((NamedList)bar.get("after")).get("count")); + assertEquals("between", 2L, ((NamedList)bar.get("between")).get("count")); final List buckets = (List) bar.get("buckets"); assertEquals(7, buckets.size()); @@ -465,7 +465,7 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { NamedList bucket = buckets.get(i); assertEquals((8 + (i * 2)) + ".00,EUR", bucket.get("val")); // 12,EUR & 15,EUR are the 2 values that align with x2 docs - assertEqualsHACK("bucket #" + i, (i == 2 || i == 3) ? 1L : 0L, bucket.get("count")); + assertEquals("bucket #" + i, (i == 2 || i == 3) ? 1L : 0L, bucket.get("count")); } } catch (AssertionError|RuntimeException ae) { throw new AssertionError(solrQuery.toString() + " -> " + rsp.toString() + " ===> " + ae.getMessage(), ae); @@ -473,14 +473,4 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase { } } - /** - * HACK to work around SOLR-11775. - * Asserts that the 'actual' argument is a (non-null) Number, then compares it's 'longValue' to the 'expected' argument - */ - private static void assertEqualsHACK(String msg, long expected, Object actual) { - assertNotNull(msg, actual); - assertTrue(msg + " ... NOT A NUMBER: " + actual.getClass(), Number.class.isInstance(actual)); - assertEquals(msg, expected, ((Number)actual).longValue()); - } - } diff --git a/solr/core/src/test/org/apache/solr/search/facet/DebugAgg.java b/solr/core/src/test/org/apache/solr/search/facet/DebugAgg.java index a8e0c586a02..ee7f0e882f1 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/DebugAgg.java +++ b/solr/core/src/test/org/apache/solr/search/facet/DebugAgg.java @@ -68,7 +68,7 @@ class DebugAgg extends AggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException { return new Acc(fcontext, numDocs, numSlots, inner.createSlotAcc(fcontext, numDocs, numSlots)); } @@ -91,10 +91,10 @@ class DebugAgg extends AggValueSource { public static Acc last; public SlotAcc sub; - public int numDocs; + public long numDocs; public int numSlots; - public Acc(FacetContext fcontext, int numDocs, int numSlots, SlotAcc sub) { + public Acc(FacetContext fcontext, long numDocs, int numSlots, SlotAcc sub) { super(fcontext); this.last = this; this.numDocs = numDocs; @@ -173,7 +173,7 @@ class DebugAgg extends AggValueSource { } @Override - public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) { + public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) { return new NumShardsAcc(fcontext, numDocs, numSlots); } @@ -188,7 +188,7 @@ class DebugAgg extends AggValueSource { } public static class NumShardsAcc extends SlotAcc { - public NumShardsAcc(FacetContext fcontext, int numDocs, int numSlots) { + public NumShardsAcc(FacetContext fcontext, long numDocs, int numSlots) { super(fcontext); } diff --git a/solr/core/src/test/org/apache/solr/search/facet/DistributedFacetSimpleRefinementLongTailTest.java b/solr/core/src/test/org/apache/solr/search/facet/DistributedFacetSimpleRefinementLongTailTest.java index b6111656f80..a24da43066c 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/DistributedFacetSimpleRefinementLongTailTest.java +++ b/solr/core/src/test/org/apache/solr/search/facet/DistributedFacetSimpleRefinementLongTailTest.java @@ -147,7 +147,7 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute for (int j = 0; j < 5; j++) { NamedList bucket = shardFooBuckets[i].get(j); assertEquals(bucket.toString(), "aaa"+j, bucket.get("val")); - assertEquals(bucket.toString(), 100, bucket.get("count")); + assertEquals(bucket.toString(), 100L, bucket.get("count")); } } // top 6-10 same on shard0 & shard1 @@ -155,19 +155,19 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute for (int j = 5; j < 10; j++) { NamedList bucket = shardFooBuckets[i].get(j); assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("bbb")); - assertEquals(bucket.toString(), 50, bucket.get("count")); + assertEquals(bucket.toString(), 50L, bucket.get("count")); } } // 6-10 on shard2 assertEquals("junkA", shardFooBuckets[2].get(5).get("val")); - assertEquals(50, shardFooBuckets[2].get(5).get("count")); + assertEquals(50L, shardFooBuckets[2].get(5).get("count")); assertEquals("tail", shardFooBuckets[2].get(6).get("val")); - assertEquals(45, shardFooBuckets[2].get(6).get("count")); + assertEquals(45L, shardFooBuckets[2].get(6).get("count")); for (int j = 7; j < 10; j++) { NamedList bucket = shardFooBuckets[2].get(j); assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("ZZZ")); - assertEquals(bucket.toString(), 1, bucket.get("count")); + assertEquals(bucket.toString(), 1L, bucket.get("count")); } // check 'bar' sub buckets on "tail" from shard2 @@ -176,11 +176,11 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute for (int j = 0; j < 5; j++) { NamedList bucket = bar_buckets.get(j); assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("junkB")); - assertEquals(bucket.toString(), 8, bucket.get("count")); + assertEquals(bucket.toString(), 8L, bucket.get("count")); } NamedList bucket = bar_buckets.get(5); assertEquals("tailB", bucket.get("val")); - assertEquals(5, bucket.get("count")); + assertEquals(5L, bucket.get("count")); } } diff --git a/solr/core/src/test/org/apache/solr/search/facet/RangeFacetCloudTest.java b/solr/core/src/test/org/apache/solr/search/facet/RangeFacetCloudTest.java index 77663dfeead..f9419de4d92 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/RangeFacetCloudTest.java +++ b/solr/core/src/test/org/apache/solr/search/facet/RangeFacetCloudTest.java @@ -741,7 +741,7 @@ public class RangeFacetCloudTest extends SolrCloudTestCase { toMerge.add(TERM_MODEL[i]); } - assertEqualsHACK("count", expectedCount, bucket.get("count")); + assertEquals("count", expectedCount, bucket.get("count")); // merge the maps of our range values by summing the (int) values on key collisions final Map expectedTermCounts = toMerge.stream() @@ -766,7 +766,7 @@ public class RangeFacetCloudTest extends SolrCloudTestCase { assertNotNull("subfacet bucket with null term: " + subBucket, term); final Long expectedTermCount = expectedTermCounts.get(term.toString()); assertNotNull("unexpected subfacet bucket: " + subBucket, expectedTermCount); - assertEqualsHACK("subfacet count for term: " + term, expectedTermCount, subBucket.get("count")); + assertEquals("subfacet count for term: " + term, expectedTermCount, subBucket.get("count")); } } @@ -910,14 +910,4 @@ public class RangeFacetCloudTest extends SolrCloudTestCase { return ", other:" + val; } - /** - * HACK to work around SOLR-11775. - * Asserts that the 'actual' argument is a (non-null) Number, then compares it's 'longValue' to the 'expected' argument - */ - private static void assertEqualsHACK(String msg, long expected, Object actual) { - assertNotNull(msg, actual); - assertTrue(msg + " ... NOT A NUMBER: " + actual.getClass(), Number.class.isInstance(actual)); - assertEquals(msg, expected, ((Number)actual).longValue()); - } - } diff --git a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java index 573a8004385..aea04b3bd25 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java +++ b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java @@ -3283,6 +3283,64 @@ public class TestJsonFacets extends SolrTestCaseHS { } + @Test + public void testFacetValueTypes() throws Exception { + doFacetValueTypeValidation(Client.localClient()); + } + + @Test + public void testFacetValueTypesDistrib() throws Exception { + initServers(); + Client client = servers.getClient(random().nextInt()); + client.queryDefaults().set( "shards", servers.getShards(), "debugQuery", Boolean.toString(random().nextBoolean()) ); + doFacetValueTypeValidation(client); + } + + private void doFacetValueTypeValidation(Client client) throws Exception { + indexSimple(client); + + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{cat_s:{type:terms,field:cat_s,mincount:0,missing:true,allBuckets:true,numBuckets:true,limit:1}}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/lst[@name='cat_s']/long[@name='numBuckets'][.=2]", // total no of buckets + "*[count(/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst)=1]", // no of entries + "/response/lst[@name='facets']/lst[@name='cat_s']/lst[@name='allBuckets']/long[@name='count'][.=5]", // allBuckets + "/response/lst[@name='facets']/lst[@name='cat_s']/lst[@name='missing']/long[@name='count'][.=1]", // missing + "/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst[1]/str[@name='val'][.='B']", // facet value + "/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst[1]/long[@name='count'][.='3']" // facet count + ); + + // aggregations types for string + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{unique:'unique(cat_s)',hll:'hll(cat_s)',vals:'countvals(cat_s)',missing:'missing(cat_s)'}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/long[@name='unique'][.=2]", // unique + "/response/lst[@name='facets']/long[@name='hll'][.=2]", // hll + "/response/lst[@name='facets']/long[@name='vals'][.=5]", // values + "/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing + ); + + // aggregations types for number + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{unique:'unique(num_i)',hll:'hll(num_i)',vals:'countvals(num_i)',missing:'missing(num_i)'}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/long[@name='unique'][.=4]", // unique + "/response/lst[@name='facets']/long[@name='hll'][.=4]", // hll + "/response/lst[@name='facets']/long[@name='vals'][.=5]", // values + "/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing + ); + + // aggregations types for multi-valued number + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{unique:'unique(num_is)',hll:'hll(num_is)',vals:'countvals(num_is)',missing:'missing(num_is)'}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/long[@name='unique'][.=7]", // unique + "/response/lst[@name='facets']/long[@name='hll'][.=7]", // hll + "/response/lst[@name='facets']/long[@name='vals'][.=9]", // values + "/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing + ); + } + public void XtestPercentiles() { AVLTreeDigest catA = new AVLTreeDigest(100); catA.add(4); diff --git a/solr/core/src/test/org/apache/solr/search/facet/TestJsonRangeFacets.java b/solr/core/src/test/org/apache/solr/search/facet/TestJsonRangeFacets.java index 0d21636f64a..6c8364cc7d6 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/TestJsonRangeFacets.java +++ b/solr/core/src/test/org/apache/solr/search/facet/TestJsonRangeFacets.java @@ -394,4 +394,42 @@ public class TestJsonRangeFacets extends SolrTestCaseHS { "facets=={count:6, price:{buckets:[{val:\"[*,*)\",count:5}]}}"); } + @Test + public void testFacetValueTypes() throws Exception { + doFacetValueTypeValidation(Client.localClient()); + } + + @Test + public void testFacetValueTypeDistrib() throws Exception { + initServers(); + Client client = servers.getClient(random().nextInt()); + client.queryDefaults().set( "shards", servers.getShards(), "debugQuery", Boolean.toString(random().nextBoolean()) ); + doFacetValueTypeValidation(client); + } + + private void doFacetValueTypeValidation(Client client) throws Exception { + indexSimple(client); + + // range faceting with start, end, and gap + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{num:{type: range, field:num_i,start:0,gap:2,end:10,mincount:1,other:all}}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/int[@name='val'][.=2]", // value + "/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/long[@name='count'][.=2]", // count + "*[count(/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst)=2]", // no of entries + "/response/lst[@name='facets']/lst[@name='num']/lst[@name='before']/long[@name='count'][.=2]", // before + "/response/lst[@name='facets']/lst[@name='num']/lst[@name='after']/long[@name='count'][.=0]", // after + "/response/lst[@name='facets']/lst[@name='num']/lst[@name='between']/long[@name='count'][.=3]" // between + ); + + // range faceting with ranges specified + client.testXQ(params("q", "*:*", "rows", "0", + "json.facet", "{num:{type: range, field:num_i,ranges:[{from:0, to:4},{from:-4,to:2}],mincount:1}}"), + "/response/lst[@name='facets']/long[@name='count'][.=6]", // count + "/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/str[@name='val'][.='[0,4)']", // value + "/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/long[@name='count'][.=2]", // count + "*[count(/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst)=1]" // no of entries + ); + } + } diff --git a/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc b/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc index bfb6472bed2..8262de9e522 100644 --- a/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc +++ b/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc @@ -103,6 +103,8 @@ _(raw; not yet edited)_ * SOLR-12720: To change the auto add replica wait period modify the `waitFor` attribute of the `.auto_add_replicas` trigger. (marcussorealheis, shalin) + +* SOLR-11775: Return long value for facet count in Json Facet module irrespective of number of shards (hossman, Munendra S N) === Upgrade Prerequisites in Solr 9 diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java index 0e7edfe4371..3da476acd9d 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java @@ -16,6 +16,7 @@ */ package org.apache.solr; +import javax.xml.xpath.XPathExpressionException; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -45,6 +46,7 @@ import org.apache.solr.client.solrj.impl.NoOpResponseParser; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; @@ -54,6 +56,7 @@ import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; import org.apache.solr.servlet.DirectSolrConnection; +import org.apache.solr.util.TestHarness; import org.noggit.JSONUtil; import org.noggit.ObjectBuilder; import org.slf4j.Logger; @@ -145,6 +148,31 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 { matchJSON(resp, tests); } + /** + * Pass "null" for the client to query to the local server. + * Fetches response in xml format and matches with the given set of xpaths + */ + public static void assertQ(SolrClient client, SolrParams args, String... tests) throws Exception { + String resp; + resp = getQueryResponse(client, "xml", args); + try { + String results = TestHarness.validateXPath(resp, tests); + if (null != results) { + String msg = "REQUEST FAILED: xpath=" + results + + "\n\txml response was: " + resp + + "\n\tparams were:" + args.toQueryString(); + + log.error(msg); + throw new RuntimeException(msg); + } + } catch (XPathExpressionException e1) { + throw new RuntimeException("XPath is invalid", e1); + } catch (Exception e2) { + SolrException.log(log,"REQUEST FAILED for params: " + args.toQueryString(), e2); + throw new RuntimeException("Exception during query", e2); + } + } + public static void matchJSON(String response, String... tests) throws Exception { boolean failed = false; @@ -256,6 +284,10 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 { public void assertJQ(SolrClient client, SolrParams args, String... tests) throws Exception { SolrTestCaseHS.assertJQ(client, args, tests); } + + public void assertQ(SolrClient client, SolrParams args, String... tests) throws Exception { + SolrTestCaseHS.assertQ(client, args, tests); + } } public static Client localClient = new Client(null, 1); @@ -299,6 +331,19 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 { tester.assertJQ(client, args, tests); } + /** + * tests are validated against xml response + */ + public void testXQ(SolrParams args, String... tests) throws Exception { + if (queryDefaults != null) { + ModifiableSolrParams newParams = params(queryDefaults); + newParams.add(args); + args = newParams; + } + SolrClient client = provider==null ? null : provider.client(null, args); + tester.assertQ(client, args, tests); + } + public Long add(SolrInputDocument sdoc, ModifiableSolrParams params) throws Exception { SolrClient client = provider==null ? null : provider.client(sdoc, params); return SolrTestCaseHS.add(client, sdoc, params);