Skip to content

Commit

Permalink
Refactor JanusGraphHasStep strategy and fix documentation misspell CTR
Browse files Browse the repository at this point in the history
Follow up to #3724

Signed-off-by: Oleksandr Porunov <[email protected]>
  • Loading branch information
porunov committed Jun 7, 2023
1 parent 5b042b4 commit dac1ea1
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 10 deletions.
6 changes: 3 additions & 3 deletions docs/configs/janusgraph-cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,13 +363,13 @@ Configuration options to configure batch queries optimization behavior
| ---- | ---- | ---- | ---- | ---- |
| query.batch.enabled | Whether traversal queries should be batched when executed against the storage backend. This can lead to significant performance improvement if there is a non-trivial latency to the backend. If `false` then all other configuration options under `query.batch` namespace are ignored. | Boolean | true | MASKABLE |
| query.batch.has-step-mode | Properties pre-fetching mode for `has` step. Used only when query.batch.enabled is `true`.<br>Supported modes:<br>- `all_properties` Pre-fetch all vertex properties on any property access<br>- `required_properties_only` Pre-fetch necessary vertex properties for the whole chain of foldable `has` steps<br>- `required_and_next_properties` Prefetch the same properties as with `required_properties_only` mode, but also prefetch
properties which may be needed in the next properties access step like `values`, `properties,` `valueMap`, or `elementMap`.
properties which may be needed in the next properties access step like `values`, `properties,` `valueMap`, `elementMap`, or `propertyMap`.
In case the next step is not one of those properties access steps then this mode behaves same as `required_properties_only`.
In case the next step is one of the properties access steps with limited scope of properties, those properties will be
pre-fetched together in the same multi-query.
In case the next step is one of the properties access steps with unspecified scope of property keys then this mode
behaves same as `all_properties`.<br>- `required_and_next_properties_or_all` Prefetch the same properties as with `required_properties_only`, but in case the next step is not
`values`, `properties,` `valueMap`, or `elementMap` then acts like `all_properties`.<br>- `none` Skips `has` step batch properties pre-fetch optimization.<br> | String | required_and_next_properties | MASKABLE |
behaves same as `all_properties`.<br>- `required_and_next_properties_or_all` Prefetch the same properties as with `required_and_next_properties`, but in case the next step is not
`values`, `properties,` `valueMap`, `elementMap`, or `propertyMap` then acts like `all_properties`.<br>- `none` Skips `has` step batch properties pre-fetch optimization.<br> | String | required_and_next_properties | MASKABLE |
| query.batch.limited | Configure a maximum batch size for queries against the storage backend. This can be used to ensure responsiveness if batches tend to grow very large. The used batch size is equivalent to the barrier size of a preceding `barrier()` step. If a step has no preceding `barrier()`, the default barrier of TinkerPop will be inserted. This option only takes effect if `query.batch.enabled` is `true`. | Boolean | true | MASKABLE |
| query.batch.limited-size | Default batch size (barrier() step size) for queries. This size is applied only for cases where `LazyBarrierStrategy` strategy didn't apply `barrier` step and where user didn't apply barrier step either. This option is used only when `query.batch.limited` is `true`. Notice, value `2147483647` is considered to be unlimited. | Integer | 2500 | MASKABLE |
| query.batch.repeat-step-mode | Batch mode for `repeat` step. Used only when query.batch.enabled is `true`.<br>These modes are controlling how the child steps with batch support are behaving if they placed to the start of the `repeat`, `emit`, or `until` traversals.<br>Supported modes:<br>- `closest_repeat_parent` Child start steps are receiving vertices for batching from the closest `repeat` step parent only.<br>- `all_repeat_parents` Child start steps are receiving vertices for batching from all `repeat` step parents.<br>- `starts_only_of_all_repeat_parents` Child start steps are receiving vertices for batching from the closest `repeat` step parent (both for the parent start and for next iterations) and also from all `repeat` step parents for the parent start. | String | all_repeat_parents | MASKABLE |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,14 @@ public class GraphDatabaseConfiguration {
"- `%s` Pre-fetch all vertex properties on any property access<br>" +
"- `%s` Pre-fetch necessary vertex properties for the whole chain of foldable `has` steps<br>" +
"- `%s` Prefetch the same properties as with `%s` mode, but also prefetch\n" +
"properties which may be needed in the next properties access step like `values`, `properties,` `valueMap`, or `elementMap`.\n" +
"properties which may be needed in the next properties access step like `values`, `properties,` `valueMap`, `elementMap`, or `propertyMap`.\n" +
"In case the next step is not one of those properties access steps then this mode behaves same as `%s`.\n" +
"In case the next step is one of the properties access steps with limited scope of properties, those properties will be\n" +
"pre-fetched together in the same multi-query.\n" +
"In case the next step is one of the properties access steps with unspecified scope of property keys then this mode\n" +
"behaves same as `%s`.<br>"+
"- `%s` Prefetch the same properties as with `%s`, but in case the next step is not\n" +
"`values`, `properties,` `valueMap`, or `elementMap` then acts like `%s`.<br>"+
"`values`, `properties,` `valueMap`, `elementMap`, or `propertyMap` then acts like `%s`.<br>"+
"- `%s` Skips `has` step batch properties pre-fetch optimization.<br>",
MultiQueryHasStepStrategyMode.ALL_PROPERTIES.getConfigName(),
MultiQueryHasStepStrategyMode.REQUIRED_PROPERTIES_ONLY.getConfigName(),
Expand All @@ -350,7 +350,7 @@ public class GraphDatabaseConfiguration {
MultiQueryHasStepStrategyMode.REQUIRED_PROPERTIES_ONLY.getConfigName(),
MultiQueryHasStepStrategyMode.ALL_PROPERTIES.getConfigName(),
MultiQueryHasStepStrategyMode.REQUIRED_AND_NEXT_PROPERTIES_OR_ALL.getConfigName(),
MultiQueryHasStepStrategyMode.REQUIRED_PROPERTIES_ONLY.getConfigName(),
MultiQueryHasStepStrategyMode.REQUIRED_AND_NEXT_PROPERTIES.getConfigName(),
MultiQueryHasStepStrategyMode.ALL_PROPERTIES.getConfigName(),
MultiQueryHasStepStrategyMode.NONE.getConfigName()),
ConfigOption.Type.MASKABLE, MultiQueryHasStepStrategyMode.REQUIRED_AND_NEXT_PROPERTIES.getConfigName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,13 @@ public <Q extends BaseVertexQuery> Q makeQuery(Q query) {
}
},
new FetchQueryBuildFunction() {
private String[] propertyKeys;
@Override
public <Q extends BaseVertexQuery> Q makeQuery(Q query) {
if(!prefetchAllPropertiesRequired && !propertiesToFetch.isEmpty()){
String[] propertyKeys = propertiesToFetch.toArray(new String[0]);
if(!prefetchAllPropertiesRequired){
if(propertyKeys == null){
propertyKeys = propertiesToFetch.toArray(new String[0]);
}
query.keys(propertyKeys);
}
return (Q) ((BasicVertexCentricQueryBuilder) query).profiler(queryProfiler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class JanusGraphHasStepStrategy extends AbstractTraversalStrategy<Travers

private static final JanusGraphHasStepStrategy INSTANCE = new JanusGraphHasStepStrategy();

private static final Set<Class<? extends ProviderOptimizationStrategy>> PRIORS = Collections.singleton(JanusGraphLocalQueryOptimizerStrategy.class);

private JanusGraphHasStepStrategy() {
}

Expand Down Expand Up @@ -146,8 +148,6 @@ public static JanusGraphHasStepStrategy instance() {
return INSTANCE;
}

private static final Set<Class<? extends ProviderOptimizationStrategy>> PRIORS = Collections.singleton(JanusGraphLocalQueryOptimizerStrategy.class);

@Override
public Set<Class<? extends ProviderOptimizationStrategy>> applyPrior() {
return PRIORS;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2023 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.util.datastructures;

import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ExceptionUtilTest {

@Test
public void isCausedBy_WhenExceptionHasNoCause_ReturnsFalse() {
Throwable exception = new RuntimeException("Test exception");
boolean result = ExceptionUtil.isCausedBy(exception, NullPointerException.class);
assertFalse(result);
}

@Test
public void isCausedBy_WhenExceptionCauseMatches_ReturnsTrue() {
NullPointerException cause = new NullPointerException("Test cause");
Throwable exception = new RuntimeException("Test exception", cause);
boolean result = ExceptionUtil.isCausedBy(exception, NullPointerException.class);
assertTrue(result);
}

@Test
public void isCausedBy_WhenExceptionCauseDoesNotMatch_ReturnsFalse() {
IllegalArgumentException cause = new IllegalArgumentException("Test cause");
Throwable exception = new RuntimeException("Test exception", cause);
boolean result = ExceptionUtil.isCausedBy(exception, NullPointerException.class);
assertFalse(result);
}

@Test
public void convertIfInterrupted_WhenRuntimeExceptionNotCausedByInterruptedException_ReturnsSameException() {
RuntimeException exception = new RuntimeException("Test exception");
RuntimeException result = ExceptionUtil.convertIfInterrupted(exception);
assertSame(exception, result);
}

@Test
public void convertIfInterrupted_WhenRuntimeExceptionCausedByInterruptedException_ReturnsTraversalInterruptedException() {
InterruptedException cause = new InterruptedException("Test cause");
RuntimeException exception = new RuntimeException("Test exception", cause);
RuntimeException result = ExceptionUtil.convertIfInterrupted(exception);
assertTrue(result instanceof TraversalInterruptedException);
assertEquals(exception, result.getCause());
}
}

1 comment on commit dac1ea1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: dac1ea1 Previous: 3a7ba53 Ratio
org.janusgraph.JanusGraphSpeedBenchmark.basicAddAndDelete 20859.96076811083 ms/op 20132.68260361965 ms/op 1.04
org.janusgraph.GraphCentricQueryBenchmark.getVertices 1816.142567769631 ms/op 1617.8956294193085 ms/op 1.12
org.janusgraph.MgmtOlapJobBenchmark.runClearIndex 222.5595572521739 ms/op 222.76279991304347 ms/op 1.00
org.janusgraph.MgmtOlapJobBenchmark.runReindex 599.0068900644444 ms/op 541.8996275500001 ms/op 1.11
org.janusgraph.JanusGraphSpeedBenchmark.basicCount 367.1732681465175 ms/op 368.0788711730627 ms/op 1.00
org.janusgraph.CQLMultiQueryHasStepBenchmark.getVerticesFilteredByHasStepWithNonHasStepAfterOut 190952.99126051553 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingEmitRepeatSteps 38612.53095589334 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getAllElementsTraversedFromOuterVertex 21968.607111862624 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithDoubleUnion 833.576925271878 ms/op
org.janusgraph.CQLMultiQueryHasStepBenchmark.getVerticesFilteredByHasStep 193639.64074360297 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getNames 23488.29916608722 ms/op 19643.66567439762 ms/op 1.20
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFilteredByAndStep 846.9237343292218 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFromMultiNestedRepeatStepStartingFromSingleVertex 30740.772159917142 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithCoalesceUsage 772.593280929701 ms/op
org.janusgraph.CQLMultiQueryHasStepBenchmark.getAllPropertiesOfVerticesFilteredByHasStep 237453.85455990594 ms/op
org.janusgraph.CQLMultiQueryHasStepBenchmark.getVerticesFilteredByHasStepInParentStep 197248.65034425672 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getIdToOutVerticesProjection 458.0167254749214 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getNeighborNames 21903.664964059444 ms/op 19824.388658859913 ms/op 1.10
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingRepeatUntilSteps 21460.03266763694 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getAdjacentVerticesLocalCounts 22674.777950415715 ms/op
org.janusgraph.CQLMultiQueryHasStepBenchmark.getSpecificPropertiesOfVerticesFilteredByHasStep 313493.00170404284 ms/op

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.