--- /dev/null
+package org.apache.lucene.facet.index.params;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+
+import org.apache.lucene.facet.search.CategoryListIterator;
+import org.apache.lucene.facet.search.PayloadIntDecodingIterator;
+import org.apache.lucene.facet.search.TotalFacetCounts;
+import org.apache.lucene.facet.util.PartitionsUtils;
+import org.apache.lucene.util.encoding.DGapIntEncoder;
+import org.apache.lucene.util.encoding.IntDecoder;
+import org.apache.lucene.util.encoding.IntEncoder;
+import org.apache.lucene.util.encoding.SortingIntEncoder;
+import org.apache.lucene.util.encoding.UniqueValuesIntEncoder;
+import org.apache.lucene.util.encoding.VInt8IntEncoder;
+
+/**
+ * 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.
+ */
+
+/**
+ * Contains parameters for a category list *
+ *
+ * @lucene.experimental
+ */
+public class CategoryListParams implements Serializable {
+
+ /** The default term used to store the facets information. */
+ public static final Term DEFAULT_TERM = new Term("$facets", "$fulltree$");
+
+ private final Term term;
+
+ private final int hashCode;
+
+ /**
+ * Constructs a default category list parameters object, using
+ * {@link #DEFAULT_TERM}.
+ */
+ public CategoryListParams() {
+ this(DEFAULT_TERM);
+ }
+
+ /**
+ * Constructs a category list parameters object, using the given {@link Term}.
+ * @param term who's payload hold the category-list.
+ */
+ public CategoryListParams(Term term) {
+ this.term = term;
+ // Pre-compute the hashCode because these objects are immutable. Saves
+ // some time on the comparisons later.
+ this.hashCode = term.hashCode();
+ }
+
+ /**
+ * A {@link Term} who's payload holds the category-list.
+ */
+ public final Term getTerm() {
+ return term;
+ }
+
+ /**
+ * Allows to override how categories are encoded and decoded. A matching
+ * {@link IntDecoder} is provided by the {@link IntEncoder}.
+ * <p>
+ * Default implementation creates a new Sorting(<b>Unique</b>(DGap)) encoder.
+ * Uniqueness in this regard means when the same category appears twice in a
+ * document, only one appearance would be encoded. This has effect on facet
+ * counting results.
+ * <p>
+ * Some possible considerations when overriding may be:
+ * <ul>
+ * <li>an application "knows" that all categories are unique. So no need to
+ * pass through the unique filter.</li>
+ * <li>Another application might wish to count multiple occurrences of the
+ * same category, or, use a faster encoding which will consume more space.</li>
+ * </ul>
+ * In any event when changing this value make sure you know what you are
+ * doing, and test the results - e.g. counts, if the application is about
+ * counting facets.
+ */
+ public IntEncoder createEncoder() {
+ return new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new VInt8IntEncoder())));
+ }
+
+ /**
+ * Equality is defined by the 'term' that defines this category list.
+ * Sub-classes should override this method if a more complex calculation
+ * is needed to ensure equality.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof CategoryListParams)) {
+ return false;
+ }
+ CategoryListParams other = (CategoryListParams) o;
+ if (this.hashCode != other.hashCode) {
+ return false;
+ }
+ // The above hashcodes might equal each other in the case of a collision,
+ // so at this point only directly term equality testing will settle
+ // the equality test.
+ return this.term.equals(other.term);
+ }
+
+ /**
+ * Hashcode is similar to {@link #equals(Object)}, in that it uses
+ * the term that defines this category list to derive the hashcode.
+ * Subclasses need to ensure that equality/hashcode is correctly defined,
+ * or there could be side-effects in the {@link TotalFacetCounts} caching
+ * mechanism (as the filename for a Total Facet Counts array cache
+ * is dependent on the hashCode, so it should consistently return the same
+ * hash for identity).
+ */
+ @Override
+ public int hashCode() {
+ return this.hashCode;
+ }
+
+ /**
+ * Create the category list iterator for the specified partition.
+ */
+ public CategoryListIterator createCategoryListIterator(IndexReader reader,
+ int partition) throws IOException {
+ String categoryListTermStr = PartitionsUtils.partitionName(this, partition);
+ Term payloadTerm = term.createTerm(categoryListTermStr);
+ return new PayloadIntDecodingIterator(reader, payloadTerm,
+ createEncoder().createMatchingDecoder());
+ }
+
+}
\ No newline at end of file