Пример #1
0
  /**
   * Returns all summary path nodes for the specified location step or {@code null} if nodes cannot
   * be retrieved or are found on different levels.
   *
   * @param data data reference
   * @param last last step to be checked
   * @return path nodes
   */
  private ArrayList<PathNode> pathNodes(final Data data, final int last) {
    // skip request if no path index exists or might be out-of-date
    if (!data.meta.uptodate) return null;

    ArrayList<PathNode> nodes = data.paths.root();
    for (int s = 0; s <= last; s++) {
      // only follow axis steps
      final Step curr = axisStep(s);
      if (curr == null) return null;

      final boolean desc = curr.axis == DESC;
      if (!desc && curr.axis != CHILD || curr.test.kind != Kind.NAME) return null;

      final int name = data.elemNames.id(curr.test.name.local());

      final ArrayList<PathNode> tmp = new ArrayList<>();
      for (final PathNode node : PathSummary.desc(nodes, desc)) {
        if (node.kind == Data.ELEM && name == node.name) {
          // skip test if an element name occurs on different levels
          if (!tmp.isEmpty() && tmp.get(0).level() != node.level()) return null;
          tmp.add(node);
        }
      }
      if (tmp.isEmpty()) return null;
      nodes = tmp;
    }
    return nodes;
  }
Пример #2
0
  /**
   * Returns all summary path nodes for the specified location step or {@code null} if nodes cannot
   * be retrieved or are found on different levels.
   *
   * @param data data reference
   * @param l last step to be checked
   * @return path nodes
   */
  ArrayList<PathNode> pathNodes(final Data data, final int l) {
    // skip request if no path index exists or might be out-of-date
    if (!data.meta.uptodate) return null;

    ArrayList<PathNode> in = data.paths.root();
    for (int s = 0; s <= l; ++s) {
      final Step curr = axisStep(s);
      if (curr == null) return null;
      final boolean desc = curr.axis == DESC;
      if (!desc && curr.axis != CHILD || curr.test.mode != Mode.LN) return null;

      final int name = data.tagindex.id(curr.test.name.local());

      final ArrayList<PathNode> al = new ArrayList<>();
      for (final PathNode pn : PathSummary.desc(in, desc)) {
        if (pn.kind == Data.ELEM && name == pn.name) {
          // skip test if a tag is found on different levels
          if (!al.isEmpty() && al.get(0).level() != pn.level()) return null;
          al.add(pn);
        }
      }
      if (al.isEmpty()) return null;
      in = al;
    }
    return in;
  }
Пример #3
0
 /**
  * Returns a string representation of a path summary node.
  *
  * @param data data reference
  * @param level level
  * @return string representation
  */
 byte[] info(final Data data, final int level) {
   final TokenBuilder tb = new TokenBuilder();
   if (level != 0) tb.add(Text.NL);
   for (int i = 0; i < level << 1; ++i) tb.add(' ');
   switch (kind) {
     case Data.DOC:
       tb.add(DOC);
       break;
     case Data.ELEM:
       tb.add(data.elemNames.key(name));
       break;
     case Data.TEXT:
       tb.add(TEXT);
       break;
     case Data.ATTR:
       tb.add(ATT);
       tb.add(data.attrNames.key(name));
       break;
     case Data.COMM:
       tb.add(COMMENT);
       break;
     case Data.PI:
       tb.add(PI);
       break;
   }
   tb.add(": " + stats);
   for (final PathNode p : children) tb.add(p.info(data, level + 1));
   return tb.finish();
 }
Пример #4
0
 @Override
 public boolean equals(Object obj) {
   PathNode b = (PathNode) obj;
   if (b.getCurr() == this.curr) {
     return true;
   }
   return false;
 }
Пример #5
0
  /**
   * Writes the node to the specified output stream.
   *
   * @param out output stream
   * @throws IOException I/O exception
   */
  void write(final DataOutput out) throws IOException {
    out.writeNum(name);
    out.write1(kind);
    out.writeNum(0);
    out.writeNum(children.length);
    out.writeDouble(1);

    // update leaf flag
    boolean leaf = stats.isLeaf();
    for (final PathNode child : children) {
      leaf &= child.kind == Data.TEXT || child.kind == Data.ATTR;
    }
    stats.setLeaf(leaf);
    stats.write(out);
    for (final PathNode child : children) child.write(out);
  }
