alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

package org.apache.lucene.search;

/**
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed 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.
 */

import java.io.IOException;
import java.util.Vector;

import org.apache.lucene.document.Document;

/** A ranked list of documents, used to hold search results. */
public final class Hits {
  private Query query;
  private Searcher searcher;
  private Filter filter = null;
  private Sort sort = null;

  private int length;				  // the total number of hits
  private Vector hitDocs = new Vector();	  // cache of hits retrieved

  private HitDoc first;         // head of LRU cache
  private HitDoc last;          // tail of LRU cache
  private int numDocs = 0;      // number cached
  private int maxDocs = 200;    // max to cache

  Hits(Searcher s, Query q, Filter f) throws IOException {
    query = q;
    searcher = s;
    filter = f;
    getMoreDocs(50); // retrieve 100 initially
  }

  Hits(Searcher s, Query q, Filter f, Sort o) throws IOException {
    query = q;
    searcher = s;
    filter = f;
    sort = o;
    getMoreDocs(50); // retrieve 100 initially
  }

  /**
   * Tries to add new documents to hitDocs.
   * Ensures that the hit numbered min has been retrieved.
   */
  private final void getMoreDocs(int min) throws IOException {
    if (hitDocs.size() > min) {
      min = hitDocs.size();
    }

    int n = min * 2;	// double # retrieved
    TopDocs topDocs = (sort == null) ? searcher.search(query, filter, n) : searcher.search(query, filter, n, sort);
    length = topDocs.totalHits;
    ScoreDoc[] scoreDocs = topDocs.scoreDocs;

    float scoreNorm = 1.0f;
    if (length > 0 && scoreDocs[0].score > 1.0f) {
      scoreNorm = 1.0f / scoreDocs[0].score;
    }

    int end = scoreDocs.length < length ? scoreDocs.length : length;
    for (int i = hitDocs.size(); i < end; i++) {
      hitDocs.addElement(new HitDoc(scoreDocs[i].score * scoreNorm,
                                    scoreDocs[i].doc));
    }
  }

  /** Returns the total number of hits available in this set. */
  public final int length() {
    return length;
  }

  /** Returns the stored fields of the nth document in this set.
   

Documents are cached, so that repeated requests for the same element may return the same Document object. */ public final Document doc(int n) throws IOException { HitDoc hitDoc = hitDoc(n); // Update LRU cache of documents remove(hitDoc); // remove from list, if there addToFront(hitDoc); // add to front of list if (numDocs > maxDocs) { // if cache is full HitDoc oldLast = last; remove(last); // flush last oldLast.doc = null; // let doc get gc'd } if (hitDoc.doc == null) { hitDoc.doc = searcher.doc(hitDoc.id); // cache miss: read document } return hitDoc.doc; } /** Returns the score for the nth document in this set. */ public final float score(int n) throws IOException { return hitDoc(n).score; } /** Returns the id for the nth document in this set. */ public final int id(int n) throws IOException { return hitDoc(n).id; } private final HitDoc hitDoc(int n) throws IOException { if (n >= length) { throw new IndexOutOfBoundsException("Not a valid hit number: " + n); } if (n >= hitDocs.size()) { getMoreDocs(n); } return (HitDoc) hitDocs.elementAt(n); } private final void addToFront(HitDoc hitDoc) { // insert at front of cache if (first == null) { last = hitDoc; } else { first.prev = hitDoc; } hitDoc.next = first; first = hitDoc; hitDoc.prev = null; numDocs++; } private final void remove(HitDoc hitDoc) { // remove from cache if (hitDoc.doc == null) { // it's not in the list return; // abort } if (hitDoc.next == null) { last = hitDoc.prev; } else { hitDoc.next.prev = hitDoc.prev; } if (hitDoc.prev == null) { first = hitDoc.next; } else { hitDoc.prev.next = hitDoc.next; } numDocs--; } } final class HitDoc { float score; int id; Document doc = null; HitDoc next; // in doubly-linked cache HitDoc prev; // in doubly-linked cache HitDoc(float s, int i) { score = s; id = i; } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.