Package org.sindice.siren.search.node

Source Code of org.sindice.siren.search.node.NodeReqOptScorer

/**
* Copyright 2014 National University of Ireland, Galway.
*
* This file is part of the SIREn project. Project and contact information:
*
*  https://github.com/rdelbru/SIREn
*
* 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.
*/

package org.sindice.siren.search.node;

import java.io.IOException;

import org.apache.lucene.util.IntsRef;
import org.sindice.siren.util.NodeUtils;

/**
* A {@link NodeScorer} for queries with a required part and an optional part.
* Delays advance() on the optional part until a score() is needed.
*
* <p>
*
* Code taken from {@link ReqOptSumScorer} and adapted for the Siren use
* case.
*/
class NodeReqOptScorer extends NodeScorer {

  /**
   * The required scorer passed from the constructor.
   */
  private final NodeScorer reqScorer;

  /**
   * The optional scorer passed from the constructor, and used for boosting
   * score.
   */
  private NodeScorer optScorer;

  /**
   * Construct a {@link NodeReqOptScorer}.
   *
   * @param reqScorer
   *          The required scorer. This must match.
   * @param optScorer
   *          The optional scorer. This is used for scoring only.
   */
  public NodeReqOptScorer(final NodeScorer reqScorer,
                          final NodeScorer optScorer) {
    super(reqScorer.getWeight());
    this.reqScorer = reqScorer;
    this.optScorer = optScorer;
  }

  @Override
  public boolean nextCandidateDocument() throws IOException {
    return reqScorer.nextCandidateDocument();
  }

  @Override
  public boolean nextNode() throws IOException {
    return reqScorer.nextNode();
  }

  @Override
  public boolean skipToCandidate(final int target) throws IOException {
    return reqScorer.skipToCandidate(target);
  }

  @Override
  public int doc() {
    return reqScorer.doc();
  }

  @Override
  public IntsRef node() {
    return reqScorer.node();
  }

  @Override
  public float freqInNode() throws IOException {
    // TODO: Computation similar to #scoreInNode. Could the instructions be
    // abstracted and merged somehow
    final float reqFreq = reqScorer.freqInNode();
    final int doc = this.doc();

    if (optScorer == null) {
      return reqFreq;
    } else if (optScorer.doc() < doc && // if it is the first call, optScorer.doc() returns -1
               !optScorer.skipToCandidate(doc)) {
      optScorer = null;
      return reqFreq;
    }

    final IntsRef reqNode = this.node();
    /*
     * the optional scorer can be in a node that is before the one where
     * the required scorer is in.
     */
    int cmp = 1;
    while ((cmp = NodeUtils.compare(optScorer.node(), reqNode)) < 0) {
      if (!optScorer.nextNode()) {
        return reqFreq;
      }
    }
    // If the optional scorer matches the same node, increase the freq
    return (optScorer.doc() == doc && cmp == 0)
           ? reqFreq + optScorer.freqInNode()
           : reqFreq;
  }

  @Override
  public float scoreInNode() throws IOException {
    final float reqScore = reqScorer.scoreInNode();
    final int doc = this.doc();

    if (optScorer == null) {
      return reqScore;
    } else if (optScorer.doc() < doc && // if it is the first call, optScorer.doc() returns -1
               !optScorer.skipToCandidate(doc)) {
      optScorer = null;
      return reqScore;
    }

    final IntsRef reqNode = this.node();
    /*
     * the optional scorer can be in a node that is before the one where
     * the required scorer is in.
     */
    int cmp = 1;
    while ((cmp = NodeUtils.compare(optScorer.node(), reqNode)) < 0) {
      if (!optScorer.nextNode()) {
        return reqScore;
      }
    }
    // If the optional scorer matches the same node, increase the score
    return (optScorer.doc() == doc && cmp == 0)
           ? reqScore + optScorer.scoreInNode()
           : reqScore;
  }

  @Override
  public String toString() {
    return "NodeReqOptScorer(" + weight + "," +
      this.doc() + "," + this.node() + ")";
  }

}
TOP

Related Classes of org.sindice.siren.search.node.NodeReqOptScorer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.