Пример #6
0
 /**
  * Recursively adds the node and its descendants to the specified list with the specified name.
  *
  * @param nodes node list
  * @param nm name id
  */
 public void addDesc(final ArrayList<PathNode> nodes, final int nm) {
   if (kind == Data.ELEM && nm == name) nodes.add(this);
   for (final PathNode child : children) child.addDesc(nodes, nm);
 }
Пример #7
0
 /**
  * Recursively adds the node and its descendants to the specified list.
  *
  * @param nodes node list
  */
 void addDesc(final ArrayList<PathNode> nodes) {
   nodes.add(this);
   for (final PathNode child : children) child.addDesc(nodes);
 }
Пример #8
0
  /**
   * Determines the routes comprising the shortest path between two cities
   *
   * @param to city 1
   * @param from city 2
   * @param considerMadeMoves should the algorithm look to see if all routes have been claimed
   * @return the list of routes in the shortest path between destinations, nested ArrayList allows
   *     access to multiple existant routes between adjacent cities, returns null if no route is
   *     found
   */
  public ArrayList<ArrayList<Route>> getPath(
      Destination to, Destination from, boolean considerMadeMoves) {
    Routes routes = Routes.getInstance();
    PriorityQueue<PathNode> openList = new PriorityQueue<PathNode>(1, new PathNodeComparator());
    ArrayList<PathNode> closedList = new ArrayList<PathNode>();

    // get origin onto PQ
    PathNode origin = new PathNode(from);
    openList.add(origin);

    while (!openList.isEmpty()) {
      PathNode node = openList.poll();
      // int fooCost = routes.shortestPathcost(from, node.getCurr());
      // System.out.println("Were looking at "+node.getCurr().name()+". The previous node is
      // "+node.getPrev()+". The distance from start is "+ node.getDistToStart()+ ". The best
      // possible cost to here is "+fooCost);
      // deal with the node having already been closed
      if (closedList.contains(node)) {
        // System.out.println("Skipping already searched city "+node.getCurr().name()+"\n");
        continue;
      }
      // deal with this being the end node
      if (node.getCurr() == to) {
        // push all the routes into a stack
        Stack<ArrayList<Route>> pathBuilder = new Stack<ArrayList<Route>>();
        boolean pathNotComplete = true;
        PathNode curr = node;
        PathNode prev = null;
        for (PathNode fooNode : closedList) {
          if (fooNode.getCurr() == curr.getPrev()) {
            prev = fooNode;
            break;
          }
        }
        while (pathNotComplete) {
          // if its the start node
          Destination currName = curr.getCurr();
          Destination prevName = prev.getCurr();
          if (currName == from) {
            break;
          }
          // System.out.println("Building path from "+currName.name()+ " to "+prevName.name());
          pathBuilder.push(routes.getRoutes(currName, prevName));
          curr = prev;
          for (PathNode fooNode : closedList) {
            if (fooNode.getCurr() == curr.getPrev()) {
              prev = fooNode;
            }
          }
        }

        // System.out.println("Building route");
        ArrayList<ArrayList<Route>> orderedRoute = new ArrayList<ArrayList<Route>>();
        while (!pathBuilder.isEmpty()) {
          orderedRoute.add(pathBuilder.pop());
        }
        return orderedRoute;
      }
      // add all values to the pq
      for (Destination dest : routes.getNeighbors(node.getCurr())) {
        // prevents looping
        boolean isClosed = false;
        for (PathNode fooNode : closedList) {
          if (dest == fooNode.getCurr()) {
            // System.out.println(dest.name()+" Node is closed");
            isClosed = true;
            break;
          }
        }
        Route thisRoute = routes.getRoutes(dest, node.getCurr()).get(0);
        if (considerMadeMoves) {
          if (!isClosed
              && (!routes.isRouteClaimed(thisRoute)
                  || (thisRoute.getOwner() instanceof TTRPlayer))) {
            // get cost of this node
            int cost = thisRoute.getCost();
            // System.out.println("Adding "+dest.name()+" to be searched. Its previous node is
            // "+node.getCurr()+". Its cost is "+cost+". Its total cost is
            // "+(cost+node.getDistToStart())+" Its owner is "+thisRoute.getOwner());
            PathNode nextNode = new PathNode(dest, node.getCurr(), node.getDistToStart() + cost);
            openList.add(nextNode);
          } else {
            // System.out.println("Not searching "+dest.name()+" because it is already closed.");
          }
        } else {
          if (!isClosed) {
            // get cost of this node
            int cost = thisRoute.getCost();
            // System.out.println("Adding "+dest.name()+" to be searched. Its previous node is
            // "+node.getCurr()+". Its cost is "+cost+". Its total cost is
            // "+(cost+node.getDistToStart()));
            PathNode nextNode = new PathNode(dest, node.getCurr(), node.getDistToStart() + cost);
            openList.add(nextNode);
          } else {
            // System.out.println("Not searching "+dest.name()+" because it is already closed.");
          }
        }
      }
      // close node
      closedList.add(node);
      // System.out.println("Closing: "+ node.getCurr()+"\n");
    }
    return null;
  }
