Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add random generation of NumberValues and BooleanValue
- Loading branch information
1 parent
e21864c
commit ba971a8
Showing
4 changed files
with
330 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
community/random-values/src/main/java/org/neo4j/values/RandomValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
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; | ||
} | ||
} |
183 changes: 183 additions & 0 deletions
183
community/random-values/src/test/java/org/neo4j/values/RandomValueTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
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<Class<? extends NumberValue>> 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<Value> 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<Class<? extends NumberValue>> 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<Value> supplier ) | ||
{ | ||
Set<Value> 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<NumberValue> 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 ) ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters