pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / facet / src / java / org / apache / lucene / facet / util / ResultSortUtils.java
1 package org.apache.lucene.facet.util;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6
7 import org.apache.lucene.util.PriorityQueue;
8
9 import org.apache.lucene.facet.search.Heap;
10 import org.apache.lucene.facet.search.params.FacetRequest;
11 import org.apache.lucene.facet.search.params.FacetRequest.SortOrder;
12 import org.apache.lucene.facet.search.results.FacetResultNode;
13
14 /**
15  * Licensed to the Apache Software Foundation (ASF) under one or more
16  * contributor license agreements.  See the NOTICE file distributed with
17  * this work for additional information regarding copyright ownership.
18  * The ASF licenses this file to You under the Apache License, Version 2.0
19  * (the "License"); you may not use this file except in compliance with
20  * the License.  You may obtain a copy of the License at
21  *
22  *     http://www.apache.org/licenses/LICENSE-2.0
23  *
24  * Unless required by applicable law or agreed to in writing, software
25  * distributed under the License is distributed on an "AS IS" BASIS,
26  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27  * See the License for the specific language governing permissions and
28  * limitations under the License.
29  */
30
31 /**
32  * Utilities for generating facet results sorted as required
33  * 
34  * @lucene.experimental
35  */
36 public class ResultSortUtils {
37
38   /**
39    * Create a suitable heap according to facet request being served. 
40    * @return heap for maintaining results for specified request.
41    * @throws IllegalArgumentException is provided facet request is not supported 
42    */
43   public static Heap<FacetResultNode> createSuitableHeap(FacetRequest facetRequest) {
44     int nresults = facetRequest.getNumResults();
45     boolean accending = (facetRequest.getSortOrder() == SortOrder.ASCENDING);
46
47     if (nresults == Integer.MAX_VALUE) {
48       return new AllValueHeap(accending);
49     }
50
51     if (accending) {
52       switch (facetRequest.getSortBy()) {
53         case VALUE:
54           return new MaxValueHeap(nresults);
55         case ORDINAL:
56           return new MaxOrdinalHeap(nresults);
57       }
58     } else {
59       switch (facetRequest.getSortBy()) {
60         case VALUE:
61           return new MinValueHeap(nresults);
62         case ORDINAL:
63           return new MinOrdinalHeap(nresults);
64       }
65     }
66     throw new IllegalArgumentException("none supported facet request: "+facetRequest);
67   }
68
69   private static class MinValueHeap extends PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
70     public MinValueHeap(int size) {
71       initialize(size);
72     }
73
74     @Override
75     protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
76       double value0 = arg0.getValue();
77       double value1 = arg1.getValue();
78
79       int valueCompare = Double.compare(value0, value1);
80       if (valueCompare == 0) { 
81         return arg0.getOrdinal() < arg1.getOrdinal();
82       }
83
84       return valueCompare < 0;
85     }
86
87   }
88
89   private static class MaxValueHeap extends PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
90     public MaxValueHeap(int size) {
91       initialize(size);
92     }
93
94     @Override
95     protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
96       double value0 = arg0.getValue();
97       double value1 = arg1.getValue();
98
99       int valueCompare = Double.compare(value0, value1);
100       if (valueCompare == 0) { 
101         return arg0.getOrdinal() > arg1.getOrdinal();
102       }
103
104       return valueCompare > 0;
105     }
106   }
107
108   private static class MinOrdinalHeap extends
109   PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
110     public MinOrdinalHeap(int size) {
111       initialize(size);
112     }
113
114     @Override
115     protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
116       return arg0.getOrdinal() < arg1.getOrdinal();
117     }
118
119   }
120
121   private static class MaxOrdinalHeap extends
122   PriorityQueue<FacetResultNode> implements Heap<FacetResultNode> {
123     public MaxOrdinalHeap(int size) {
124       initialize(size);
125     }
126
127     @Override
128     protected boolean lessThan(FacetResultNode arg0, FacetResultNode arg1) {
129       return arg0.getOrdinal() > arg1.getOrdinal();
130     }
131
132   }
133
134   /**
135    * Create a Heap-Look-Alike, which implements {@link Heap}, but uses a
136    * regular <code>ArrayList</code> for holding <b>ALL</b> the objects given,
137    * only sorting upon the first call to {@link #pop()}.
138    */
139   private static class AllValueHeap implements Heap<FacetResultNode> {
140     private ArrayList<FacetResultNode> resultNodes = new ArrayList<FacetResultNode>();
141     final boolean accending;
142     private boolean isReady = false;
143     public AllValueHeap(boolean accending) {
144       this.accending = accending;
145     }
146
147     public FacetResultNode insertWithOverflow(FacetResultNode node) {
148       resultNodes.add(node);
149       return null;
150     }
151
152     public FacetResultNode pop() {
153       if (!isReady) {
154         Collections.sort(resultNodes, new Comparator<FacetResultNode>() {
155           public int compare(FacetResultNode o1, FacetResultNode o2) {
156             int value = Double.compare(o1.getValue(), o2
157                 .getValue());
158             if (value == 0) {
159               value = o1.getOrdinal() - o2.getOrdinal();
160             }
161             if (accending) {
162               value = -value;
163             }
164             return value;
165           }
166         });
167         isReady = true;
168       }
169
170       return resultNodes.remove(0);
171     }
172
173     public int size() {
174       return resultNodes.size();
175     }
176
177     public FacetResultNode top() {
178       if (resultNodes.size() > 0) {
179         return resultNodes.get(0);
180       }
181
182       return null;
183     }
184
185     public FacetResultNode add(FacetResultNode frn) {
186       resultNodes.add(frn);
187       return null;
188     }
189
190     public void clear() {
191       resultNodes.clear();
192     }
193   }
194 }