You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2018/10/06 16:11:18 UTC
[tinkerpop] 01/01: TINKERPOP-2058 Use `Compare.eq` in
`Contains.within` to ensure equal filter behaviors.
This is an automated email from the ASF dual-hosted git repository.
dkuppitz pushed a commit to branch TINKERPOP-2058
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 72be3549a5e4f99115e9d491e0fc051fff77998a
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Thu Oct 4 07:15:09 2018 -0700
TINKERPOP-2058 Use `Compare.eq` in `Contains.within` to ensure equal filter behaviors.
If the object to be filtered is a number, `Contains` predicates will now scan the provided collection, comparing
each element using `Compare.eq`. For non-numeric values `Contains.within` will still use `collection.contains()`
in order to make use of search-optimized data types (e.g. `Set`).
---
CHANGELOG.asciidoc | 1 +
.../tinkerpop/gremlin/process/traversal/Contains.java | 16 +++++++++++++---
.../gremlin/process/traversal/ContainsTest.java | 2 +-
.../tinkerpop/gremlin/process/traversal/PTest.java | 2 +-
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 06ad72a..cbe60f4 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
This release also includes changes from <<release-3-3-3, 3.3.3>>.
+* Use `Compare.eq` in `Contains` predicates to ensure the same filter behavior for numeric values.
* Added text predicates.
* Removed groovy-sql
* Rewrote `ConnectiveStrategy` to support an arbitrary number of infix notations in a single traversal.
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Contains.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Contains.java
index da46d0b..35a8ca7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Contains.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Contains.java
@@ -18,19 +18,27 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
import java.util.Collection;
import java.util.function.BiPredicate;
/**
* {@link Contains} is a {@link BiPredicate} that evaluates whether the first object is contained within (or not
- * within) the second collection object. For example:
+ * within) the second collection object. If the first object is a number, each element in the second collection
+ * will be compared to the first object using {@link Compare}'s {@code eq} predicate. This will ensure, that numbers
+ * are matched by their value only, ignoring the number type. For example:
* <p/>
* <pre>
* gremlin Contains.within [gremlin, blueprints, furnace] == true
* gremlin Contains.without [gremlin, rexster] == false
* rexster Contains.without [gremlin, blueprints, furnace] == true
+ * 123 Contains.within [1, 2, 3] == false
+ * 100 Contains.within [1L, 10L, 100L] == true
* </pre>
*
+ *
+ *
* @author Pierre De Wilde
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -44,7 +52,9 @@ public enum Contains implements BiPredicate<Object, Collection> {
within {
@Override
public boolean test(final Object first, final Collection second) {
- return second.contains(first);
+ return first instanceof Number
+ ? IteratorUtils.anyMatch(second.iterator(), o -> Compare.eq.test(first, o))
+ : second.contains(first);
}
},
@@ -56,7 +66,7 @@ public enum Contains implements BiPredicate<Object, Collection> {
without {
@Override
public boolean test(final Object first, final Collection second) {
- return !second.contains(first);
+ return !within.test(first, second);
}
};
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/ContainsTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/ContainsTest.java
index 6d9ea38..2ea635d 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/ContainsTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/ContainsTest.java
@@ -43,7 +43,7 @@ public class ContainsTest {
{Contains.within, 10, Collections.emptyList(), false},
{Contains.without, 10, Collections.emptyList(), true},
{Contains.within, 100, Arrays.asList(1, 2, 3, 4, 10), false},
- {Contains.without, 10l, Arrays.asList(1, 2, 3, 4, 10), true}, // no forgiveness
+ {Contains.without, 10L, Arrays.asList(1, 2, 3, 4, 10), false},
{Contains.within, "test", Arrays.asList(1, 2, 3, "test", 10), true},
{Contains.without, "testing", Arrays.asList(1, 2, 3, "test", 10), true}
}));
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PTest.java
index 3494e32..f2e0868 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PTest.java
@@ -127,7 +127,7 @@ public class PTest {
assertEquals(expected, predicate.test(value));
assertNotEquals(expected, predicate.clone().negate().test(value));
assertNotEquals(expected, P.not(predicate.clone()).test(value));
- if (value instanceof Number && !(predicate.biPredicate instanceof Contains)) {
+ if (value instanceof Number) {
assertEquals(expected, predicate.test(((Number) value).longValue()));
assertNotEquals(expected, predicate.clone().negate().test(((Number) value).longValue()));
assertNotEquals(expected, P.not(predicate).test(((Number) value).longValue()));