Пример #9
0
 @Override
 public int compare(PathNode to, PathNode from) {
   return (to.getDistToStart() < from.getDistToStart())
       ? -1
       : (to.getDistToStart() == from.getDistToStart()) ? 0 : 1;
 }
Пример #10
0
  /**
   * Converts descendant to child steps.
   *
   * @param ctx query context
   * @param data data reference
   * @return path
   */
  Expr children(final QueryContext ctx, final Data data) {
    // skip path check if no path index exists, or if it is out-of-date
    if (!data.meta.uptodate || data.nspaces.globalNS() == null) return this;

    Path path = this;
    for (int s = 0; s < steps.length; ++s) {
      // don't allow predicates in preceding location steps
      final Step prev = s > 0 ? axisStep(s - 1) : null;
      if (prev != null && prev.preds.length != 0) break;

      // ignore axes other than descendant, or numeric predicates
      final Step curr = axisStep(s);
      if (curr == null || curr.axis != DESC || curr.has(Flag.FCS)) continue;

      // check if child steps can be retrieved for current step
      ArrayList<PathNode> pn = pathNodes(data, s);
      if (pn == null) continue;

      // cache child steps
      final ArrayList<QNm> qnm = new ArrayList<>();
      while (pn.get(0).par != null) {
        QNm nm = new QNm(data.tagindex.key(pn.get(0).name));
        // skip children with prefixes
        if (nm.hasPrefix()) return this;
        for (final PathNode p : pn) {
          if (pn.get(0).name != p.name) nm = null;
        }
        qnm.add(nm);
        pn = PathSummary.parent(pn);
      }
      ctx.compInfo(OPTCHILD, steps[s]);

      // build new steps
      int ts = qnm.size();
      final Expr[] stps = new Expr[ts + steps.length - s - 1];
      for (int t = 0; t < ts; ++t) {
        final Expr[] preds = t == ts - 1 ? ((Preds) steps[s]).preds : new Expr[0];
        final QNm nm = qnm.get(ts - t - 1);
        final NameTest nt =
            nm == null ? new NameTest(false) : new NameTest(nm, Mode.LN, false, null);
        stps[t] = Step.get(info, CHILD, nt, preds);
      }
      while (++s < steps.length) stps[ts++] = steps[s];
      path = get(info, root, stps);
      break;
    }

    // check if the all children in the path exist; don't test with namespaces
    if (data.nspaces.size() == 0) {
      LOOP:
      for (int s = 0; s < path.steps.length; ++s) {
        // only verify child steps; ignore namespaces
        final Step st = path.axisStep(s);
        if (st == null || st.axis != CHILD) break;
        if (st.test.mode == Mode.ALL || st.test.mode == null) continue;
        if (st.test.mode != Mode.LN) break;

        // check if one of the addressed nodes is on the correct level
        final int name = data.tagindex.id(st.test.name.local());
        for (final PathNode pn : data.paths.desc(name, Data.ELEM)) {
          if (pn.level() == s + 1) continue LOOP;
        }
        ctx.compInfo(OPTPATH, path);
        return Empty.SEQ;
      }
    }
    return path;
  }