Package dovetaildb.dbservice

Source Code of dovetaildb.dbservice.QueryNodeIter$RangeSpecialization

package dovetaildb.dbservice;

import java.util.ArrayList;

import dovetaildb.bagindex.BagIndex;
import dovetaildb.bagindex.Range;
import dovetaildb.bytes.ArrayBytes;
import dovetaildb.dbservice.DbServiceUtil.RangeExtractor;
import dovetaildb.iter.AbstractIter;
import dovetaildb.querynode.AndQueryNode;
import dovetaildb.querynode.NodeHeap;
import dovetaildb.querynode.QueryNode;
import dovetaildb.querynode.WrappingQueryNode;
import dovetaildb.querynode.QueryNode.NextStatus;

public class QueryNodeIter extends AbstractIter {

  protected static class RangeSpecialization {
    RangeSpecialization(Range range, QueryNode node) { this.range=range; this.node=node; }
    Range range;
    QueryNode node;
  }
 
  boolean isAdvanced;
  protected QueryNode innerNode, outerNode;
  protected AndQueryNode specializationNode = null;
  protected ArrayList<RangeSpecialization> rangeSpecializations = new ArrayList<RangeSpecialization>();
  protected QueryNodeDbResult dbResult;
  protected BagIndex index;
  protected long revNum, curDocId;

  protected QueryNodeIter(QueryNode selector, QueryNode display, BagIndex index, long revNum) {
    dbResult = new QueryNodeDbResult(display);
    innerNode = outerNode = selector;
    this.index = index;
    this.revNum = revNum;
    initHere();
  }
 
  private void initHere() {
    isAdvanced = true;
    curDocId = outerNode.doc();
  }
 
  public void addSpecializationRange(Range range) {
    ensureIsAdvanced();
    if (outerNode == null) {
      outerNode = null;
      return;
    }
    QueryNode node = index.getRange(new Range(range), revNum);
    if (node == null) {
      outerNode = null;
      return;
    }
    long curDoc = outerNode.doc();
    node.seek(curDoc, ArrayBytes.EMPTY_BYTES);
    if (node.doc() == Long.MAX_VALUE) {
      outerNode = null;
      return;
    }
    rangeSpecializations.add(new RangeSpecialization(range, node));
    ArrayList<QueryNode> nodes = new ArrayList<QueryNode>();
    nodes.add(innerNode);
    for(RangeSpecialization specialization : rangeSpecializations) {
      nodes.add(specialization.node);
    }
    assert nodes.size() > 1;
    specializationNode = (AndQueryNode)AndQueryNode.make(nodes);
    outerNode = specializationNode;
  }

  private void rebuildSpecializationRange() {
    ArrayList<QueryNode> nodes = new ArrayList<QueryNode>();
    nodes.add(innerNode);
    for(RangeSpecialization rec : rangeSpecializations) {
      nodes.add(rec.node);
    }
    specializationNode = new AndQueryNode(new NodeHeap(nodes));
    outerNode = specializationNode;
  }

  private void bind() {
//    long docId = outerNode.doc();

    long docId = curDocId;
    dbResult.reset();
    dbResult.docId = docId;
    dbResult.initialize(docId);
  }

  @Override
  public boolean specialize(Object query) {
    RangeExtractor ex = new RangeExtractor();
    ArrayList<Range> ranges = ex.getRanges(query);
    boolean optimized = false;
    for(Range range : ranges) {
      range.flattenTerms();
      RangeSpecialization target = null;
      for(RangeSpecialization special: rangeSpecializations) {
        if (special.range.contains(range)) {
          target = special;
          break;
        } else if (range.contains(special.range)) {
          return false;
        }
      }
      if (target == null) {
        addSpecializationRange(range);
        optimized = true;
      } else {
        Object[] heap = specializationNode.heap.heap;
        for(int i=1; i<heap.length; i++) {
          QueryNode curNode = (QueryNode) heap[i];
          if (curNode == target.node) {
            QueryNode newNode = specializationNode.heap.specializeChild(i, range);
            optimized |= target.node != newNode;
            if (optimized) {
              target.node = newNode;
              rebuildSpecializationRange();
            }
            break;
          }
        }
      }
      long newDocId = outerNode.doc();
      if (newDocId < curDocId) {
        newDocId = outerNode.nextValidDocId(curDocId);
      }
      if (newDocId > curDocId) {
        isAdvanced = true;
      }
      curDocId = newDocId;
    }
    return optimized;
  }

  private void ensureIsAdvanced() {
    if (!isAdvanced) {

//      boolean hasNext = outerNode.next();
//      if (!hasNext) outerNode = innerNode = null;

      curDocId = outerNode.nextValidDocId(curDocId + 1);
      if (curDocId == Long.MAX_VALUE) outerNode = innerNode = null;
     
      isAdvanced = true;
    }
  }
 
  public boolean hasNext() {
    if (outerNode == null) return false;
    ensureIsAdvanced();
    return outerNode != null;
  }

  public Object next() {
    ensureIsAdvanced();
    bind();
    isAdvanced = false;
    return dbResult.simplify();
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }

}
TOP

Related Classes of dovetaildb.dbservice.QueryNodeIter$RangeSpecialization

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.