not even compiled.
Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/0594fd07 Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/0594fd07 Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/0594fd07 Branch: refs/heads/master Commit: 0594fd0760f80d8e51dacd1b8e3549002328edac Parents: 7ddc276 Author: DO YUNG YOON <[email protected]> Authored: Wed Jul 12 11:56:00 2017 +0900 Committer: DO YUNG YOON <[email protected]> Committed: Wed Jul 12 11:56:00 2017 +0900 ---------------------------------------------------------------------- .../io/tinkerpop/optimize/HasStepFolder.java | 203 +++++++++++++++++++ .../core/io/tinkerpop/optimize/S2GraphStep.java | 4 +- .../tinkerpop/optimize/S2GraphStepStrategy.java | 29 +-- .../optimize/S2GraphTraversalUtil.java | 41 ++++ .../tinkerpop/optimize/S2GraphVertexStep.java | 128 ++++++++++++ .../s2graph/core/index/IndexProvider.scala | 39 +++- .../s2graph/core/index/IndexProviderTest.scala | 3 +- .../core/tinkerpop/S2GraphProvider.scala | 1 + 8 files changed, 422 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/HasStepFolder.java ---------------------------------------------------------------------- diff --git a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/HasStepFolder.java b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/HasStepFolder.java new file mode 100644 index 0000000..116f95d --- /dev/null +++ b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/HasStepFolder.java @@ -0,0 +1,203 @@ +package org.apache.s2graph.core.io.tinkerpop.optimize; + +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.Step; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder; +import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging; +import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.ElementValueComparator; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer; +import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; +import org.javatuples.Pair; + +import java.util.*; +import java.util.stream.Collectors; + +public interface HasStepFolder<S, E> extends Step<S, E> { + + void addAll(Iterable<HasContainer> hasContainers); + + void orderBy(String key, Order order); + + void setLimit(int limit); + + int getLimit(); + +// static boolean validJanusGraphHas(HasContainer has) { +// if (has.getPredicate() instanceof AndP) { +// final List<? extends P<?>> predicates = ((AndP<?>) has.getPredicate()).getPredicates(); +// return !predicates.stream().filter(p->!validJanusGraphHas(new HasContainer(has.getKey(), p))).findAny().isPresent(); +// } else { +// return JanusGraphPredicate.Converter.supports(has.getBiPredicate()); +// } +// } + +// static boolean validJanusGraphHas(Iterable<HasContainer> has) { +// for (HasContainer h : has) { +// if (!validJanusGraphHas(h)) return false; +// } +// return true; +// } + +// static boolean validJanusGraphOrder(OrderGlobalStep ostep, Traversal rootTraversal, +// boolean isVertexOrder) { +// for (Pair<Traversal.Admin<Object, Comparable>, Comparator<Comparable>> comp : (List<Pair<Traversal.Admin<Object, Comparable>, Comparator<Comparable>>>) ostep.getComparators()) { +// if (!(comp.getValue1() instanceof ElementValueComparator)) return false; +// ElementValueComparator evc = (ElementValueComparator) comp.getValue1(); +// if (!(evc.getValueComparator() instanceof Order)) return false; +// +// JanusGraphTransaction tx = JanusGraphTraversalUtil.getTx(rootTraversal.asAdmin()); +// String key = evc.getPropertyKey(); +// PropertyKey pkey = tx.getPropertyKey(key); +// if (pkey == null || !(Comparable.class.isAssignableFrom(pkey.dataType()))) return false; +// if (isVertexOrder && pkey.cardinality() != Cardinality.SINGLE) return false; +// } +// return true; +// } + + static void foldInIds(final HasStepFolder s2graphStep, final Traversal.Admin<?, ?> traversal) { + Step<?, ?> currentStep = s2graphStep.getNextStep(); + while (true) { + if (currentStep instanceof HasContainerHolder) { + Set<Object> ids = new HashSet<>(); + final GraphStep graphStep = (GraphStep) s2graphStep; + for (final HasContainer hasContainer : ((HasContainerHolder) currentStep).getHasContainers()) { + if (GraphStep.processHasContainerIds(graphStep, hasContainer)) { + currentStep.getLabels().forEach(s2graphStep::addLabel); + if (!ids.isEmpty()) { + // intersect ids (shouldn't this be handled in TP GraphStep.processHasContainerIds?) + ids.stream().filter(id -> Arrays.stream(graphStep.getIds()).noneMatch(id::equals)) + .collect(Collectors.toSet()).forEach(ids::remove); + if (ids.isEmpty()) break; + } else { + Arrays.stream(graphStep.getIds()).forEach(ids::add); + } + } + // clear ids to allow folding in ids from next HasContainer if relevant + graphStep.clearIds(); + } + graphStep.addIds(ids); + if (!ids.isEmpty()) traversal.removeStep(currentStep); + } + else if (currentStep instanceof IdentityStep) { + // do nothing, has no impact + } else if (currentStep instanceof NoOpBarrierStep) { + // do nothing, has no impact + } else { + break; + } + currentStep = currentStep.getNextStep(); + } + } + + static void foldInHasContainer(final HasStepFolder s2graphStep, final Traversal.Admin<?, ?> traversal) { + Step<?, ?> currentStep = s2graphStep.getNextStep(); + while (true) { + if (currentStep instanceof HasContainerHolder) { + Iterable<HasContainer> containers = ((HasContainerHolder) currentStep).getHasContainers(); +// if (validJanusGraphHas(containers)) { + s2graphStep.addAll(containers); + currentStep.getLabels().forEach(s2graphStep::addLabel); + traversal.removeStep(currentStep); +// } + } else if (currentStep instanceof IdentityStep) { + // do nothing, has no impact + } else if (currentStep instanceof NoOpBarrierStep) { + // do nothing, has no impact + } else { + break; + } + currentStep = currentStep.getNextStep(); + } + } + +// public static boolean addLabeledStepAsIdentity(Step<?,?> currentStep, final Traversal.Admin<?, ?> traversal) { +// if (currentStep.getLabel().isPresent()) { +// final IdentityStep identityStep = new IdentityStep<>(traversal); +// identityStep.setLabel(currentStep.getLabel().get()); +// TraversalHelper.insertAfterStep(identityStep, currentStep, traversal); +// return true; +// } else return false; +// } + + static void foldInOrder(final HasStepFolder s2graphStep, final Traversal.Admin<?, ?> traversal, + final Traversal<?, ?> rootTraversal, boolean isVertexOrder) { + Step<?, ?> currentStep = s2graphStep.getNextStep(); + OrderGlobalStep<?, ?> lastOrder = null; + while (true) { + if (currentStep instanceof OrderGlobalStep) { + if (lastOrder != null) { //Previous orders are rendered irrelevant by next order (since re-ordered) + lastOrder.getLabels().forEach(s2graphStep::addLabel); + traversal.removeStep(lastOrder); + } + lastOrder = (OrderGlobalStep) currentStep; + } else if (currentStep instanceof IdentityStep) { + // do nothing, can be skipped + } else if (currentStep instanceof HasStep) { + // do nothing, can be skipped + } else if (currentStep instanceof NoOpBarrierStep) { + // do nothing, can be skipped + } else { + break; + } + currentStep = currentStep.getNextStep(); + } + + if (lastOrder != null && lastOrder instanceof OrderGlobalStep) { +// if (validJanusGraphOrder(lastOrder, rootTraversal, isVertexOrder)) { + //Add orders to HasStepFolder + for (Pair<Traversal.Admin<Object, Comparable>, Comparator<Comparable>> comp : (List<Pair<Traversal.Admin<Object, Comparable>, Comparator<Comparable>>>) ((OrderGlobalStep) lastOrder).getComparators()) { + ElementValueComparator evc = (ElementValueComparator) comp.getValue1(); + s2graphStep.orderBy(evc.getPropertyKey(), (Order) evc.getValueComparator()); + } + lastOrder.getLabels().forEach(s2graphStep::addLabel); + traversal.removeStep(lastOrder); +// } + } + } + +// static void splitAndP(final List<HasContainer> hasContainers, final Iterable<HasContainer> has) { +// has.forEach(hasContainer -> { +// if (hasContainer.getPredicate() instanceof AndP) { +// for (final P<?> predicate : ((AndP<?>) hasContainer.getPredicate()).getPredicates()) { +// hasContainers.add(new HasContainer(hasContainer.getKey(), predicate)); +// } +// } else +// hasContainers.add(hasContainer); +// }); +// } + + class OrderEntry { + + public final String key; + public final Order order; + + public OrderEntry(String key, Order order) { + this.key = key; + this.order = order; + } + } + +// static <E extends Ranging> void foldInRange(final HasStepFolder s2graphStep, final Traversal.Admin<?, ?> traversal) { +// Step<?, ?> nextStep = S2GraphTraversalUtil.getNextNonIdentityStep(s2graphStep); +// +// if (nextStep instanceof RangeGlobalStep) { +// RangeGlobalStep range = (RangeGlobalStep) nextStep; +// int limit = 10; +// s2graphStep.setLimit(limit); +// if (range.getLowRange() == 0) { //Range can be removed since there is no offset +// nextStep.getLabels().forEach(s2graphStep::addLabel); +// traversal.removeStep(nextStep); +// } +// } +// } + + +} http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStep.java ---------------------------------------------------------------------- diff --git a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStep.java b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStep.java index 384a88b..d494995 100644 --- a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStep.java +++ b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStep.java @@ -65,8 +65,8 @@ public class S2GraphStep<S, E extends Element> extends GraphStep<S, E> { // full scan String queryString = IndexProvider$.MODULE$.buildQueryString(hasContainers); - - List<String> ids = graph.indexProvider().fetchIds(queryString); + Boolean isVertex = Vertex.class.isAssignableFrom(this.returnClass); + List<String> ids = graph.indexProvider().fetchIds(queryString, isVertex); return (Iterator) (Vertex.class.isAssignableFrom(this.returnClass) ? graph.vertices(ids) : graph.edges(ids)); }); } http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStepStrategy.java ---------------------------------------------------------------------- diff --git a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStepStrategy.java b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStepStrategy.java index 15d7699..e30a502 100644 --- a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStepStrategy.java +++ b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphStepStrategy.java @@ -6,6 +6,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep; import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Graph; + +import java.util.Iterator; public class S2GraphStepStrategy extends AbstractTraversalStrategy<TraversalStrategy.ProviderOptimizationStrategy> implements TraversalStrategy.ProviderOptimizationStrategy { @@ -27,21 +31,18 @@ public class S2GraphStepStrategy extends AbstractTraversalStrategy<TraversalStra TraversalHelper.replaceStep(originalGraphStep, (Step) s2GraphStep, traversal); - } else { - //Make sure that any provided "start" elements are instantiated in the current transaction -// Object[] ids = originalGraphStep.getIds(); -// ElementUtils.verifyArgsMustBeEitherIdorElement(ids); -// if (ids[0] instanceof Element) { -// //GraphStep constructor ensures that the entire array is elements -// final Object[] elementIds = new Object[ids.length]; -// for (int i = 0; i < ids.length; i++) { -// elementIds[i] = ((Element) ids[i]).id(); -// } -// originalGraphStep.setIteratorSupplier(() -> (Iterator) (originalGraphStep.returnsVertex() ? -// ((Graph) originalGraphStep.getTraversal().getGraph().get()).vertices(elementIds) : -// ((Graph) originalGraphStep.getTraversal().getGraph().get()).edges(elementIds))); -// } + Object[] ids = originalGraphStep.getIds(); + if (ids[0] instanceof Element) { + //GraphStep constructor ensures that the entire array is elements + final Object[] elementIds = new Object[ids.length]; + for (int i = 0; i < ids.length; i++) { + elementIds[i] = ((Element) ids[i]).id(); + } + originalGraphStep.setIteratorSupplier(() -> (Iterator) (originalGraphStep.returnsVertex() ? + ((Graph) originalGraphStep.getTraversal().getGraph().get()).vertices(elementIds) : + ((Graph) originalGraphStep.getTraversal().getGraph().get()).edges(elementIds))); + } } }); } http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphTraversalUtil.java ---------------------------------------------------------------------- diff --git a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphTraversalUtil.java b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphTraversalUtil.java new file mode 100644 index 0000000..72f6999 --- /dev/null +++ b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphTraversalUtil.java @@ -0,0 +1,41 @@ +package org.apache.s2graph.core.io.tinkerpop.optimize; + +import org.apache.s2graph.core.S2Vertex; +import org.apache.tinkerpop.gremlin.process.traversal.Step; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep; +import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.wrapped.WrappedVertex; + +import java.util.Optional; + +public class S2GraphTraversalUtil { + + public static S2Vertex getS2Vertex(Element v) { + while (v instanceof WrappedVertex) { + v = ((WrappedVertex<Vertex>) v).getBaseVertex(); + } + if (v instanceof S2Vertex) { + return (S2Vertex) v; + } else throw new IllegalArgumentException("Expected traverser of JanusGraph vertex but found: " + v); + } + + public static S2Vertex getS2Vertex(Traverser<? extends Element> traverser) { + return getS2Vertex(traverser.get()); + } + + + public static Step getNextNonIdentityStep(final Step start) { + Step currentStep = start.getNextStep(); + //Skip over identity steps + while (currentStep instanceof IdentityStep) currentStep = currentStep.getNextStep(); + return currentStep; + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphVertexStep.java ---------------------------------------------------------------------- diff --git a/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphVertexStep.java b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphVertexStep.java new file mode 100644 index 0000000..a637617 --- /dev/null +++ b/s2core/src/main/java/org/apache/s2graph/core/io/tinkerpop/optimize/S2GraphVertexStep.java @@ -0,0 +1,128 @@ +package org.apache.s2graph.core.io.tinkerpop.optimize; + + +import org.apache.s2graph.core.Query; +import org.apache.s2graph.core.S2Vertex; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.Profiling; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer; +import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException; +import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.StringFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +//public class S2GraphVertexStep<E extends Element> extends VertexStep<E> implements HasStepFolder<Vertex, E>, Profiling { +// +// public S2GraphVertexStep(VertexStep<E> originalStep) { +// super(originalStep.getTraversal(), originalStep.getReturnClass(), originalStep.getDirection(), originalStep.getEdgeLabels()); +// originalStep.getLabels().forEach(this::addLabel); +// this.hasContainers = new ArrayList<>(); +// this.limit = Integer.MAX_VALUE; +// } +// +// private boolean initialized = false; +// private Map<S2Vertex, Iterable<? extends Element>> multiQueryResults = null; +// +// +// public Query makeQuery(Query query) { +// query.labels(getEdgeLabels()); +// query.direction(getDirection()); +// for (HasContainer condition : hasContainers) { +// query.has(condition.getKey(), JanusGraphPredicate.Converter.convert(condition.getBiPredicate()), condition.getValue()); +// } +// for (OrderEntry order : orders) query.orderBy(order.key, order.order); +// if (limit != BaseQuery.NO_LIMIT) query.limit(limit); +// ((BasicVertexCentricQueryBuilder) query).profiler(queryProfiler); +// return query; +// } +// +// @SuppressWarnings("deprecation") +// private void initialize() { +// assert !initialized; +// initialized = true; +// +// if (!starts.hasNext()) throw FastNoSuchElementException.instance(); +// JanusGraphMultiVertexQuery mquery = JanusGraphTraversalUtil.getTx(traversal).multiQuery(); +// List<Traverser.Admin<Vertex>> vertices = new ArrayList<>(); +// starts.forEachRemaining(v -> { +// vertices.add(v); +// mquery.addVertex(v.get()); +// }); +// starts.add(vertices.iterator()); +// assert vertices.size() > 0; +// makeQuery(mquery); +// +// multiQueryResults = (Vertex.class.isAssignableFrom(getReturnClass())) ? mquery.vertices() : mquery.edges(); +// +// } +// +// @Override +// protected Traverser.Admin<E> processNextStart() { +// if (!initialized) initialize(); +// return super.processNextStart(); +// } +// +// @Override +// protected Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser) { +// JanusGraphVertexQuery query = makeQuery((JanusGraphTraversalUtil.getJanusGraphVertex(traverser)).query()); +// return (Vertex.class.isAssignableFrom(getReturnClass())) ? query.vertices().iterator() : query.edges().iterator(); +// } +// +// @Override +// public void reset() { +// super.reset(); +// this.initialized = false; +// } +// +// @Override +// public S2GraphVertexStep<E> clone() { +// final S2GraphVertexStep<E> clone = (S2GraphVertexStep<E>) super.clone(); +// clone.initialized = false; +// return clone; +// } +// +// +// private final List<HasContainer> hasContainers; +// private int limit = Integer.MAX_VALUE; +// private List<OrderEntry> orders = new ArrayList<>(); +// +// +// @Override +// public void addAll(Iterable<HasContainer> has) { +// HasStepFolder.splitAndP(hasContainers, has); +// } +// +// @Override +// public void orderBy(String key, Order order) { +// orders.add(new OrderEntry(key, order)); +// } +// +// @Override +// public void setLimit(int limit) { +// this.limit = limit; +// } +// +// @Override +// public int getLimit() { +// return this.limit; +// } +// +// @Override +// public String toString() { +// return this.hasContainers.isEmpty() ? super.toString() : StringFactory.stepString(this, this.hasContainers); +// } +// +// @Override +// public void setMetrics(MutableMetrics metrics) { +//// queryProfiler = new TP3ProfileWrapper(metrics); +// } +//} + http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/main/scala/org/apache/s2graph/core/index/IndexProvider.scala ---------------------------------------------------------------------- diff --git a/s2core/src/main/scala/org/apache/s2graph/core/index/IndexProvider.scala b/s2core/src/main/scala/org/apache/s2graph/core/index/IndexProvider.scala index d3878af..c8b2ebb 100644 --- a/s2core/src/main/scala/org/apache/s2graph/core/index/IndexProvider.scala +++ b/s2core/src/main/scala/org/apache/s2graph/core/index/IndexProvider.scala @@ -8,14 +8,16 @@ import org.apache.lucene.queryparser.classic.QueryParser import org.apache.lucene.search.IndexSearcher import org.apache.lucene.store.RAMDirectory import org.apache.s2graph.core.io.Conversions -import org.apache.s2graph.core.{EdgeId, S2Edge} +import org.apache.s2graph.core.{EdgeId, S2Edge, S2Vertex} import org.apache.s2graph.core.mysqls._ import org.apache.s2graph.core.types.InnerValLike import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer import play.api.libs.json.Json object IndexProvider { - val edgeIdField = "_edgeId_" + val vidField = "_vid_" + val eidField = "_eid_" + def apply(config: Config): IndexProvider = { val indexProviderType = "lucene" // if (config.hasPath("index.provider")) config.getString("index.provider") else "lucene" @@ -36,10 +38,12 @@ object IndexProvider { trait IndexProvider { //TODO: Seq nee do be changed into stream - def fetchIds(queryString: String): java.util.List[String] + def fetchIds(queryString: String, isVertex: Boolean = true): java.util.List[String] - def mutateEdges(edges: Seq[S2Edge]): Seq[Boolean] + def mutateVertices(vertices: Seq[S2Vertex]): Seq[Boolean] + def mutateEdges(edges: Seq[S2Edge]): Seq[Boolean] +` def shutdown(): Unit } @@ -51,11 +55,26 @@ class LuceneIndexProvider(config: Config) extends IndexProvider { val indexConfig = new IndexWriterConfig(analyzer) val writer = new IndexWriter(directory, indexConfig) + override def mutateVertices(vertices: Seq[S2Vertex]): Seq[Boolean] = { + vertices.map { vertex => + val doc = new Document() + val id = vertex.id.toString() + doc.add(new StringField(vidField, id, Field.Store.YES)) + + vertex.properties.foreach { case (dim, value) => + doc.add(new TextField(dim, value.toString, Field.Store.YES)) + } + writer.addDocument(doc) + } + writer.commit() + vertices.map(_ => true) + } + override def mutateEdges(edges: Seq[S2Edge]): Seq[Boolean] = { edges.map { edge => val doc = new Document() - val edgeIdString = edge.edgeId.toString - doc.add(new StringField(edgeIdField, edgeIdString, Field.Store.YES)) + val id = edge.edgeId.toString + doc.add(new StringField(eidField, id, Field.Store.YES)) edge.properties.foreach { case (dim, value) => doc.add(new TextField(dim, value.toString, Field.Store.YES)) @@ -66,9 +85,10 @@ class LuceneIndexProvider(config: Config) extends IndexProvider { edges.map(_ => true) } - override def fetchIds(queryString: String): java.util.List[String] = { + override def fetchIds(queryString: String, isVertex: Boolean = true): java.util.List[String] = { + val field = if (isVertex) vidField else eidField val ids = new java.util.ArrayList[String] - val q = new QueryParser(edgeIdField, analyzer).parse(queryString) + val q = new QueryParser(field, analyzer).parse(queryString) val hitsPerPage = 10 val reader = DirectoryReader.open(directory) val searcher = new IndexSearcher(reader) @@ -77,7 +97,7 @@ class LuceneIndexProvider(config: Config) extends IndexProvider { docs.scoreDocs.foreach { scoreDoc => val document = searcher.doc(scoreDoc.doc) - ids.add(document.get(edgeIdField)) + ids.add(document.get(field)) } reader.close() @@ -87,4 +107,5 @@ class LuceneIndexProvider(config: Config) extends IndexProvider { override def shutdown(): Unit = { writer.close() } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/test/scala/org/apache/s2graph/core/index/IndexProviderTest.scala ---------------------------------------------------------------------- diff --git a/s2core/src/test/scala/org/apache/s2graph/core/index/IndexProviderTest.scala b/s2core/src/test/scala/org/apache/s2graph/core/index/IndexProviderTest.scala index 70f7c3c..e9150e9 100644 --- a/s2core/src/test/scala/org/apache/s2graph/core/index/IndexProviderTest.scala +++ b/s2core/src/test/scala/org/apache/s2graph/core/index/IndexProviderTest.scala @@ -25,7 +25,8 @@ class IndexProviderTest extends IntegrateCommon { edges.foreach(e => logger.debug(s"[Edge]: $e")) indexProvider.mutateEdges(edges) - val edgeIds = indexProvider.fetchIds("time: 10") + import scala.collection.JavaConversions._ + val edgeIds = indexProvider.fetchIds("time: 10", isVertex = false) edgeIds.foreach { edgeId => logger.debug(s"[EdgeId]: $edgeId") http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/0594fd07/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala ---------------------------------------------------------------------- diff --git a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala index 87eac0e..1d06e46 100644 --- a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala +++ b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala @@ -37,6 +37,7 @@ import org.apache.tinkerpop.gremlin.{AbstractGraphProvider, LoadGraphWith} import scala.collection.JavaConverters._ object S2GraphProvider { + val Implementation: Set[Class[_]] = Set( classOf[S2Edge], classOf[S2Vertex],
