Beispiel #1
0
        @Override
        public Iterator<TitanElement> execute(final StandardElementQuery query) {
          Iterator<TitanElement> iter = null;
          if (!query.hasIndex()) {
            log.warn(
                "Query requires iterating over all vertices [{}]. For better performance, use indexes",
                query.getCondition());
            if (query.getType() == StandardElementQuery.Type.VERTEX) {
              iter = (Iterator) getVertices().iterator();
            } else if (query.getType() == StandardElementQuery.Type.EDGE) {
              iter = (Iterator) getEdges().iterator();
            } else throw new IllegalArgumentException("Unexpected type: " + query.getType());
            iter =
                Iterators.filter(
                    iter,
                    new Predicate<TitanElement>() {
                      @Override
                      public boolean apply(@Nullable TitanElement element) {
                        return query.matches(element);
                      }
                    });
          } else {
            String index = query.getIndex();
            log.debug("Answering query [{}] with index {}", query, index);
            // Filter out everything not covered by the index
            KeyCondition<TitanKey> condition = query.getCondition();
            // ASSUMPTION: query is an AND of KeyAtom
            Preconditions.checkArgument(condition instanceof KeyAnd);
            Preconditions.checkArgument(condition.hasChildren());
            List<KeyCondition<TitanKey>> newConds = Lists.newArrayList();

            boolean needsFilter = false;
            for (KeyCondition<TitanKey> c : condition.getChildren()) {
              KeyAtom<TitanKey> atom = (KeyAtom<TitanKey>) c;
              if (getGraph()
                      .getIndexInformation(index)
                      .supports(atom.getKey().getDataType(), atom.getRelation())
                  && atom.getKey().hasIndex(index, query.getType().getElementType())
                  && atom.getCondition() != null) {
                newConds.add(atom);
              } else {
                log.debug(
                    "Filtered out atom [{}] from query [{}] because it is not indexed or not covered by the index");
                needsFilter = true;
              }
            }
            Preconditions.checkArgument(
                !newConds.isEmpty(), "Invalid index assignment [%s] to query [%s]", index, query);
            final StandardElementQuery indexQuery;
            if (needsFilter) {
              Preconditions.checkArgument(
                  !newConds.isEmpty(),
                  "Query has been assigned an index [%s] in error: %s",
                  query.getIndex(),
                  query);
              indexQuery =
                  new StandardElementQuery(
                      query.getType(),
                      KeyAnd.of(newConds.toArray(new KeyAtom[newConds.size()])),
                      query.getLimit(),
                      index);
            } else {
              indexQuery = query;
            }
            try {
              iter =
                  Iterators.transform(
                      indexCache
                          .get(
                              indexQuery,
                              new Callable<List<Object>>() {
                                @Override
                                public List<Object> call() throws Exception {
                                  return graph.elementQuery(indexQuery, txHandle);
                                }
                              })
                          .iterator(),
                      new Function<Object, TitanElement>() {
                        @Nullable
                        @Override
                        public TitanElement apply(@Nullable Object id) {
                          Preconditions.checkNotNull(id);
                          if (id instanceof Long) return (TitanVertex) getVertex((Long) id);
                          else if (id instanceof RelationIdentifier)
                            return (TitanElement) getEdge((RelationIdentifier) id);
                          else throw new IllegalArgumentException("Unexpected id type: " + id);
                        }
                      });
            } catch (Exception e) {
              throw new TitanException("Could not call index", e);
            }
            if (needsFilter) {
              iter =
                  Iterators.filter(
                      iter,
                      new Predicate<TitanElement>() {
                        @Override
                        public boolean apply(@Nullable TitanElement element) {
                          return element != null
                              && !element.isRemoved()
                              && !isDeleted(query, element)
                              && query.matches(element);
                        }
                      });
            } else {
              iter =
                  Iterators.filter(
                      iter,
                      new Predicate<TitanElement>() {
                        @Override
                        public boolean apply(@Nullable TitanElement element) {
                          return element != null
                              && !element.isRemoved()
                              && !isDeleted(query, element);
                        }
                      });
            }
          }
          return iter;
        }