pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / facet / src / java / org / apache / lucene / facet / search / TopKFacetResultsHandler.java
diff --git a/lucene-java-3.4.0/lucene/contrib/facet/src/java/org/apache/lucene/facet/search/TopKFacetResultsHandler.java b/lucene-java-3.4.0/lucene/contrib/facet/src/java/org/apache/lucene/facet/search/TopKFacetResultsHandler.java
deleted file mode 100644 (file)
index 43df368..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-package org.apache.lucene.facet.search;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-import org.apache.lucene.facet.search.params.FacetRequest;
-import org.apache.lucene.facet.search.results.FacetResult;
-import org.apache.lucene.facet.search.results.FacetResultNode;
-import org.apache.lucene.facet.search.results.MutableFacetResultNode;
-import org.apache.lucene.facet.search.results.IntermediateFacetResult;
-import org.apache.lucene.facet.taxonomy.TaxonomyReader;
-import org.apache.lucene.facet.taxonomy.TaxonomyReader.ChildrenArrays;
-import org.apache.lucene.facet.util.ResultSortUtils;
-
-/**
- * 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.
- */
-
-/** 
- * Generate Top-K results for a particular FacetRequest.
- * <p>
- * K is global (among all results) and is defined by {@link FacetRequest#getNumResults()}.
- * <p> 
- * Note: Values of 0 (Zero) are ignored by this results handler.
- * 
- * @lucene.experimental
- */
-public class TopKFacetResultsHandler extends FacetResultsHandler {
-  
-  /**
-   * Construct top-K results handler.  
-   * @param taxonomyReader taxonomy reader
-   * @param facetRequest facet request being served
-   */
-  public TopKFacetResultsHandler(TaxonomyReader taxonomyReader,
-      FacetRequest facetRequest) {
-    super(taxonomyReader, facetRequest);
-  }
-  
-  // fetch top K for specific partition. 
-  @Override
-  public IntermediateFacetResult fetchPartitionResult(FacetArrays facetArrays, int offset)
-  throws IOException {
-    TopKFacetResult res = null;
-    int ordinal = taxonomyReader.getOrdinal(facetRequest.getCategoryPath());
-    if (ordinal != TaxonomyReader.INVALID_ORDINAL) {
-      double value = 0;  
-      if (isSelfPartition(ordinal, facetArrays, offset)) {
-        int partitionSize = facetArrays.getArraysLength();
-        value = facetRequest.getValueOf(facetArrays, ordinal % partitionSize);
-      }
-      
-      // TODO (Facet): should initial value of "residue" depend on aggregator if not sum?
-      MutableFacetResultNode parentResultNode = 
-        new MutableFacetResultNode(ordinal, value);
-      
-      Heap<FacetResultNode> heap = ResultSortUtils.createSuitableHeap(facetRequest);
-      int totalFacets = heapDescendants(ordinal, heap, parentResultNode, facetArrays, offset);
-      res = new TopKFacetResult(facetRequest, parentResultNode, totalFacets);
-      res.setHeap(heap);
-    }
-    return res;
-  }
-  
-  // merge given top K results into current 
-  @Override
-  public IntermediateFacetResult mergeResults(IntermediateFacetResult... tmpResults) throws IOException {
-    
-    int ordinal = taxonomyReader.getOrdinal(facetRequest.getCategoryPath());
-    MutableFacetResultNode resNode = new MutableFacetResultNode(ordinal, 0);
-    
-    int totalFacets = 0;
-    Heap<FacetResultNode> heap = null;
-    
-    // merge other results in queue
-    for (IntermediateFacetResult tmpFres : tmpResults) {
-      // cast should succeed
-      TopKFacetResult fres = (TopKFacetResult) tmpFres;
-      totalFacets += fres.getNumValidDescendants();
-      // set the value for the result node representing the facet request
-      resNode.increaseValue(fres.getFacetResultNode().getValue());
-      Heap<FacetResultNode> tmpHeap = fres.getHeap();
-      if (heap == null) {
-        heap = tmpHeap;
-        continue;
-      }
-      // bring sub results from heap of tmp res into result heap
-      for (int i = tmpHeap.size(); i > 0; i--) {
-        
-        FacetResultNode a = heap.insertWithOverflow(tmpHeap.pop());
-        if (a != null) {
-          resNode.increaseResidue(a.getResidue());
-        }
-      }
-    }
-    
-    TopKFacetResult res = new TopKFacetResult(facetRequest, resNode, totalFacets);
-    res.setHeap(heap);
-    return res;
-  }
-  
-  /**
-   * Finds the top K descendants of ordinal, which are at most facetRequest.getDepth()
-   * deeper than facetRequest.getCategoryPath (whose ordinal is input parameter ordinal). 
-   * Candidates are restricted to current "counting list" and current "partition",
-   * they join the overall priority queue pq of size K.  
-   * @return total number of descendants considered here by pq, excluding ordinal itself.
-   */
-  private int heapDescendants(int ordinal, Heap<FacetResultNode> pq,
-      MutableFacetResultNode parentResultNode, FacetArrays facetArrays, int offset) {
-    int partitionSize = facetArrays.getArraysLength();
-    int endOffset = offset + partitionSize;
-    ChildrenArrays childrenArray = taxonomyReader.getChildrenArrays();
-    int[] youngestChild = childrenArray.getYoungestChildArray();
-    int[] olderSibling = childrenArray.getOlderSiblingArray();
-    FacetResultNode reusable = null;
-    int localDepth = 0;
-    int depth = facetRequest.getDepth();
-    int[] ordinalStack = new int[2+Math.min(Short.MAX_VALUE, depth)];
-    int childrenCounter = 0;
-    
-    int tosOrdinal; // top of stack element
-    
-    int yc = youngestChild[ordinal];
-    while (yc >= endOffset) {
-      yc = olderSibling[yc];
-    }
-    // make use of the fact that TaxonomyReader.INVALID_ORDINAL == -1, < endOffset
-    // and it, too, can stop the loop.
-    ordinalStack[++localDepth] = yc;
-    
-    /*
-     * stack holds input parameter ordinal in position 0.
-     * Other elements are < endoffset.
-     * Only top of stack can be TaxonomyReader.INVALID_ORDINAL, and this if and only if
-     * the element below it exhausted all its children: has them all processed.
-     * 
-     * stack elements are processed (counted and accumulated) only if they 
-     * belong to current partition (between offset and endoffset) and first time
-     * they are on top of stack 
-     * 
-     * loop as long as stack is not empty of elements other than input ordinal, or for a little while -- it sibling
-     */
-    while (localDepth > 0) {
-      tosOrdinal = ordinalStack[localDepth];
-      if (tosOrdinal == TaxonomyReader.INVALID_ORDINAL) {
-        // element below tos has all its children, and itself, all processed
-        // need to proceed to its sibling
-        localDepth--;
-        // change element now on top of stack to its sibling.
-        ordinalStack[localDepth] = olderSibling[ordinalStack[localDepth]];
-        continue;
-      }
-      // top of stack is not invalid, this is the first time we see it on top of stack.
-      // collect it, if belongs to current partition, and then push its kids on itself, if applicable
-      if (tosOrdinal >= offset) { // tosOrdinal resides in current partition
-        int relativeOrdinal = tosOrdinal % partitionSize;
-        double value = facetRequest.getValueOf(facetArrays, relativeOrdinal);
-        if (value != 0 && !Double.isNaN(value)) {
-          // Count current ordinal -- the TOS
-          if (reusable == null) {
-            reusable = new MutableFacetResultNode(tosOrdinal, value);
-          } else {
-            // it is safe to cast since reusable was created here.
-            ((MutableFacetResultNode)reusable).reset(tosOrdinal, value);
-          }
-          ++childrenCounter;
-          reusable = pq.insertWithOverflow(reusable);
-          if (reusable != null) {
-            // TODO (Facet): is other logic (not add) needed, per aggregator?
-            parentResultNode.increaseResidue(reusable.getValue());
-          }
-        }
-      }
-      if (localDepth < depth) {
-        // push kid of current tos
-        yc = youngestChild[tosOrdinal];
-        while (yc >= endOffset) {
-          yc = olderSibling[yc];
-        }
-        ordinalStack[++localDepth] = yc;
-      } else { // localDepth == depth; current tos exhausted its possible children, mark this by pushing INVALID_ORDINAL
-        ordinalStack[++localDepth] = TaxonomyReader.INVALID_ORDINAL;
-      }
-    } // endof while stack is not empty
-    
-    return childrenCounter; // we're done
-  }
-  
-  @Override
-  public FacetResult renderFacetResult(IntermediateFacetResult tmpResult) {
-    TopKFacetResult res = (TopKFacetResult) tmpResult; // cast is safe by contract of this class
-    if (res != null) {
-      Heap<FacetResultNode> heap = res.getHeap();
-      MutableFacetResultNode resNode = (MutableFacetResultNode)res.getFacetResultNode(); // cast safe too
-      for (int i = heap.size(); i > 0; i--) {
-        resNode.insertSubResult(heap.pop());
-      }
-    }
-    return res;
-  }
-  
-  @Override
-  public FacetResult rearrangeFacetResult(FacetResult facetResult) {
-    TopKFacetResult res = (TopKFacetResult) facetResult; // cast is safe by contract of this class
-    Heap<FacetResultNode> heap = res.getHeap();
-    heap.clear(); // just to be safe
-    MutableFacetResultNode topFrn = (MutableFacetResultNode) res.getFacetResultNode(); // safe cast
-    for (FacetResultNode frn : topFrn.getSubResults()) {
-      heap.add(frn);
-    }
-    int size = heap.size();
-    ArrayList<FacetResultNode> subResults = new ArrayList<FacetResultNode>(size);
-    for (int i = heap.size(); i > 0; i--) {
-      subResults.add(0,heap.pop());
-    }
-    topFrn.setSubResults(subResults);
-    return res;
-  }
-  
-  @Override
-  // label top K sub results
-  public void labelResult(FacetResult facetResult) throws IOException {
-    if (facetResult != null) { // any result to label?
-      FacetResultNode facetResultNode = facetResult.getFacetResultNode();
-      if (facetResultNode != null) { // any result to label?
-        facetResultNode.getLabel(taxonomyReader);
-        int num2label = facetRequest.getNumLabel();
-        for (FacetResultNode frn : facetResultNode.getSubResults()) {
-          if (--num2label < 0) {
-            break;
-          }
-          frn.getLabel(taxonomyReader);
-        }
-      }
-    }
-  }
-  
-  ////////////////////////////////////////////////////////////////////////////////////
-  ////////////////////////////////////////////////////////////////////////////////////
-  
-  /**
-   * Private Mutable implementation of result of faceted search.
-   */
-  private static class TopKFacetResult extends FacetResult implements IntermediateFacetResult {
-    
-    // TODO (Facet): is it worth to override PriorityQueue.getSentinelObject()
-    // for any of our PQs?
-    private Heap<FacetResultNode> heap; 
-    
-    /**
-     * Create a Facet Result.
-     * @param facetRequest Request for which this result was obtained.
-     * @param facetResultNode top result node for this facet result.
-     * @param totalFacets - number of children of the targetFacet, up till the requested depth.
-     */
-    TopKFacetResult(FacetRequest facetRequest, MutableFacetResultNode facetResultNode, int totalFacets) {
-      super(facetRequest, facetResultNode, totalFacets);
-    }
-    
-    /**
-     * @return the heap
-     */
-    public Heap<FacetResultNode> getHeap() {
-      return heap;
-    }
-    
-    /**
-     * Set the heap for this result.
-     * @param heap heap top be set.
-     */
-    public void setHeap(Heap<FacetResultNode> heap) {
-      this.heap = heap;
-    }
-    
-  }
-  
-  //////////////////////////////////////////////////////
-}