diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/NodeUpdates.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/NodeUpdates.java index bee6c0c692b2d..92b6b84d9e466 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/NodeUpdates.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/NodeUpdates.java @@ -28,7 +28,7 @@ import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntObjectMap; import org.neo4j.collection.primitive.PrimitiveIntSet; -import org.neo4j.collection.primitive.PrimitiveSortedArraySet; +import org.neo4j.collection.primitive.PrimitiveArrays; import org.neo4j.helpers.collection.Iterables; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.properties.DefinedProperty; @@ -133,12 +133,12 @@ public final long getNodeId() public long[] labelsChanged() { - return PrimitiveSortedArraySet.symmetricDifference( labelsBefore, labelsAfter ); + return PrimitiveArrays.symmetricDifference( labelsBefore, labelsAfter ); } public long[] labelsUnchanged() { - return PrimitiveSortedArraySet.intersect( labelsBefore, labelsAfter ); + return PrimitiveArrays.intersect( labelsBefore, labelsAfter ); } public PrimitiveIntCollection propertiesChanged() diff --git a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveSortedArraySet.java b/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveArrays.java similarity index 85% rename from community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveSortedArraySet.java rename to community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveArrays.java index 19276485032ce..79c6b6768212c 100644 --- a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveSortedArraySet.java +++ b/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveArrays.java @@ -22,15 +22,14 @@ import java.util.Arrays; /** - * Specialized methods for operations on sets represented as sorted primitive arrays. + * Specialized methods for operations on primitive arrays. * - * This class does not contain a complete set of operations for all primitives, but only - * the ones that were needed. Feel free to add specializations on demand, but remember to test. + * For set operations (union, intersect, symmetricDifference), input and output arrays + * are arrays containing unique values in sorted ascending order. */ -public class PrimitiveSortedArraySet +public class PrimitiveArrays { - private static final long[] NO_LONGS = new long[]{}; - private static final int INT_BITS = Integer.BYTES * 8; + private static final long[] EMPTY_LONG_ARRAY = new long[]{}; /** * Compute union of two sets of integers represented as sorted arrays. @@ -50,6 +49,7 @@ public static int[] union( int[] lhs, int[] rhs ) return lhs == null ? rhs : lhs; } + assert isSortedSet( lhs ) && isSortedSet( rhs ); if ( lhs.length < rhs.length ) { return union( rhs, lhs ); @@ -123,9 +123,11 @@ public static long[] intersect( long[] left, long[] right ) { if ( left == null || right == null ) { - return NO_LONGS; + return EMPTY_LONG_ARRAY; } + assert isSortedSet( left ) && isSortedSet( right ); + long uniqueCounts = countUnique( left, right ); if ( uniqueCounts == 0 ) // complete intersection { @@ -133,7 +135,7 @@ public static long[] intersect( long[] left, long[] right ) } if ( right( uniqueCounts ) == right.length || left( uniqueCounts ) == left.length ) // non-intersecting { - return NO_LONGS; + return EMPTY_LONG_ARRAY; } long[] intersect = new long[left.length - left( uniqueCounts )]; @@ -175,10 +177,12 @@ public static long[] symmetricDifference( long[] left, long[] right ) return left == null ? right : left; } + assert isSortedSet( left ) && isSortedSet( right ); + long uniqueCounts = countUnique( left, right ); if ( uniqueCounts == 0 ) // complete intersection { - return NO_LONGS; + return EMPTY_LONG_ARRAY; } long[] difference = new long[left( uniqueCounts ) + right( uniqueCounts )]; @@ -256,12 +260,12 @@ else if ( left[l] < right[r] ) private static long intPair( int left, int right ) { - return ( ((long)left) << INT_BITS ) | right; + return ( ((long)left) << Integer.SIZE ) | right; } private static int left( long pair ) { - return (int)(pair >> INT_BITS); + return (int)(pair >> Integer.SIZE); } private static int right( long pair ) @@ -269,7 +273,25 @@ private static int right( long pair ) return (int)(pair & 0xFFFF_FFFFL); } - private PrimitiveSortedArraySet() + private static boolean isSortedSet( int[] set ) + { + for ( int i = 0; i < set.length - 1; i++ ) + { + assert set[i] < set[i+1] : "Array is not a sorted set: has " + set[i] + " before " + set[i + 1]; + } + return true; + } + + private static boolean isSortedSet( long[] set ) + { + for ( int i = 0; i < set.length - 1; i++ ) + { + assert set[i] < set[i+1] : "Array is not a sorted set: has " + set[i] + " before " + set[i + 1]; + } + return true; + } + + private PrimitiveArrays() { // No instances allowed } } diff --git a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetTest.java b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysTest.java similarity index 52% rename from community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetTest.java rename to community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysTest.java index cceb06d2e582c..28a6a31a6dc32 100644 --- a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetTest.java +++ b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysTest.java @@ -28,7 +28,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; -public class PrimitiveSortedArraySetTest +public class PrimitiveArraysTest { private static final int[] NO_INTS = new int[0]; private static final int[] ONE_INT = new int[]{1}; @@ -40,11 +40,11 @@ public class PrimitiveSortedArraySetTest @Test public void union_shouldHandleNullInput() { - assertThat( PrimitiveSortedArraySet.union( null, null ), nullValue() ); - assertThat( PrimitiveSortedArraySet.union( null, NO_INTS ), equalTo( NO_INTS ) ); - assertThat( PrimitiveSortedArraySet.union( NO_INTS, null ), equalTo( NO_INTS ) ); - assertThat( PrimitiveSortedArraySet.union( null, ONE_INT ), equalTo( ONE_INT ) ); - assertThat( PrimitiveSortedArraySet.union( ONE_INT, null ), equalTo( ONE_INT ) ); + assertThat( PrimitiveArrays.union( null, null ), nullValue() ); + assertThat( PrimitiveArrays.union( null, NO_INTS ), equalTo( NO_INTS ) ); + assertThat( PrimitiveArrays.union( NO_INTS, null ), equalTo( NO_INTS ) ); + assertThat( PrimitiveArrays.union( null, ONE_INT ), equalTo( ONE_INT ) ); + assertThat( PrimitiveArrays.union( ONE_INT, null ), equalTo( ONE_INT ) ); } // intersect() @@ -52,30 +52,30 @@ public void union_shouldHandleNullInput() @Test public void intersect_shouldHandleNullInput() { - assertThat( PrimitiveSortedArraySet.intersect( null, null ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.intersect( null, NO_LONGS ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.intersect( NO_LONGS, null ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.intersect( null, ONE_LONG ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.intersect( ONE_LONG, null ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.intersect( null, null ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.intersect( null, NO_LONGS ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.intersect( NO_LONGS, null ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.intersect( null, ONE_LONG ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.intersect( ONE_LONG, null ), equalTo( NO_LONGS ) ); } @Test public void intersect_shouldHandleNonIntersectingArrays() { - assertThat( PrimitiveSortedArraySet.intersect( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), + assertThat( PrimitiveArrays.intersect( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.intersect( new long[]{14, 15, 16}, new long[]{1, 2, 3} ), + assertThat( PrimitiveArrays.intersect( new long[]{14, 15, 16}, new long[]{1, 2, 3} ), equalTo( NO_LONGS ) ); } @Test public void intersect_shouldHandleIntersectingArrays() { - assertThat( PrimitiveSortedArraySet.intersect( new long[]{1, 2, 3}, new long[]{3, 4, 5} ), + assertThat( PrimitiveArrays.intersect( new long[]{1, 2, 3}, new long[]{3, 4, 5} ), isArray( 3 ) ); - assertThat( PrimitiveSortedArraySet.intersect( new long[]{3, 4, 5}, new long[]{1, 2, 3, 4} ), + assertThat( PrimitiveArrays.intersect( new long[]{3, 4, 5}, new long[]{1, 2, 3, 4} ), isArray( 3, 4 ) ); } @@ -83,10 +83,10 @@ public void intersect_shouldHandleIntersectingArrays() public void intersect_shouldHandleComplexIntersectingArraysWithGaps() { assertThat( - PrimitiveSortedArraySet.intersect( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), + PrimitiveArrays.intersect( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), isArray( 4, 9, 12 ) ); assertThat( - PrimitiveSortedArraySet.intersect( new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19}, new long[]{4, 6, 9, 11, 12, 15} ), + PrimitiveArrays.intersect( new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19}, new long[]{4, 6, 9, 11, 12, 15} ), isArray( 4, 9, 12 ) ); } @@ -95,30 +95,30 @@ public void intersect_shouldHandleComplexIntersectingArraysWithGaps() @Test public void symDiff_shouldHandleNullInput() { - assertThat( PrimitiveSortedArraySet.symmetricDifference( null, null ), equalTo( null ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( null, NO_LONGS ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( NO_LONGS, null ), equalTo( NO_LONGS ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( null, ONE_LONG ), equalTo( ONE_LONG ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( ONE_LONG, null ), equalTo( ONE_LONG ) ); + assertThat( PrimitiveArrays.symmetricDifference( null, null ), equalTo( null ) ); + assertThat( PrimitiveArrays.symmetricDifference( null, NO_LONGS ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.symmetricDifference( NO_LONGS, null ), equalTo( NO_LONGS ) ); + assertThat( PrimitiveArrays.symmetricDifference( null, ONE_LONG ), equalTo( ONE_LONG ) ); + assertThat( PrimitiveArrays.symmetricDifference( ONE_LONG, null ), equalTo( ONE_LONG ) ); } @Test public void symDiff_shouldHandleNonIntersectingArrays() { - assertThat( PrimitiveSortedArraySet.symmetricDifference( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), + assertThat( PrimitiveArrays.symmetricDifference( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), isArray( 1, 2, 3, 4, 5, 6 ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( new long[]{14, 15, 16}, new long[]{1, 2, 3} ), + assertThat( PrimitiveArrays.symmetricDifference( new long[]{14, 15, 16}, new long[]{1, 2, 3} ), isArray( 1, 2, 3, 14, 15, 16 ) ); } @Test public void symDiff_shouldHandleIntersectingArrays() { - assertThat( PrimitiveSortedArraySet.symmetricDifference( new long[]{1, 2, 3}, new long[]{3, 4, 5} ), + assertThat( PrimitiveArrays.symmetricDifference( new long[]{1, 2, 3}, new long[]{3, 4, 5} ), isArray( 1, 2, 4, 5 ) ); - assertThat( PrimitiveSortedArraySet.symmetricDifference( new long[]{3, 4, 5}, new long[]{1, 2, 3, 4} ), + assertThat( PrimitiveArrays.symmetricDifference( new long[]{3, 4, 5}, new long[]{1, 2, 3, 4} ), isArray( 1, 2, 5 ) ); } @@ -126,10 +126,12 @@ public void symDiff_shouldHandleIntersectingArrays() public void symDiff_shouldHandleComplexIntersectingArraysWithGaps() { assertThat( - PrimitiveSortedArraySet.symmetricDifference( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), + PrimitiveArrays + .symmetricDifference( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), isArray( 2, 3, 6, 7, 8, 11, 15, 16, 19 ) ); assertThat( - PrimitiveSortedArraySet.symmetricDifference( new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19}, new long[]{4, 6, 9, 11, 12, 15} ), + PrimitiveArrays + .symmetricDifference( new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19}, new long[]{4, 6, 9, 11, 12, 15} ), isArray( 2, 3, 6, 7, 8, 11, 15, 16, 19 ) ); } @@ -139,39 +141,39 @@ public void symDiff_shouldHandleComplexIntersectingArraysWithGaps() public void shouldCountUnique() { assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), + PrimitiveArrays.countUnique( new long[]{1, 2, 3}, new long[]{4, 5, 6} ), isIntPair( 3, 3 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{1, 2, 3}, new long[]{3, 6} ), + PrimitiveArrays.countUnique( new long[]{1, 2, 3}, new long[]{3, 6} ), isIntPair( 2, 1 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{1, 2, 3}, new long[]{3} ), + PrimitiveArrays.countUnique( new long[]{1, 2, 3}, new long[]{3} ), isIntPair( 2, 0 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{3}, new long[]{1, 2, 3} ), + PrimitiveArrays.countUnique( new long[]{3}, new long[]{1, 2, 3} ), isIntPair( 0, 2 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{3}, new long[]{3} ), + PrimitiveArrays.countUnique( new long[]{3}, new long[]{3} ), isIntPair( 0, 0 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{3, 6, 8}, new long[]{} ), + PrimitiveArrays.countUnique( new long[]{3, 6, 8}, new long[]{} ), isIntPair( 3, 0 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{}, new long[]{3, 6, 8} ), + PrimitiveArrays.countUnique( new long[]{}, new long[]{3, 6, 8} ), isIntPair( 0, 3 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{}, new long[]{} ), + PrimitiveArrays.countUnique( new long[]{}, new long[]{} ), isIntPair( 0, 0 ) ); assertThat( - PrimitiveSortedArraySet.countUnique( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), + PrimitiveArrays.countUnique( new long[]{4, 6, 9, 11, 12, 15}, new long[]{2, 3, 4, 7, 8, 9, 12, 16, 19} ), isIntPair( 3, 6 ) ); } diff --git a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetUnionTest.java b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysUnionTest.java similarity index 95% rename from community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetUnionTest.java rename to community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysUnionTest.java index 07a19950f2eac..497a16a384e7b 100644 --- a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveSortedArraySetUnionTest.java +++ b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveArraysUnionTest.java @@ -27,10 +27,10 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertSame; -import static org.neo4j.collection.primitive.PrimitiveSortedArraySet.union; +import static org.neo4j.collection.primitive.PrimitiveArrays.union; @RunWith( Parameterized.class ) -public class PrimitiveSortedArraySetUnionTest +public class PrimitiveArraysUnionTest { @Parameterized.Parameters( name = "{0}" ) public static Iterable parameters() @@ -55,7 +55,7 @@ public static Iterable parameters() private final int[] rhs; private final int[] expected; - public PrimitiveSortedArraySetUnionTest( Input input ) + public PrimitiveArraysUnionTest( Input input ) { this.lhs = input.lhs; this.rhs = input.rhs; diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java index 31ff50ec9b8ac..da768668337ef 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java @@ -50,7 +50,7 @@ import static java.lang.String.format; import static java.util.Collections.emptyList; -import static org.neo4j.collection.primitive.PrimitiveSortedArraySet.union; +import static org.neo4j.collection.primitive.PrimitiveArrays.union; import static org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException.Phase.VALIDATION; class PropertyExistenceEnforcer