diff --git a/community/pom.xml b/community/pom.xml
index cb9a661f770e2..b675b8a01b154 100644
--- a/community/pom.xml
+++ b/community/pom.xml
@@ -58,6 +58,7 @@
dbms
command-line
procedure-compiler
+ random-values
values
ssl
spatial-index
diff --git a/community/random-values/src/main/java/org/neo4j/values/RandomValue.java b/community/random-values/src/main/java/org/neo4j/values/RandomValue.java
new file mode 100644
index 0000000000000..26591da64e5cc
--- /dev/null
+++ b/community/random-values/src/main/java/org/neo4j/values/RandomValue.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2002-2018 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.values;
+
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.neo4j.values.storable.BooleanValue;
+import org.neo4j.values.storable.ByteValue;
+import org.neo4j.values.storable.DoubleValue;
+import org.neo4j.values.storable.FloatValue;
+import org.neo4j.values.storable.IntValue;
+import org.neo4j.values.storable.LongValue;
+import org.neo4j.values.storable.NumberValue;
+import org.neo4j.values.storable.ShortValue;
+import org.neo4j.values.storable.Values;
+
+import static java.lang.Math.abs;
+import static org.neo4j.values.storable.Values.byteValue;
+import static org.neo4j.values.storable.Values.doubleValue;
+import static org.neo4j.values.storable.Values.floatValue;
+import static org.neo4j.values.storable.Values.intValue;
+import static org.neo4j.values.storable.Values.longValue;
+import static org.neo4j.values.storable.Values.shortValue;
+
+public class RandomValue
+{
+ //TODO make possible to use SplittableRandom
+ private final Random random;
+
+ public RandomValue()
+ {
+ this( ThreadLocalRandom.current() );
+ }
+
+ public RandomValue( Random random )
+ {
+ this.random = random;
+ }
+
+ LongValue nextLongValue()
+ {
+ return longValue( random.nextLong() );
+ }
+
+ LongValue nextLongValue( long bound )
+ {
+ return longValue( nextLong( bound ) );
+ }
+
+ public LongValue nextLongValue( long lower, long upper )
+ {
+ return longValue( nextLong( (upper - lower) + 1L ) + lower );
+ }
+
+ public BooleanValue nextBooleanValue()
+ {
+ return Values.booleanValue( random.nextBoolean() );
+ }
+
+ public IntValue nextIntValue( int bound )
+ {
+ return intValue( random.nextInt( bound ) );
+ }
+
+ public IntValue nextIntValue()
+ {
+ return intValue( random.nextInt() );
+ }
+
+ public ShortValue nextShortValue( short bound )
+ {
+ return shortValue( (short) random.nextInt( bound ) );
+ }
+
+ public ShortValue nextShortValue()
+ {
+ return shortValue( (short) random.nextInt() );
+ }
+
+ public ByteValue nextByteValue( byte bound )
+ {
+ return byteValue( (byte) random.nextInt( bound ) );
+ }
+
+ public ByteValue nextByteValue()
+ {
+ return byteValue( (byte) random.nextInt() );
+ }
+
+ public FloatValue nextFloatValue()
+ {
+ return floatValue( random.nextFloat() );
+ }
+
+ public DoubleValue nextDoubleValue()
+ {
+ return doubleValue( random.nextFloat() );
+ }
+
+ public NumberValue nextNumberValue()
+ {
+ int type = random.nextInt( 6 );
+ switch ( type )
+ {
+ case 0:
+ return nextByteValue();
+ case 1:
+ return nextShortValue();
+ case 2:
+ return nextIntValue();
+ case 3:
+ return nextLongValue();
+ case 4:
+ return nextFloatValue();
+ case 5:
+ return nextDoubleValue();
+ default:
+ throw new IllegalArgumentException( "Unknown value type " + type );
+ }
+ }
+
+ private long nextLong( long bound )
+ {
+ return abs( random.nextLong() ) % bound;
+ }
+}
diff --git a/community/random-values/src/test/java/org/neo4j/values/RandomValueTest.java b/community/random-values/src/test/java/org/neo4j/values/RandomValueTest.java
new file mode 100644
index 0000000000000..105bc4eb0eae3
--- /dev/null
+++ b/community/random-values/src/test/java/org/neo4j/values/RandomValueTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2002-2018 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.values;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import org.neo4j.values.storable.ByteValue;
+import org.neo4j.values.storable.DoubleValue;
+import org.neo4j.values.storable.FloatValue;
+import org.neo4j.values.storable.IntValue;
+import org.neo4j.values.storable.LongValue;
+import org.neo4j.values.storable.NumberValue;
+import org.neo4j.values.storable.ShortValue;
+import org.neo4j.values.storable.Value;
+
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.neo4j.values.storable.Values.ZERO_INT;
+import static org.neo4j.values.storable.Values.longValue;
+
+public class RandomValueTest
+{
+ private static final int ITERATIONS = 100;
+ private final RandomValue randomValue = new RandomValue();
+ private final static byte BOUND = 100;
+ private final static LongValue UPPER = longValue( BOUND );
+ private static final Set> NUMBER_TYPES = new HashSet<>( Arrays.asList(
+ LongValue.class, IntValue.class, ShortValue.class, ByteValue.class, FloatValue.class,
+ DoubleValue.class ) );
+
+ @Test
+ public void nextLongValueUnbounded()
+ {
+ checkDistribution( randomValue::nextLongValue );
+ }
+
+ @Test
+ public void nextLongValueBounded()
+ {
+ checkDistribution( () -> randomValue.nextLongValue( BOUND ) );
+ checkBounded( () -> randomValue.nextLongValue( BOUND ) );
+ }
+
+ @Test
+ public void nextLongValueBoundedAndShifted()
+ {
+ Set values = new HashSet<>();
+ for ( int i = 0; i < ITERATIONS; i++ )
+ {
+ LongValue value = randomValue.nextLongValue( 1337, 1337 + BOUND );
+ assertThat( value, notNullValue() );
+ assertThat( value.compareTo( longValue( 1337 ) ), greaterThanOrEqualTo( 0 ) );
+ assertThat( value.toString(), value.compareTo( longValue( 1337 + BOUND ) ), lessThanOrEqualTo( 0 ) );
+ values.add( value );
+ }
+
+ assertThat( values.size(), greaterThan( 1 ) );
+ }
+
+ @Test
+ public void nextBooleanValue()
+ {
+ checkDistribution( randomValue::nextBooleanValue );
+ }
+
+ @Test
+ public void nextIntValueUnbounded()
+ {
+ checkDistribution( randomValue::nextIntValue );
+ }
+
+ @Test
+ public void nextIntValueBounded()
+ {
+ checkDistribution( () -> randomValue.nextIntValue( BOUND ) );
+ checkBounded( () -> randomValue.nextIntValue( BOUND ) );
+ }
+
+ @Test
+ public void nextShortValueUnbounded()
+ {
+ checkDistribution( randomValue::nextShortValue );
+ }
+
+ @Test
+ public void nextShortValueBounded()
+ {
+ checkDistribution( () -> randomValue.nextShortValue( BOUND ) );
+ checkBounded( () -> randomValue.nextShortValue( BOUND ) );
+ }
+
+
+ @Test
+ public void nextByteValueUnbounded()
+ {
+ checkDistribution( randomValue::nextByteValue );
+ }
+
+ @Test
+ public void nextByteValueBounded()
+ {
+ checkDistribution( () -> randomValue.nextByteValue( BOUND ) );
+ checkBounded( () -> randomValue.nextByteValue( BOUND ) );
+ }
+
+ @Test
+ public void nextFloatValue()
+ {
+ checkDistribution( randomValue::nextFloatValue );
+ }
+
+ @Test
+ public void nextDoubleValue()
+ {
+ checkDistribution( randomValue::nextDoubleValue );
+ }
+
+ @Test
+ public void nextNumberValue()
+ {
+ HashSet> seen = new HashSet<>( NUMBER_TYPES );
+
+ for ( int i = 0; i < ITERATIONS; i++ )
+ {
+ NumberValue numberValue = randomValue.nextNumberValue();
+ assertThat( NUMBER_TYPES, hasItem( numberValue.getClass() ));
+ seen.remove( numberValue.getClass() );
+ }
+ assertThat( seen, empty() );
+ }
+
+ private void checkDistribution( Supplier supplier )
+ {
+ Set values = new HashSet<>();
+ for ( int i = 0; i < ITERATIONS; i++ )
+ {
+ Value value = supplier.get();
+ assertThat( value, notNullValue() );
+ values.add( value );
+ }
+
+ assertThat( values.size(), greaterThan( 1 ) );
+ }
+
+ private void checkBounded( Supplier supplier )
+ {
+ for ( int i = 0; i < ITERATIONS; i++ )
+ {
+ NumberValue value = supplier.get();
+ assertThat( value, notNullValue() );
+ assertThat( value.compareTo( ZERO_INT ), greaterThanOrEqualTo( 0 ) );
+ assertThat( value.compareTo( UPPER ), lessThan( 0 ) );
+ }
+ }
+}
\ No newline at end of file
diff --git a/community/values/src/main/java/org/neo4j/values/storable/NumberValue.java b/community/values/src/main/java/org/neo4j/values/storable/NumberValue.java
index d58548193d5b6..c2986d1ac96d8 100644
--- a/community/values/src/main/java/org/neo4j/values/storable/NumberValue.java
+++ b/community/values/src/main/java/org/neo4j/values/storable/NumberValue.java
@@ -45,9 +45,9 @@ public static double safeCastFloatingPoint( String name, AnyValue value, double
public abstract long longValue();
- abstract int compareTo( IntegralValue other );
+ public abstract int compareTo( IntegralValue other );
- abstract int compareTo( FloatingPointValue other );
+ public abstract int compareTo( FloatingPointValue other );
@Override
int unsafeCompareTo( Value otherValue )