From 91a6fd5c3306c3c42ad0627fa656e7859220ea09 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Mon, 2 May 2022 03:37:13 -0400 Subject: [PATCH] SOLR-16165: Rare deadlock in SlotAcc initialization (#819) --- .../apache/solr/search/facet/Constants.java | 94 +++++++++++++++++++ .../facet/FacetFieldProcessorByArray.java | 8 +- .../org/apache/solr/search/facet/SlotAcc.java | 57 ----------- 3 files changed, 99 insertions(+), 60 deletions(-) create mode 100644 solr/core/src/java/org/apache/solr/search/facet/Constants.java diff --git a/solr/core/src/java/org/apache/solr/search/facet/Constants.java b/solr/core/src/java/org/apache/solr/search/facet/Constants.java new file mode 100644 index 000000000000..39c983157818 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/search/facet/Constants.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.search.facet; + +import java.io.IOException; +import java.util.function.IntFunction; +import org.apache.lucene.index.LeafReaderContext; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.search.DocSet; + +/** constants used in facets package */ +public class Constants { + public static final SlotAcc.CountSlotAcc DEV_NULL_SLOT_ACC = new DevNullCountSlotAcc(); + + private Constants() {} + + /** + * This CountSlotAcc exists as a /dev/null sink for callers of collect(...) and other "write"-type + * methods. It should be used in contexts where "read"-type access methods will never be called. + */ + private static class DevNullCountSlotAcc extends SlotAcc.CountSlotAcc { + + public DevNullCountSlotAcc() { + super(null); + } + + @Override + public void resize(Resizer resizer) { + // No-op + } + + @Override + public void reset() throws IOException { + // No-op + } + + @Override + public void collect(int doc, int slot, IntFunction slotContext) + throws IOException { + // No-op + } + + @Override + public void incrementCount(int slot, int count) { + // No-op + } + + @Override + public void setNextReader(LeafReaderContext readerContext) throws IOException { + // No-op + } + + @Override + public int collect(DocSet docs, int slot, IntFunction slotContext) + throws IOException { + return docs.size(); // dressed up no-op + } + + @Override + public Object getValue(int slotNum) throws IOException { + throw new UnsupportedOperationException("not supported"); + } + + @Override + public int compare(int slotA, int slotB) { + throw new UnsupportedOperationException("not supported"); + } + + @Override + public void setValues(SimpleOrderedMap bucket, int slotNum) throws IOException { + throw new UnsupportedOperationException("not supported"); + } + + @Override + public int getCount(int slot) { + throw new UnsupportedOperationException("not supported"); + } + } +} diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArray.java b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArray.java index 57781cfe13f6..8e5118dc3b9e 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArray.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArray.java @@ -118,9 +118,11 @@ private SimpleOrderedMap calcFacets() throws IOException { if (refineResult != null) { if (freq.allBuckets) { // count is irrelevant, but hardcoded in collect(...), so intercept/mask normal counts. - // Set here to prevent createAccs(...) from creating a 1-slot countAcc that will fail with AIOOBE - // NOTE: because collectAcc will be null, it is fine/irrelevant to set a countAcc that doesn't support sweeping - countAcc = SlotAcc.DEV_NULL_SLOT_ACC; + // Set here to prevent createAccs(...) from creating a 1-slot countAcc that will fail with + // AIOOBE + // NOTE: because collectAcc will be null, it is fine/irrelevant to set a countAcc that + // doesn't support sweeping + countAcc = Constants.DEV_NULL_SLOT_ACC; createAccs(nDocs, 1); assert collectAcc == null; otherAccs = accs; // accs is created above and set on allBucketsAcc; but during collection, setNextReader is called on otherAccs. 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 e89cfd86b931..dd960be9cc91 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 @@ -823,63 +823,6 @@ public CountSlotAcc(FacetContext fcontext) { public abstract int getCount(int slot); } - /** - * This CountSlotAcc exists as a /dev/null sink for callers of collect(...) and other "write"-type - * methods. It should be used in contexts where "read"-type access methods will never be called. - */ - static final CountSlotAcc DEV_NULL_SLOT_ACC = new CountSlotAcc(null) { - - @Override - public void resize(Resizer resizer) { - // No-op - } - - @Override - public void reset() throws IOException { - // No-op - } - - @Override - public void collect(int doc, int slot, IntFunction slotContext) throws IOException { - // No-op - } - - @Override - public void incrementCount(int slot, int count) { - // No-op - } - - @Override - public void setNextReader(LeafReaderContext readerContext) throws IOException { - // No-op - } - - @Override - public int collect(DocSet docs, int slot, IntFunction slotContext) throws IOException { - return docs.size(); // dressed up no-op - } - - @Override - public Object getValue(int slotNum) throws IOException { - throw new UnsupportedOperationException("not supported"); - } - - @Override - public int compare(int slotA, int slotB) { - throw new UnsupportedOperationException("not supported"); - } - - @Override - public void setValues(SimpleOrderedMap bucket, int slotNum) throws IOException { - throw new UnsupportedOperationException("not supported"); - } - - @Override - public int getCount(int slot) { - throw new UnsupportedOperationException("not supported"); - } - }; - static class CountSlotArrAcc extends CountSlotAcc { int[] result;