Skip to content

Commit d21d942

Browse files
committed
Preserve BulkSet in P
Doesn't address all the problems here with performance but for now just trying to preserve BulkSet for within/without which can happen with: aggregate('x')...where(without('x')) CTR
1 parent f80c374 commit d21d942

File tree

3 files changed

+116
-3
lines changed

3 files changed

+116
-3
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
2525
2626
This release also includes changes from <<release-3-7-6, 3.7.6>>.
2727
28+
* Preserved `BulkSet` when given to 'P'.
2829
* Fixed bug in Gremlin orderability semantics for `OffsetDateTime`.
2930
* Fixed bug in Javascript translation for UUID.
3031
* Fixed bug in pre-repeat() `emit()/until()` where `emit()` and `until()` traversers weren't added to the results.

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.commons.collections.CollectionUtils;
2222
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
23+
import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
2324
import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
2425
import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
2526

@@ -71,7 +72,12 @@ public P(final PBiPredicate<V, V> biPredicate, final GValue<V> value) {
7172
protected P(final PBiPredicate<V, V> biPredicate, final Collection<V> literals, final Map<String, V> variables, final boolean isCollection) {
7273
this.biPredicate = biPredicate;
7374
this.variables.putAll(variables);
74-
this.literals = new ArrayList<>(literals);
75+
if (literals instanceof BulkSet) {
76+
this.literals = new BulkSet<>();
77+
this.literals.addAll(literals);
78+
} else {
79+
this.literals = new ArrayList<>(literals);
80+
}
7581
this.isCollection = isCollection;
7682
}
7783

@@ -89,7 +95,16 @@ public PBiPredicate<V, V> getBiPredicate() {
8995
*/
9096
public V getValue() {
9197
if (isCollection) {
92-
Collection<V> values = this.literals.stream().collect(Collectors.toList());
98+
if (this.variables.isEmpty()) return (V) this.literals;
99+
100+
final Collection<V> values;
101+
if (this.literals instanceof BulkSet) {
102+
values = new BulkSet<>();
103+
values.addAll(this.literals);
104+
} else {
105+
values = new ArrayList<>(this.literals);
106+
}
107+
93108
values.addAll(this.variables.values());
94109
return (V) values;
95110
} else if (!this.literals.isEmpty()) {
@@ -113,7 +128,7 @@ public void setValue(final V value) {
113128
} else if (value instanceof Collection) {
114129
isCollection = true;
115130
if (((Collection<?>) value).stream().anyMatch(v -> v instanceof GValue)) {
116-
this.literals = new ArrayList<>();
131+
this.literals = (value instanceof BulkSet) ? new BulkSet<>() : new ArrayList<>();
117132
for (Object v : ((Collection<?>) value)) {
118133
// Separate variables and literals
119134
if (v instanceof GValue) {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package org.apache.tinkerpop.gremlin.process.traversal;
2+
3+
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
4+
import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
5+
import org.junit.Test;
6+
7+
import java.util.Collection;
8+
import java.util.Collections;
9+
import java.util.Map;
10+
11+
import static org.junit.Assert.assertEquals;
12+
import static org.junit.Assert.assertTrue;
13+
14+
/**
15+
* Test class for {@link P} with {@link BulkSet} literals ensure that if a {@link BulkSet} is used as a literal,
16+
* it is preserved in the {@link P} object's value, and that the {@link P} object can handle {@link BulkSet} literals
17+
* with {@link GValue} elements correctly. You get a {@link BulkSet} in {@link P} when you have some Gremlin like:
18+
* {@code aggreate('x')...where(within('x'))}.
19+
*/
20+
public class PBulkSetTest {
21+
22+
@Test
23+
public void shouldPreserveBulkSetInGetValue() {
24+
final BulkSet<String> bulkSet = new BulkSet<>();
25+
bulkSet.add("a", 2);
26+
bulkSet.add("b", 1);
27+
28+
final P p = P.within(bulkSet);
29+
final Object value = p.getValue();
30+
31+
assertTrue("Value should be a BulkSet but was " + value.getClass().getName(), value instanceof BulkSet);
32+
assertEquals(bulkSet, value);
33+
assertEquals(3, ((BulkSet) value).size());
34+
assertEquals(2L, ((BulkSet) value).get("a"));
35+
}
36+
37+
@Test
38+
public void shouldPreserveBulkSetInSetValueWithGValues() {
39+
final BulkSet<Object> bulkSet = new BulkSet<>();
40+
bulkSet.add("a", 2);
41+
bulkSet.add(GValue.of("x", "b"), 1);
42+
43+
final P p = P.within(Collections.emptyList());
44+
p.setValue(bulkSet);
45+
46+
final Object value = p.getValue();
47+
// Currently this will fail and return an ArrayList (or a List from the stream)
48+
assertTrue("Value should be a BulkSet but was " + (value == null ? "null" : value.getClass().getName()), value instanceof BulkSet);
49+
assertEquals(3, ((BulkSet) value).size());
50+
assertEquals(2L, ((BulkSet) value).get("a"));
51+
}
52+
53+
@Test
54+
public void shouldCloneBulkSetInGetValueWithVariables() {
55+
final BulkSet<Object> bulkSet = new BulkSet<>();
56+
bulkSet.add("a", 2);
57+
58+
// Subclass to access protected constructor and merge literals and variables
59+
final P p = new PSubWithVars(Compare.eq, bulkSet, Collections.singletonMap("var1", "b"));
60+
61+
final Object value = p.getValue();
62+
assertTrue("Value should be a BulkSet but was " + (value == null ? "null" : value.getClass().getName()), value instanceof BulkSet);
63+
assertEquals(3, ((BulkSet) value).size());
64+
assertEquals(2L, ((BulkSet) value).get("a"));
65+
assertEquals(1L, ((BulkSet) value).get("b"));
66+
67+
// Ensure original bulkSet was not modified (p.getValue() should have cloned)
68+
assertEquals(2, bulkSet.size());
69+
assertEquals(2L, bulkSet.get("a"));
70+
assertEquals(0L, bulkSet.get("b"));
71+
}
72+
73+
@Test
74+
public void shouldPreserveBulkSetInProtectedConstructor() throws Exception {
75+
final BulkSet<String> bulkSet = new BulkSet<>();
76+
bulkSet.add("a", 2);
77+
78+
final P p = new PSub(Compare.eq, bulkSet);
79+
80+
final Object value = p.getValue();
81+
assertTrue("Value should be a BulkSet but was " + (value == null ? "null" : value.getClass().getName()), value instanceof BulkSet);
82+
assertEquals(2, ((BulkSet) value).size());
83+
assertEquals(2L, ((BulkSet) value).get("a"));
84+
}
85+
86+
private static class PSub extends P {
87+
public PSub(final PBiPredicate biPredicate, final Collection literals) {
88+
super(biPredicate, literals, Collections.emptyMap(), true);
89+
}
90+
}
91+
92+
private static class PSubWithVars extends P {
93+
public PSubWithVars(final PBiPredicate biPredicate, final Collection literals, final Map variables) {
94+
super(biPredicate, literals, variables, true);
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)