Package dovetaildb.querynode

Source Code of dovetaildb.querynode.FlatOrQueryNode

package dovetaildb.querynode;

import java.util.ArrayList;
import java.util.List;

import dovetaildb.bagindex.Range;
import dovetaildb.bytes.ArrayBytes;
import dovetaildb.bytes.Bytes;
import dovetaildb.querynode.QueryNode.NextStatus;

public class FlatOrQueryNode extends AbstractQueryNode {
 
  int idx = 0;
  QueryNode[] nodes;
 
  public FlatOrQueryNode(List<? extends QueryNode> queries) {
    nodes = new QueryNode[queries.size()];
    int i=0;
    for(QueryNode node : queries) {
      nodes[i++] = node;
    }
    setIdx();
  }

  public FlatOrQueryNode(QueryNode[] nodes) {
    this.nodes = nodes;
    setIdx();
  }

  public static QueryNode make(ArrayList<QueryNode> nodes) {
    if (nodes.size() < 2) {
      if (nodes.isEmpty()) {
        return null;
      }
      else return nodes.get(0);
    }
    return new FlatOrQueryNode(nodes);
  }

  @Override
  public long doc() {
    return nodes[idx].doc();
  }

  @Override
  public Bytes term() {
    return nodes[idx].term();
  }
 
  private void setIdx() {
    long smallestDoc = Long.MAX_VALUE;
    Bytes smallestTerm = null;
    for(int curIdx=nodes.length-1; curIdx>=0; curIdx--) {
      QueryNode node = nodes[curIdx];
      long curDoc = node.doc();
      if (curDoc > smallestDoc || curDoc == Long.MAX_VALUE) continue;
      Bytes curTerm = node.term();
      if (smallestTerm == null ||
          curDoc < smallestDoc ||
          curTerm.compareTo(smallestTerm) < 0) {
        smallestDoc = curDoc;
        smallestTerm = curTerm;
        idx = curIdx;
      }
    }
  }

  @Override
  public void seek(long seekDoc, Bytes seekTerm) {
    for(int curIdx=nodes.length-1; curIdx>=0; curIdx--) {
      QueryNode node = nodes[curIdx];
      node.seek(seekDoc, seekTerm);
    }
    setIdx();
  }

  @Override
  public boolean next() {
    throw new RuntimeException("Not supported");
  }

  @Override
  public NextStatus nextTerm() { //TODO kill this and callers of it
    long oldDoc = nodes[idx].doc();
    nodes[idx].nextTerm();
    setIdx();
    long newDoc = nodes[idx].doc();
    if (oldDoc == newDoc) return NextStatus.NEXT_TERM;
    else if (newDoc == Long.MAX_VALUE) return NextStatus.AT_END;
    else return NextStatus.NEXT_DOC;
  }

  @Override
  public QueryNode copy() {
    QueryNode[] nodesCopy = new QueryNode[nodes.length];
    for(int i=0; i<nodesCopy.length; i++) {
      nodesCopy[i] = nodes[i].copy();
    }
    return new FlatOrQueryNode(nodesCopy);
  }

  @Override
  public QueryNode specialize(Range range) {
    boolean anyChange = false;
    ArrayList<QueryNode> clauses = new ArrayList<QueryNode>(nodes.length);
    for(int i=nodes.length-1; i>=0; i--) {
      QueryNode node = nodes[i];
      QueryNode newNode = node.specialize(range);
      if (node == newNode) {
        clauses.add(newNode);
      } else {
        anyChange = true;
        if (newNode != null) {
          clauses.add(newNode);
        }
      }
    }
    if (anyChange) {
      return FlatOrQueryNode.make(clauses);
    } else {
      return this;
    }
  }

  private boolean findNextPositionList() {
    QueryNode node;
    do {
      if (++idx >= nodes.length) return false;
      node = nodes[idx];
      if (node.doc() > positionDoc) continue;
    } while (node.positionSet(positionDoc, positionPrefix) == false);
    return true;
  }
 
  @Override
  public boolean positionSet(long docId, Bytes prefix) {
    idx = 0;
    positionDoc = docId;
    positionPrefix = prefix;
    QueryNode firstNode = nodes[0];
    if (firstNode.positionSet(docId, prefix)) return true;
    return findNextPositionList();
  }
 
  @Override
  public boolean positionNext() {
    if (nodes[idx].positionNext()) return true;
    return findNextPositionList();
  }
 
  @Override
  public long nextValidDocId(long docId) {
//    this.seek(docId, ArrayBytes.EMPTY_BYTES);
//    return doc();
    long smallestDoc = Long.MAX_VALUE;
    for(int curIdx=nodes.length-1; curIdx>=0; curIdx--) {
      QueryNode node = nodes[curIdx];
      long curDoc = node.nextValidDocId(docId);
      if (curDoc < smallestDoc) {
        idx = curIdx;
        if (curDoc == docId) {
          return docId;
        }
        smallestDoc = curDoc;
      }
    }
    return smallestDoc;
  }

  @Override
  public boolean anyNext() {
    boolean cycledOnce = false;
    while (true) {
      if (nodes[idx].anyNext()) return true;
      if (++idx >= nodes.length) {
        idx = 0;
        if (cycledOnce) return false;
        cycledOnce = true;
      }
    }
  }

  public String toString() {
    StringBuffer buf = new StringBuffer("FlatOrQueryNode([\n");
    for(QueryNode node : nodes) {
      if (node == null) continue;
      buf.append("  "+node+"\n");
    }
    buf.append("])\n");
    return buf.toString();
  }
}
TOP

Related Classes of dovetaildb.querynode.FlatOrQueryNode

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.