Skip to content

Commit

Permalink
Lazy load relations and cached query optimization
Browse files Browse the repository at this point in the history
Signed-off-by: ntisseyre <[email protected]>
  • Loading branch information
ntisseyre committed Apr 10, 2024
1 parent cd91c52 commit 803680e
Show file tree
Hide file tree
Showing 19 changed files with 724 additions and 18 deletions.
3 changes: 3 additions & 0 deletions docs/basics/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ following aspects of a transaction to be configured:
cache access during read operations. Doesn't have any effect if database
level cache was disabled via config `cache.db-cache`.

- `lazyLoadRelations()` - Set lazy-load for all properties and edges of the vertex: ids and values are deserialized upon demand.
When enabled, it can have a boost on large-scale read operations, if only certain types of relations are being read from the vertex.

Once, the desired configuration options have been specified, the new
transaction is started via `start()` which returns a
`JanusGraphTransaction`.
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
import org.janusgraph.graphdb.database.util.StaleIndexRecordUtil;
import org.janusgraph.graphdb.internal.ElementCategory;
import org.janusgraph.graphdb.internal.ElementLifeCycle;
import org.janusgraph.graphdb.internal.InternalElement;
import org.janusgraph.graphdb.internal.InternalRelationType;
import org.janusgraph.graphdb.internal.InternalVertex;
import org.janusgraph.graphdb.internal.Order;
Expand All @@ -129,7 +130,6 @@
import org.janusgraph.graphdb.query.condition.PredicateCondition;
import org.janusgraph.graphdb.query.index.IndexSelectionUtil;
import org.janusgraph.graphdb.query.profile.QueryProfiler;
import org.janusgraph.graphdb.relations.AbstractEdge;
import org.janusgraph.graphdb.relations.RelationIdentifier;
import org.janusgraph.graphdb.relations.StandardEdge;
import org.janusgraph.graphdb.relations.StandardVertexProperty;
Expand Down Expand Up @@ -425,7 +425,7 @@ public void testUpdatePropertyPropThenRemoveVertex() {
public void testUpdateEdgePropertyThenRemoveEdge() {
initializeGraphWithVerticesAndEdges();
// normal edge
AbstractEdge edge = (AbstractEdge) graph.traversal().E().has("_e", 1).next();
InternalElement edge = (InternalElement) graph.traversal().E().has("_e", 1).next();
assertTrue(ElementLifeCycle.isLoaded(edge.getLifeCycle()));
Object id = edge.id();

Expand All @@ -452,7 +452,7 @@ public void testUpdateEdgePropertyThenRemoveEdge() {
public void testUpdateForkEdgePropertyThenRemoveEdge() {
initializeGraphWithVerticesAndEdges();
// fork edge
AbstractEdge edge = (AbstractEdge) graph.traversal().E().has("_e", 2).next();
InternalElement edge = (InternalElement) graph.traversal().E().has("_e", 2).next();
assertTrue(ElementLifeCycle.isLoaded(edge.getLifeCycle()));
Object id = edge.id();

Expand Down Expand Up @@ -483,7 +483,7 @@ public void testUpdateForkEdgePropertyThenRemoveEdge() {
@Test
public void testUpdateForkEdgePropertyThenFindEdgeById() {
initializeGraphWithVerticesAndEdges();
AbstractEdge edge = (AbstractEdge) graph.traversal().E().has("_e", 2).next();
InternalElement edge = (InternalElement) graph.traversal().E().has("_e", 2).next();
Object id = edge.id();

edge.property("_e", -2);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.janusgraph.graphdb.database;

import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.AdjacentVertexFilterOptimizerStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.AdjacentVertexHasIdOptimizerStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.AdjacentVertexHasUniquePropertyOptimizerStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.AdjacentVertexIsOptimizerStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphHasStepStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphIoRegistrationStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphLocalQueryOptimizerStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphMixedIndexAggStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphMixedIndexCountStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphMultiQueryStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphStepStrategy;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphUnusedMultiQueryRemovalStrategy;
import org.janusgraph.graphdb.transaction.StandardTransactionBuilder;

public class LazyLoadGraphTest extends StandardJanusGraph {

static {
TraversalStrategies graphStrategies =
TraversalStrategies.GlobalCache.getStrategies(Graph.class)
.clone()
.addStrategies(AdjacentVertexFilterOptimizerStrategy.instance(),
AdjacentVertexHasIdOptimizerStrategy.instance(),
AdjacentVertexIsOptimizerStrategy.instance(),
AdjacentVertexHasUniquePropertyOptimizerStrategy.instance(),
JanusGraphLocalQueryOptimizerStrategy.instance(),
JanusGraphHasStepStrategy.instance(),
JanusGraphMultiQueryStrategy.instance(),
JanusGraphUnusedMultiQueryRemovalStrategy.instance(),
JanusGraphMixedIndexAggStrategy.instance(),
JanusGraphMixedIndexCountStrategy.instance(),
JanusGraphStepStrategy.instance(),
JanusGraphIoRegistrationStrategy.instance());

//Register with cache
TraversalStrategies.GlobalCache.registerStrategies(LazyLoadGraphTest.class, graphStrategies);
}

public LazyLoadGraphTest(GraphDatabaseConfiguration configuration) {
super(configuration);
}

@Override
public StandardTransactionBuilder buildTransaction() {
return (StandardTransactionBuilder) new StandardTransactionBuilder(getConfiguration(), this)
.lazyLoadRelations();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2024 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.janusgraph.core;

import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.janusgraph.diskstorage.Entry;
import org.janusgraph.graphdb.internal.InternalRelation;
import org.janusgraph.graphdb.internal.InternalRelationType;
import org.janusgraph.graphdb.internal.InternalVertex;
import org.janusgraph.graphdb.transaction.StandardJanusGraphTx;

public class JanusGraphLazyEdge extends JanusGraphLazyRelation implements JanusGraphEdge {

public JanusGraphLazyEdge(InternalRelation janusGraphRelation,
final InternalVertex vertex,
final StandardJanusGraphTx tx,
final InternalRelationType type) {
super(janusGraphRelation, vertex, tx, type);
}

public JanusGraphLazyEdge(Entry dataEntry,
final InternalVertex vertex,
final StandardJanusGraphTx tx,
final InternalRelationType type) {
super(dataEntry, vertex, tx, type);
}

private JanusGraphEdge loadEdge() {
assert this.isEdge();
return (JanusGraphEdge) this.loadValue();
}

@Override
public JanusGraphVertex vertex(Direction dir) {
return this.loadEdge().vertex(dir);
}

@Override
public JanusGraphVertex otherVertex(Vertex vertex) {
return this.loadEdge().otherVertex(vertex);
}
}
Loading

0 comments on commit 803680e

Please sign in to comment.