Beispiel #1
0
        @Override
        public Iterator<TitanElement> getNew(final StandardElementQuery query) {
          Preconditions.checkArgument(
              query.getType() == StandardElementQuery.Type.VERTEX
                  || query.getType() == StandardElementQuery.Type.EDGE);
          if (query.getType() == StandardElementQuery.Type.VERTEX && hasModifications()) {
            // Collect all keys from the query - ASSUMPTION: query is an AND of KeyAtom
            final Set<TitanKey> keys = Sets.newHashSet();
            KeyAtom<TitanKey> standardIndexKey = null;
            for (KeyCondition<TitanKey> cond : query.getCondition().getChildren()) {
              KeyAtom<TitanKey> atom = (KeyAtom<TitanKey>) cond;
              if (atom.getRelation() == Cmp.EQUAL && isVertexIndexProperty(atom.getKey()))
                standardIndexKey = atom;
              keys.add(atom.getKey());
            }
            Iterator<TitanVertex> vertices;
            if (standardIndexKey == null) {
              Set<TitanVertex> vertexSet = Sets.newHashSet();
              for (TitanRelation r :
                  addedRelations.getView(
                      new Predicate<InternalRelation>() {
                        @Override
                        public boolean apply(@Nullable InternalRelation relation) {
                          return keys.contains(relation.getType());
                        }
                      })) {
                vertexSet.add(((TitanProperty) r).getVertex());
              }
              for (TitanRelation r : deletedRelations.values()) {
                if (keys.contains(r.getType())) {
                  TitanVertex v = ((TitanProperty) r).getVertex();
                  if (!v.isRemoved()) vertexSet.add(v);
                }
              }
              vertices = vertexSet.iterator();
            } else {
              vertices =
                  Iterators.transform(
                      newVertexIndexEntries
                          .get(standardIndexKey.getCondition(), standardIndexKey.getKey())
                          .iterator(),
                      new Function<TitanProperty, TitanVertex>() {
                        @Nullable
                        @Override
                        public TitanVertex apply(@Nullable TitanProperty o) {
                          return o.getVertex();
                        }
                      });
            }

            return (Iterator)
                Iterators.filter(
                    vertices,
                    new Predicate<TitanVertex>() {
                      @Override
                      public boolean apply(@Nullable TitanVertex vertex) {
                        return query.matches(vertex);
                      }
                    });
          } else if (query.getType() == StandardElementQuery.Type.EDGE
              && !addedRelations.isEmpty()) {
            return (Iterator)
                addedRelations
                    .getView(
                        new Predicate<InternalRelation>() {
                          @Override
                          public boolean apply(@Nullable InternalRelation relation) {
                            return (relation instanceof TitanEdge)
                                && !relation.isHidden()
                                && query.matches(relation);
                          }
                        })
                    .iterator();
          } else throw new IllegalArgumentException("Unexpected type: " + query.getType());
        }
Beispiel #2
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;
        }
Beispiel #3
0
        @Override
        public Iterator<TitanRelation> execute(final VertexCentricQuery query) {
          if (query.getVertex().isNew()) return Iterators.emptyIterator();

          final EdgeSerializer edgeSerializer = graph.getEdgeSerializer();
          FittedSliceQuery sq = edgeSerializer.getQuery(query);
          final boolean fittedQuery = sq.isFitted();
          final InternalVertex v = query.getVertex();
          final boolean needsFiltering = !sq.isFitted() || !deletedRelations.isEmpty();
          if (needsFiltering && sq.hasLimit())
            sq = new FittedSliceQuery(sq, QueryUtil.updateLimit(sq.getLimit(), 1.1));

          Iterable<TitanRelation> result = null;
          double limitMultiplier = 1.0;
          int previousDiskSize = 0;
          boolean finished;
          do {
            finished = true;
            Iterable<Entry> iter = null;

            if (v instanceof CacheVertex) {
              CacheVertex cv = (CacheVertex) v;
              iter =
                  ((CacheVertex) v)
                      .loadRelations(
                          sq,
                          new Retriever<SliceQuery, List<Entry>>() {
                            @Override
                            public List<Entry> get(SliceQuery query) {
                              return graph.edgeQuery(v.getID(), query, txHandle);
                            }
                          });
            } else {
              iter = graph.edgeQuery(v.getID(), sq, txHandle);
            }
            result =
                Iterables.transform(
                    iter,
                    new Function<Entry, TitanRelation>() {
                      @Nullable
                      @Override
                      public TitanRelation apply(@Nullable Entry entry) {
                        return edgeSerializer.readRelation(v, entry);
                      }
                    });
            if (needsFiltering) {
              result =
                  Iterables.filter(
                      result,
                      new Predicate<TitanRelation>() {
                        @Override
                        public boolean apply(@Nullable TitanRelation relation) {
                          // Filter out updated and deleted relations
                          return (relation == ((InternalRelation) relation).it()
                                  && !deletedRelations.containsKey(Long.valueOf(relation.getID())))
                              && (fittedQuery || query.matches(relation));
                        }
                      });
            }
            // Determine termination
            if (needsFiltering && query.hasLimit()) {
              if (!IterablesUtil.sizeLargerOrEqualThan(result, query.getLimit())) {
                int currentDiskSize = IterablesUtil.size(iter);
                if (currentDiskSize > previousDiskSize) {
                  finished = false;
                  previousDiskSize = currentDiskSize;
                  limitMultiplier *= 2;
                  sq =
                      new FittedSliceQuery(
                          sq, QueryUtil.updateLimit(sq.getLimit(), limitMultiplier));
                }
              }
            }
          } while (!finished);

          return result.iterator();
        }