pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / facet / src / java / org / apache / lucene / facet / util / ResultSortUtils.java
diff --git a/lucene-java-3.5.0/lucene/contrib/facet/src/java/org/apache/lucene/facet/util/ResultSortUtils.java b/lucene-java-3.5.0/lucene/contrib/facet/src/java/org/apache/lucene/facet/util/ResultSortUtils.java
new file mode 100644 (file)
index 0000000..8f39d3b
--- /dev/null
@@ -0,0 +1,194 @@
+package org.apache.lucene.facet.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import org.apache.lucene.util.PriorityQueue;
+
+import org.apache.lucene.facet.search.Heap;
+import org.apache.lucene.facet.search.params.FacetRequest;
+import org.apache.lucene.facet.search.params.FacetRequest.SortOrder;
+import org.apache.lucene.facet.search.results.FacetResultNode;
+
+/**
+ * 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.
+ */
+
+/**
+ * Utilities for generating facet results sorted as required
+ * 
+ * @lucene.experimental
+ */
+public class ResultSortUtils {
+
+  /**
+   * Create a suitable heap according to facet request being served. 
+   * @return heap for maintaining results for specified request.
+   * @throws IllegalArgumentException is provided facet request is not supported 
+   */
+  public static Heap<FacetResultNode> createSuitableHeap(FacetRequest facetRequest) {
+    int nresults = facetRequest.getNumResults();
+    boolean accending = (facetRequest.getSortOrder() == SortOrder.ASCENDING);
+
+    if (nresults == Integer.MAX_VALUE) {
+      return new AllValueHeap(accending);
+    }
+
+    if (accending) {
+      switch (facetRequest.getSortBy()) {
+        case VALUE:
+          return new MaxValueHeap(nresults);
+        case ORDINAL:
+          return new MaxOrdinalHeap(nresults);
+      }
+    } else {
+      switch (facetRequest.getSortBy()) {
+        case VALUE:
+          return new MinValueHeap(nresults);
+        case ORDINAL:
+          return new MinOrdinalHeap(nresults);
+      }
+    }
+    throw new IllegalArgumentException("none supported facet request: "+facetRequest);
+  }
+
+  private static class MinValueHeap extends PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
+    public MinValueHeap(int size) {
+      initialize(size);
+    }
+
+    @Override
+    protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
+      double value0 = arg0.getValue();
+      double value1 = arg1.getValue();
+
+      int valueCompare = Double.compare(value0, value1);
+      if (valueCompare == 0) { 
+        return arg0.getOrdinal() < arg1.getOrdinal();
+      }
+
+      return valueCompare < 0;
+    }
+
+  }
+
+  private static class MaxValueHeap extends PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
+    public MaxValueHeap(int size) {
+      initialize(size);
+    }
+
+    @Override
+    protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
+      double value0 = arg0.getValue();
+      double value1 = arg1.getValue();
+
+      int valueCompare = Double.compare(value0, value1);
+      if (valueCompare == 0) { 
+        return arg0.getOrdinal() > arg1.getOrdinal();
+      }
+
+      return valueCompare > 0;
+    }
+  }
+
+  private static class MinOrdinalHeap extends
+  PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
+    public MinOrdinalHeap(int size) {
+      initialize(size);
+    }
+
+    @Override
+    protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
+      return arg0.getOrdinal() < arg1.getOrdinal();
+    }
+
+  }
+
+  private static class MaxOrdinalHeap extends
+  PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
+    public MaxOrdinalHeap(int size) {
+      initialize(size);
+    }
+
+    @Override
+    protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
+      return arg0.getOrdinal() > arg1.getOrdinal();
+    }
+
+  }
+
+  /**
+   * Create a Heap-Look-Alike, which implements {@link Heap}, but uses a
+   * regular <code>ArrayList</code> for holding <b>ALL</b> the objects given,
+   * only sorting upon the first call to {@link #pop()}.
+   */
+  private static class AllValueHeap implements Heap<FacetResultNode> {
+    private ArrayList<FacetResultNode> resultNodes = new ArrayList<FacetResultNode>();
+    final boolean accending;
+    private boolean isReady = false;
+    public AllValueHeap(boolean accending) {
+      this.accending = accending;
+    }
+
+    public FacetResultNode insertWithOverflow(FacetResultNode node) {
+      resultNodes.add(node);
+      return null;
+    }
+
+    public FacetResultNode pop() {
+      if (!isReady) {
+        Collections.sort(resultNodes, new Comparator<FacetResultNode>() {
+          public int compare(FacetResultNode o1, FacetResultNode o2) {
+            int value = Double.compare(o1.getValue(), o2
+                .getValue());
+            if (value == 0) {
+              value = o1.getOrdinal() - o2.getOrdinal();
+            }
+            if (accending) {
+              value = -value;
+            }
+            return value;
+          }
+        });
+        isReady = true;
+      }
+
+      return resultNodes.remove(0);
+    }
+
+    public int size() {
+      return resultNodes.size();
+    }
+
+    public FacetResultNode top() {
+      if (resultNodes.size() > 0) {
+        return resultNodes.get(0);
+      }
+
+      return null;
+    }
+
+    public FacetResultNode add(FacetResultNode frn) {
+      resultNodes.add(frn);
+      return null;
+    }
+
+    public void clear() {
+      resultNodes.clear();
+    }
+  }
+}