diff --git a/community/common/src/test/java/org/neo4j/test/Randoms.java b/community/common/src/test/java/org/neo4j/test/Randoms.java deleted file mode 100644 index 62fd443454a5f..0000000000000 --- a/community/common/src/test/java/org/neo4j/test/Randoms.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * 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.test; - -import java.lang.reflect.Array; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetTime; -import java.time.Period; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAmount; -import java.util.List; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Consumer; - -import static java.lang.Integer.bitCount; -import static java.lang.Math.abs; -import static java.time.ZoneOffset.UTC; -import static java.time.temporal.ChronoUnit.DAYS; - -/** - * Set of useful randomizing utilities, for example randomizing a string or property value of random type and value. - */ -public class Randoms -{ - public interface Configuration - { - int stringMinLength(); - - int stringMaxLength(); - - int stringCharacterSets(); - - int arrayMinLength(); - - int arrayMaxLength(); - } - - public static class Default implements Configuration - { - @Override - public int stringMinLength() - { - return 5; - } - - @Override - public int stringMaxLength() - { - return 20; - } - - @Override - public int stringCharacterSets() - { - return CSA_LETTERS_AND_DIGITS; - } - - @Override - public int arrayMinLength() - { - return 1; - } - - @Override - public int arrayMaxLength() - { - return 10; - } - } - - public static final Configuration DEFAULT = new Default(); - - public static final int CS_LOWERCASE_LETTERS = 0x1; - public static final int CS_UPPERCASE_LETTERS = 0x2; - public static final int CS_DIGITS = 0x3; - public static final int CS_SYMBOLS = 0x4; - - public static final int CSA_LETTERS = CS_LOWERCASE_LETTERS | CS_UPPERCASE_LETTERS; - public static final int CSA_LETTERS_AND_DIGITS = CSA_LETTERS | CS_DIGITS; - - public static final long NANOS_PER_SECOND = 1_000_000_000L; - - private final Random random; - private final Configuration configuration; - - public Randoms() - { - this( ThreadLocalRandom.current(), DEFAULT ); - } - - public Randoms( Random random, Configuration configuration ) - { - this.random = random; - this.configuration = configuration; - } - - public Randoms fork( Configuration configuration ) - { - return new Randoms( random, configuration ); - } - - public Random random() - { - return random; - } - - public int intBetween( int min, int max ) - { - return min + random.nextInt( max - min + 1 ); - } - - public String string() - { - return string( configuration.stringMinLength(), configuration.stringMaxLength(), - configuration.stringCharacterSets() ); - } - - public String string( int minLength, int maxLength, int characterSets ) - { - char[] chars = new char[intBetween( minLength, maxLength )]; - for ( int i = 0; i < chars.length; i++ ) - { - chars[i] = character( characterSets ); - } - return String.valueOf( chars ); - } - - public Object array() - { - int length = intBetween( configuration.arrayMinLength(), configuration.arrayMaxLength() ); - byte componentType = propertyType( false ); - Object itemType = propertyValue( componentType ); - Object array = Array.newInstance( itemType.getClass(), length ); - for ( int i = 0; i < length; i++ ) - { - Array.set( array, i, propertyValue( componentType ) ); - } - return array; - } - - public char character( int characterSets ) - { - int setCount = bitCount( characterSets ); - while ( true ) - { - int bit = 1 << random.nextInt( setCount ); - if ( (characterSets & bit) != 0 ) - { - switch ( bit ) - { - case CS_LOWERCASE_LETTERS: - return (char) intBetween( 'a', 'z' ); - case CS_UPPERCASE_LETTERS: - return (char) intBetween( 'A', 'Z' ); - case CS_DIGITS: - return (char) intBetween( '0', '9' ); - case CS_SYMBOLS: - return symbol(); - default: - throw new IllegalArgumentException( "Unknown character set " + bit ); - } - } - } - } - - @SuppressWarnings( "unchecked" ) - public T[] selection( T[] among, int min, int max, boolean allowDuplicates ) - { - assert min <= max; - int diff = min == max ? 0 : random.nextInt( max - min ); - int length = min + diff; - T[] result = (T[]) Array.newInstance( among.getClass().getComponentType(), length ); - for ( int i = 0; i < length; i++ ) - { - while ( true ) - { - T candidate = among( among ); - if ( !allowDuplicates && contains( result, candidate ) ) - { // Try again - continue; - } - result[i] = candidate; - break; - } - } - return result; - } - - private static boolean contains( T[] array, T contains ) - { - for ( T item : array ) - { - if ( nullSafeEquals( item, contains ) ) - { - return true; - } - } - return false; - } - - private static boolean nullSafeEquals( T first, T other ) - { - return first == null ? other == null : first.equals( other ); - } - - public T among( T[] among ) - { - return among[random.nextInt( among.length )]; - } - - public T among( List among ) - { - return among.get( random.nextInt( among.size() ) ); - } - - public void among( List among, Consumer action ) - { - if ( !among.isEmpty() ) - { - T item = among( among ); - action.accept( item ); - } - } - - public Number numberPropertyValue() - { - int type = random.nextInt( 6 ); - switch ( type ) - { - case 0: - return (byte) random.nextInt(); - case 1: - return (short) random.nextInt(); - case 2: - return random.nextInt(); - case 3: - return random.nextLong(); - case 4: - return random.nextFloat(); - case 5: - return random.nextDouble(); - default: - throw new IllegalArgumentException( "Unknown value type " + type ); - } - } - - public Object propertyValue() - { - return propertyValue( propertyType( true ) ); - } - - private byte propertyType( boolean allowArrays ) - { - return (byte) random.nextInt( allowArrays ? 17 : 16 ); - } - - // TODO add Point also - private Object propertyValue( byte type ) - { - switch ( type ) - { - case 0: - return random.nextBoolean(); - case 1: - return (byte) random.nextInt(); - case 2: - return (short) random.nextInt(); - case 3: - return character( CSA_LETTERS_AND_DIGITS ); - case 4: - return random.nextInt(); - case 5: - return random.nextLong(); - case 6: - return random.nextFloat(); - case 7: - return random.nextDouble(); - case 8: - return randomDateTime(); - case 9: - return randomTime(); - case 10: - return randomDate(); - case 11: - return randomLocalDateTime(); - case 12: - return randomLocalTime(); - case 13: - return randomPeriod(); - case 14: - return randomDuration(); - case 15: - return string(); - case 16: - return array(); - default: - throw new IllegalArgumentException( "Unknown value type " + type ); - } - } - - public OffsetTime randomTime() - { - return OffsetTime.ofInstant( randomInstant(), UTC); - } - - public LocalDateTime randomLocalDateTime() - { - return LocalDateTime.ofInstant( randomInstant(), UTC); - } - - public LocalDate randomDate() - { - return LocalDate.ofEpochDay( nextLong( LocalDate.MIN.toEpochDay(), LocalDate.MAX.toEpochDay() ) ); - } - - public LocalTime randomLocalTime() - { - return LocalTime.ofNanoOfDay( nextLong( LocalTime.MIN.toNanoOfDay(), LocalTime.MAX.toNanoOfDay() ) ); - } - - private Instant randomInstant() - { - return Instant.ofEpochSecond( nextLong( LocalDateTime.MIN.toEpochSecond( UTC ), LocalDateTime.MAX.toEpochSecond( UTC ) ), - nextLong( NANOS_PER_SECOND ) ); - } - - public ZonedDateTime randomDateTime() - { - return ZonedDateTime.ofInstant( randomInstant(), UTC ); - } - - public TemporalAmount randomPeriod() - { - // Based on Java period (years, months and days) - return Period.of( random.nextInt(), random.nextInt( 12 ), random.nextInt( 28 ) ); - } - - public TemporalAmount randomDuration() - { - // Based on java duration (seconds) - return Duration.of( nextLong( DAYS.getDuration().getSeconds() ), ChronoUnit.SECONDS ); - } - - private char symbol() - { - int range = random.nextInt( 5 ); - switch ( range ) - { - case 0: - return (char) intBetween( 33, 47 ); - case 1: - return (char) intBetween( 58, 64 ); - case 2: - return (char) intBetween( 91, 96 ); - case 3: - return (char) intBetween( 123, 126 ); - case 4: - return ' '; - default: - throw new IllegalArgumentException( "Unknown symbol range " + range ); - } - } - - public long nextLong() - { - return random.nextLong(); - } - - /** - * Returns a random long between 0 and a positive number - * - * @param bound upper bound, exclusive - */ - public long nextLong( long bound ) - { - return abs( random.nextLong() ) % bound; - } - - /** - * Returns a random long between two positive numbers. - * @param origin lower bound, inclusive - * @param bound upper bound, inclusive - */ - public long nextLong( long origin, long bound ) - { - return nextLong( (bound - origin) + 1L ) + origin; - } - - public boolean nextBoolean() - { - return random.nextBoolean(); - } - - public int nextInt( int bound ) - { - return random.nextInt( bound ); - } - - public int nextInt() - { - return random.nextInt(); - } - - public void nextBytes( byte[] data ) - { - random.nextBytes( data ); - } - - public float nextFloat() - { - return random.nextFloat(); - } -} diff --git a/community/common/src/test/java/org/neo4j/test/rule/RandomRule.java b/community/common/src/test/java/org/neo4j/test/rule/RandomRule.java deleted file mode 100644 index 76940e2ace729..0000000000000 --- a/community/common/src/test/java/org/neo4j/test/rule/RandomRule.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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.test.rule; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.MultipleFailureException; -import org.junit.runners.model.Statement; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.List; -import java.util.Random; -import java.util.function.Consumer; - -import org.neo4j.helpers.Exceptions; -import org.neo4j.test.Randoms; -import org.neo4j.test.Randoms.Configuration; - -import static java.lang.System.currentTimeMillis; - -/** - * Like a {@link Random} but guarantees to include the seed with the test failure, which helps - * greatly in debugging. - * - * Available methods directly on this class include those found in {@link Randoms} and the basic ones in {@link Random}. - */ -public class RandomRule implements TestRule -{ - private long seed; - private boolean hasGlobalSeed; - private Random random; - private Randoms randoms; - private Configuration config = Randoms.DEFAULT; - - public RandomRule withConfiguration( Randoms.Configuration config ) - { - this.config = config; - return this; - } - - public RandomRule withSeedForAllTests( long seed ) - { - hasGlobalSeed = true; - this.seed = seed; - return this; - } - - public Configuration configuration() - { - return config; - } - - @Override - public Statement apply( final Statement base, Description description ) - { - return new Statement() - { - @Override - public void evaluate() throws Throwable - { - if ( !hasGlobalSeed ) - { - Seed methodSeed = description.getAnnotation( Seed.class ); - if ( methodSeed != null ) - { - seed = methodSeed.value(); - } - else - { - seed = currentTimeMillis(); - } - } - reset(); - try - { - base.evaluate(); - } - catch ( Throwable t ) - { - if ( t instanceof MultipleFailureException ) - { - MultipleFailureException multipleFailures = (MultipleFailureException) t; - for ( Throwable failure : multipleFailures.getFailures() ) - { - enhanceFailureWithSeed( failure ); - } - } - else - { - enhanceFailureWithSeed( t ); - } - throw t; - } - } - - private void enhanceFailureWithSeed( Throwable t ) - { - Exceptions.withMessage( t, t.getMessage() + ": random seed used:" + seed + "L" ); - } - }; - } - - // ============================ - // Methods from Random - // ============================ - - public void nextBytes( byte[] bytes ) - { - random.nextBytes( bytes ); - } - - public boolean nextBoolean() - { - return random.nextBoolean(); - } - - public double nextDouble() - { - return random.nextDouble(); - } - - public float nextFloat() - { - return random.nextFloat(); - } - - public int nextInt() - { - return random.nextInt(); - } - - public int nextInt( int n ) - { - return random.nextInt( n ); - } - - public int nextInt( int origin, int bound ) - { - return random.nextInt( (bound - origin) + 1 ) + origin; - } - - public double nextGaussian() - { - return random.nextGaussian(); - } - - public long nextLong() - { - return random.nextLong(); - } - - public long nextLong( long n ) - { - return Math.abs( nextLong() ) % n; - } - - public long nextLong( long origin, long bound ) - { - return nextLong( (bound - origin) + 1L ) + origin; - } - - // ============================ - // Methods from Randoms - // ============================ - - public int intBetween( int min, int max ) - { - return randoms.intBetween( min, max ); - } - - public String string() - { - return randoms.string(); - } - - public String string( int minLength, int maxLength, int characterSets ) - { - return randoms.string( minLength, maxLength, characterSets ); - } - - public char character( int characterSets ) - { - return randoms.character( characterSets ); - } - - public T[] selection( T[] among, int min, int max, boolean allowDuplicates ) - { - return randoms.selection( among, min, max, allowDuplicates ); - } - - public T among( T[] among ) - { - return randoms.among( among ); - } - - public T among( List among ) - { - return randoms.among( among ); - } - - public void among( List among, Consumer action ) - { - randoms.among( among, action ); - } - - public Number numberPropertyValue() - { - return randoms.numberPropertyValue(); - } - - public Object propertyValue() - { - return randoms.propertyValue(); - } - - // ============================ - // Other utility methods - // ============================ - - public void reset() - { - random = new Random( seed ); - randoms = new Randoms( random, config ); - } - - public Randoms fork( Configuration configuration ) - { - return randoms.fork( configuration ); - } - - public long seed() - { - return seed; - } - - public Random random() - { - return random; - } - - public Randoms randoms() - { - return randoms; - } - - @Retention( RetentionPolicy.RUNTIME ) - @Target( ElementType.METHOD ) - public @interface Seed - { - long value(); - } -} diff --git a/community/index/pom.xml b/community/index/pom.xml index 80eb6c7868f9e..6a707f93630d5 100644 --- a/community/index/pom.xml +++ b/community/index/pom.xml @@ -75,6 +75,12 @@ the relevant Commercial Agreement. test + org.neo4j + neo4j-random-values + ${project.version} + test + + org.neo4j neo4j-collections ${project.version} diff --git a/community/index/src/test/java/org/neo4j/index/internal/gbptree/LargeDynamicKeysIT.java b/community/index/src/test/java/org/neo4j/index/internal/gbptree/LargeDynamicKeysIT.java index 6a4e1378c1817..59b5c61768890 100644 --- a/community/index/src/test/java/org/neo4j/index/internal/gbptree/LargeDynamicKeysIT.java +++ b/community/index/src/test/java/org/neo4j/index/internal/gbptree/LargeDynamicKeysIT.java @@ -39,7 +39,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.neo4j.test.Randoms.CSA_LETTERS_AND_DIGITS; public class LargeDynamicKeysIT { @@ -72,7 +71,7 @@ public void shouldWriteAndReadKeysOfSizesCloseToTheLimits() throws IOException String string; do { - string = random.string( 3_000, 4_000, CSA_LETTERS_AND_DIGITS ); + string = random.nextAlphaNumericString( 3_000, 4_000 ); } while ( !generatedStrings.add( string ) ); RawBytes key = new RawBytes(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/RecoveryIT.java b/community/kernel/src/test/java/org/neo4j/kernel/RecoveryIT.java index 442552a9931cb..ba7f6150155c1 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/RecoveryIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/RecoveryIT.java @@ -555,7 +555,7 @@ private void produceRandomGraphUpdates( GraphDatabaseService db, int numberOfTra Node node = db.createNode( random.nextBoolean() ? array( randomLabel() ) : new Label[0] ); if ( random.nextBoolean() ) { - node.setProperty( randomKey(), random.propertyValue() ); + node.setProperty( randomKey(), random.nextValueAsObject() ); } } else @@ -566,7 +566,7 @@ private void produceRandomGraphUpdates( GraphDatabaseService db, int numberOfTra .createRelationshipTo( random.among( nodes ), randomRelationshipType() ); if ( random.nextBoolean() ) { - relationship.setProperty( randomKey(), random.propertyValue() ); + relationship.setProperty( randomKey(), random.nextValueAsObject() ); } } } @@ -583,12 +583,12 @@ else if ( operation < 0.5 ) } else if ( operation < 0.75 ) { // set node property - random.among( nodes, node -> node.setProperty( randomKey(), random.propertyValue() ) ); + random.among( nodes, node -> node.setProperty( randomKey(), random.nextValueAsObject() ) ); } else { // set relationship property onRandomRelationship( nodes, - relationship -> relationship.setProperty( randomKey(), random.propertyValue() ) ); + relationship -> relationship.setProperty( randomKey(), random.nextValueAsObject() ) ); } } else @@ -712,7 +712,7 @@ else if ( operation < 0.3 ) { if ( random.nextBoolean() ) { - node.setProperty( key, random.propertyValue() ); + node.setProperty( key, random.nextValueAsObject() ); } } nodes.add( node ); @@ -727,7 +727,7 @@ else if ( operation < 0.6 ) } else if ( operation < 0.85 ) { // Set property - random.among( nodes, node -> node.setProperty( random.among( keys ), random.propertyValue() ) ); + random.among( nodes, node -> node.setProperty( random.among( keys ), random.nextValueAsObject() ) ); } else { // Remove property diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/event/TransactionEventsIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/event/TransactionEventsIT.java index 1e883a58ec62e..4948c8a4065dd 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/event/TransactionEventsIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/event/TransactionEventsIT.java @@ -579,7 +579,7 @@ String randomPropertyKey() Object randomPropertyValue() { - return random.propertyValue(); + return random.nextValueAsObject(); } int nodeCount() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DurationLayoutTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DurationLayoutTestUtil.java index a1bbd34037a1a..e5a76041f373a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DurationLayoutTestUtil.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DurationLayoutTestUtil.java @@ -28,7 +28,6 @@ import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; -import org.neo4j.test.Randoms; import org.neo4j.values.storable.DurationValue; import org.neo4j.values.storable.RandomValues; import org.neo4j.values.storable.Value; @@ -48,15 +47,6 @@ public class DurationLayoutTestUtil extends LayoutTestUtil,IOException> cursor = new ResultCursor( keys.iterator() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/FilteringNativeHitIteratorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/FilteringNativeHitIteratorTest.java index 126127c54ccf9..9965cf052a31f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/FilteringNativeHitIteratorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/FilteringNativeHitIteratorTest.java @@ -52,7 +52,7 @@ public void shouldFilterResults() for ( int i = 0; i < 100; i++ ) { // duplicates are fine - keys.add( random.string() ); + keys.add( random.nextAlphaNumericString() ); } RawCursor,IOException> cursor = new ResultCursor( keys.iterator() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/LayoutTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/LayoutTestUtil.java index c17b333075684..d80c85d7f2a5f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/LayoutTestUtil.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/LayoutTestUtil.java @@ -34,7 +34,6 @@ import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.RandomRule; import org.neo4j.values.storable.RandomValues; import org.neo4j.values.storable.Value; @@ -94,45 +93,12 @@ protected IndexEntryUpdate fetchNextOrNull() } else { - value = newUniqueValue( RandomValues.create( random.random(), getConfiguration() ), - uniqueCompareValues, uniqueValues ); + value = newUniqueValue( random.randomValues(), uniqueCompareValues, uniqueValues ); } return add( currentEntityId++, value ); } - private RandomValues.Configuration getConfiguration() - { - return new RandomValues.Configuration() - { - private Randoms.Configuration conf = random.configuration(); - - @Override - public int stringMinLength() - { - return conf.stringMinLength(); - } - - @Override - public int stringMaxLength() - { - return conf.stringMaxLength(); - } - - @Override - public int arrayMinLength() - { - return conf.arrayMinLength(); - } - - @Override - public int arrayMaxLength() - { - return conf.arrayMaxLength(); - } - }; - } - private Value existingNonUniqueValue( RandomRule randomRule ) { return uniqueValues.get( randomRule.nextInt( uniqueValues.size() ) ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/StringLayoutTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/StringLayoutTestUtil.java index 65835583b52ef..ae6b374383415 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/StringLayoutTestUtil.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/StringLayoutTestUtil.java @@ -83,7 +83,7 @@ protected Value newUniqueValue( RandomValues random, Set uniqueCompareVa TextValue candidate; do { - candidate = random.nextString(); + candidate = random.nextTextValue(); } while ( !uniqueCompareValues.add( candidate.stringValue() ) ); uniqueValues.add( candidate ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/PropertyValueRecordSizeCalculatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/PropertyValueRecordSizeCalculatorTest.java index f4ad9972c1fa2..6111f5bc806eb 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/PropertyValueRecordSizeCalculatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/PropertyValueRecordSizeCalculatorTest.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.neo4j.kernel.impl.store.format.standard.PropertyRecordFormat; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.RandomRule; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Values; @@ -88,7 +87,7 @@ public void shouldSpanMultiplePropertyRecords() private String string( int length ) { - return random.string( length, length, Randoms.CSA_LETTERS_AND_DIGITS ); + return random.nextAlphaNumericString( length, length ); } private PropertyValueRecordSizeCalculator newCalculator() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/AbstractRecordFormatTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/AbstractRecordFormatTest.java index 5e92e36e9ef32..3392e702a7e04 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/AbstractRecordFormatTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/AbstractRecordFormatTest.java @@ -98,7 +98,7 @@ public static void setupPageCache() @Before public void before() { - generators = new LimitedRecordGenerators( random.randoms(), entityBits, propertyBits, 40, 16, -1 ); + generators = new LimitedRecordGenerators( random.randomValues(), entityBits, propertyBits, 40, 16, -1 ); } @Test diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/LimitedRecordGenerators.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/LimitedRecordGenerators.java index 693f016fd8038..15c8fc9fcf54f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/LimitedRecordGenerators.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/format/LimitedRecordGenerators.java @@ -31,8 +31,7 @@ import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; import org.neo4j.kernel.impl.store.record.RelationshipRecord; import org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord; -import org.neo4j.test.Randoms; -import org.neo4j.values.storable.Values; +import org.neo4j.values.storable.RandomValues; import static java.lang.Long.max; import static java.lang.Math.abs; @@ -42,7 +41,7 @@ public class LimitedRecordGenerators implements RecordGenerators { static final long NULL = -1; - private final Randoms random; + private final RandomValues random; private final int entityBits; private final int propertyBits; private final int nodeLabelBits; @@ -50,13 +49,13 @@ public class LimitedRecordGenerators implements RecordGenerators private final long nullValue; private final float fractionNullValues; - public LimitedRecordGenerators( Randoms random, int entityBits, int propertyBits, int nodeLabelBits, + public LimitedRecordGenerators( RandomValues random, int entityBits, int propertyBits, int nodeLabelBits, int tokenBits, long nullValue ) { this( random, entityBits, propertyBits, nodeLabelBits, tokenBits, nullValue, 0.2f ); } - public LimitedRecordGenerators( Randoms random, int entityBits, int propertyBits, int nodeLabelBits, + public LimitedRecordGenerators( RandomValues random, int entityBits, int propertyBits, int nodeLabelBits, int tokenBits, long nullValue, float fractionNullValues ) { this.random = random; @@ -126,7 +125,7 @@ public Generator property() PropertyBlock block = new PropertyBlock(); // Dynamic records will not be written and read by the property record format, // that happens in the store where it delegates to a "sub" store. - PropertyStore.encodeValue( block, random.nextInt( tokenBits ), Values.of( random.propertyValue() ), + PropertyStore.encodeValue( block, random.nextInt( tokenBits ), random.nextValue(), stringAllocator, arrayAllocator, true ); int tentativeBlocksWithThisOne = blocksOccupied + block.getValueBlocks().length; if ( tentativeBlocksWithThisOne <= 4 ) @@ -170,9 +169,8 @@ public Generator dynamic() long next = length == dataSize ? randomLong( propertyBits ) : nullValue; DynamicRecord record = new DynamicRecord( max( 1, recordId ) ).initialize( random.nextBoolean(), random.nextBoolean(), next, random.nextInt( PropertyType.values().length ), length ); - byte[] data = new byte[record.getLength()]; - random.nextBytes( data ); - record.setData( data ); + byte[] bytes = random.nextByteArray( record.getLength(), record.getLength() ).asObjectCopy(); + record.setData( bytes ); return record; }; } diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/DeleteDuplicateNodesStepTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/DeleteDuplicateNodesStepTest.java index 4686e7e322f09..d13e9ed2e75db 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/DeleteDuplicateNodesStepTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/DeleteDuplicateNodesStepTest.java @@ -46,20 +46,19 @@ import org.neo4j.kernel.impl.transaction.state.PropertyCreator; import org.neo4j.kernel.impl.transaction.state.PropertyTraverser; import org.neo4j.kernel.impl.transaction.state.RecordAccess; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.NeoStoresRule; import org.neo4j.test.rule.RandomRule; import org.neo4j.test.rule.RepeatRule; import org.neo4j.test.rule.RepeatRule.Repeat; import org.neo4j.unsafe.batchinsert.internal.DirectRecordAccess; import org.neo4j.unsafe.impl.batchimport.staging.SimpleStageControl; -import org.neo4j.values.storable.Values; +import org.neo4j.values.storable.RandomValues; import static org.junit.Assert.assertEquals; public class DeleteDuplicateNodesStepTest { - private final RandomRule random = new RandomRule().withConfiguration( new Randoms.Default() + private final RandomRule random = new RandomRule().withConfiguration( new RandomValues.Default() { @Override public int stringMaxLength() @@ -237,7 +236,7 @@ protected PropertyBlock fetchNextOrNull() return null; } PropertyBlock block = new PropertyBlock(); - propertyStore.encodeValue( block, i, Values.of( random.propertyValue() ) ); + propertyStore.encodeValue( block, i, random.nextValue() ); i++; return block; } diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/ImportPanicIT.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/ImportPanicIT.java index a8a8c50874a5c..9f596600f786a 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/ImportPanicIT.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/ImportPanicIT.java @@ -51,7 +51,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - import static org.neo4j.unsafe.impl.batchimport.ImportLogic.NO_MONITOR; import static org.neo4j.unsafe.impl.batchimport.input.InputEntityDecorators.NO_DECORATOR; import static org.neo4j.unsafe.impl.batchimport.input.csv.Configuration.COMMAS; diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/RandomsStates.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/RandomsStates.java index 8ac7682fc083a..913e265aade07 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/RandomsStates.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/RandomsStates.java @@ -22,13 +22,13 @@ import java.util.Random; import java.util.function.LongFunction; -import org.neo4j.test.Randoms; +import org.neo4j.values.storable.RandomValues; /** * Utility for generating deterministically randomized data, even though chunks may be reordered * during actual import. */ -public class RandomsStates implements LongFunction +public class RandomsStates implements LongFunction { private final long initialSeed; @@ -38,8 +38,8 @@ public RandomsStates( long initialSeed ) } @Override - public Randoms apply( long batch ) + public RandomValues apply( long batch ) { - return new Randoms( new Random( initialSeed + batch ), Randoms.DEFAULT ); + return RandomValues.create( new Random( initialSeed + batch ) ); } } diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/NumberArrayTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/NumberArrayTest.java index bd6b1ec2747d8..4cfcc6dca4478 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/NumberArrayTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/NumberArrayTest.java @@ -39,11 +39,10 @@ import org.neo4j.io.pagecache.PageCache; import org.neo4j.test.rule.RandomRule; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; import static java.lang.Integer.max; - +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.neo4j.unsafe.impl.batchimport.cache.NumberArrayFactory.AUTO_WITHOUT_PAGECACHE; import static org.neo4j.unsafe.impl.batchimport.cache.NumberArrayFactory.CHUNKED_FIXED_SIZE; import static org.neo4j.unsafe.impl.batchimport.cache.NumberArrayFactory.HEAP; diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/StringCollisionValuesTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/StringCollisionValuesTest.java index 1de984c2d7af2..7d6d540358492 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/StringCollisionValuesTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/StringCollisionValuesTest.java @@ -29,9 +29,9 @@ import java.util.Arrays; import java.util.Collection; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.RandomRule; import org.neo4j.unsafe.impl.batchimport.cache.NumberArrayFactory; +import org.neo4j.values.storable.RandomValues; import static org.junit.Assert.assertEquals; import static org.neo4j.unsafe.impl.batchimport.cache.NumberArrayFactory.AUTO_WITHOUT_PAGECACHE; @@ -43,7 +43,7 @@ public class StringCollisionValuesTest { @Rule - public final RandomRule random = new RandomRule().withConfiguration( new Randoms.Default() + public final RandomRule random = new RandomRule().withConfiguration( new RandomValues.Default() { @Override public int stringMaxLength() @@ -72,7 +72,7 @@ public void shouldStoreAndLoadStrings() String[] strings = new String[offsets.length]; for ( int i = 0; i < offsets.length; i++ ) { - String string = random.string(); + String string = random.nextAlphaNumericString(); offsets[i] = values.add( string ); strings[i] = string; } diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/Distribution.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/Distribution.java index 2bd94d9146c3a..5ef0731fbe556 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/Distribution.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/Distribution.java @@ -21,6 +21,8 @@ import java.util.Random; +import org.neo4j.values.storable.RandomValues; + /** * Distributes the given items so that item[0] converges towards being returned 1/2 of the times, * the next item, item[1] 1/4 of the times, item[2] 1/8 and so on. @@ -53,4 +55,19 @@ public T random( Random random ) } return items[items.length - 1]; } + + public T random( RandomValues random ) + { + float value = random.nextFloat(); + float comparison = 0.5f; + for ( T item : items ) + { + if ( value >= comparison ) + { + return item; + } + comparison /= 2f; + } + return items[items.length - 1]; + } } diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputCacheTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputCacheTest.java index eb7dcb4be7dbf..0001a354663db 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputCacheTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputCacheTest.java @@ -36,11 +36,11 @@ import java.util.function.Consumer; import org.neo4j.kernel.impl.store.format.standard.Standard; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.RandomRule; import org.neo4j.test.rule.TestDirectory; import org.neo4j.test.rule.fs.DefaultFileSystemRule; import org.neo4j.unsafe.impl.batchimport.InputIterator; +import org.neo4j.values.storable.RandomValues; import static java.lang.Math.abs; import static org.junit.Assert.assertEquals; @@ -133,11 +133,11 @@ private List readEntities( InputIterator reader ) throws Exception return allReadEntities; } - private void writeEntities( InputCacher cacher, BiConsumer generator ) throws Exception + private void writeEntities( InputCacher cacher, BiConsumer generator ) throws Exception { for ( int i = 0; i < threads; i++ ) { - Randoms localRandom = new Randoms( new Random( randomRule.seed() + i ), Randoms.DEFAULT ); + RandomValues localRandom = RandomValues.create( new Random( randomRule.seed() + i ) ); submit( () -> { InputEntity actual = new InputEntity(); @@ -162,12 +162,12 @@ private void assertNoFilesLeftBehind() assertEquals( 0, fileSystemRule.get().listFiles( dir.directory() ).length ); } - private void randomRelationship( Randoms random, InputEntityVisitor relationship ) + private void randomRelationship( RandomValues random, InputEntityVisitor relationship ) { - if ( random.random().nextFloat() < 0.1f ) + if ( random.nextFloat() < 0.1f ) { - relationship.type( abs( random.random().nextInt( 20_000 ) ) ); - relationship.propertyId( abs( random.random().nextLong() ) ); + relationship.type( abs( random.nextInt( 20_000 ) ) ); + relationship.propertyId( abs( random.nextLong() ) ); } else { @@ -186,9 +186,9 @@ private void randomRelationship( Randoms random, InputEntityVisitor relationship } } - private void randomNode( Randoms random, InputEntityVisitor node ) + private void randomNode( RandomValues random, InputEntityVisitor node ) { - if ( random.random().nextFloat() < 0.1f ) + if ( random.nextFloat() < 0.1f ) { node.id( randomId( random ) ); node.propertyId( randomId( random ) ); @@ -210,13 +210,13 @@ private void randomNode( Randoms random, InputEntityVisitor node ) } } - private void randomProperties( InputEntityVisitor entity, Randoms random ) + private void randomProperties( InputEntityVisitor entity, RandomValues random ) { - int length = random.random().nextInt( 10 ); + int length = random.nextInt( 10 ); for ( int i = 0; i < length; i++ ) { - Object value = random.propertyValue(); - if ( random.random().nextFloat() < 0.2f ) + Object value = random.nextValue().asObject(); + if ( random.nextFloat() < 0.2f ) { entity.property( random.intBetween( 0, 10 ), value ); } @@ -227,24 +227,24 @@ private void randomProperties( InputEntityVisitor entity, Randoms random ) } } - private String randomType( Randoms random ) + private String randomType( RandomValues random ) { return random.among( TOKENS ); } - private Group randomGroup( Randoms random ) + private Group randomGroup( RandomValues random ) { - return new Group.Adapter( random.nextInt( 100 ), random.string() ); + return new Group.Adapter( random.nextInt( 100 ), random.nextAlphaNumericTextValue().stringValue() ); } - private String[] randomLabels( Randoms random ) + private String[] randomLabels( RandomValues random ) { return random.selection( TOKENS, 1, 5, false ); } - private long randomId( Randoms random ) + private long randomId( RandomValues random ) { - return abs( random.random().nextLong() ); + return abs( random.nextLong() ); } private void submit( Callable toRun ) diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputEntityCacherTokenCreationTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputEntityCacherTokenCreationTest.java index 87f3acb058d92..a762e08df8822 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputEntityCacherTokenCreationTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/InputEntityCacherTokenCreationTest.java @@ -30,8 +30,8 @@ import org.neo4j.io.fs.StoreChannel; import org.neo4j.kernel.impl.store.format.RecordFormat; import org.neo4j.kernel.impl.store.format.RecordFormats; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.RandomRule; +import org.neo4j.values.storable.RandomValues; import static java.lang.Math.abs; import static org.mockito.Mockito.mock; @@ -109,7 +109,7 @@ private void cacheRelationship( int iterations, int maxNumberOfRelationshipTypes { for ( int i = 0; i < iterations; i++ ) { - generateRelationship( getRandoms(), visitor ); + generateRelationship( getRandomValues(), visitor ); } } } @@ -123,7 +123,7 @@ private void cacheLabels( int iterations, int maxNumberOfLabels ) throws IOExcep { for ( int i = 0; i < iterations; i++ ) { - generateNode( getRandoms(), visitor ); + generateNode( getRandomValues(), visitor ); } } } @@ -135,7 +135,7 @@ private void cacheGroups( int iterations, int maxNumberOfGroups ) throws IOExcep try ( InputNodeCacheWriter cacher = getNodeCacher( recordFormats ); InputEntityVisitor visitor = cacher.wrap( new InputEntity() ) ) { - Randoms randoms = getRandoms(); + RandomValues randoms = getRandomValues(); for ( int i = 0; i < iterations; i++ ) { generateNode( randoms, visitor, false ); @@ -150,7 +150,7 @@ private void cacheNodeWithProperties( int iterations, int maxNumberOfProperties try ( InputNodeCacheWriter cacher = getNodeCacher( recordFormats ); InputEntityVisitor visitor = cacher.wrap( new InputEntity() ) ) { - Randoms randoms = getRandoms(); + RandomValues randoms = getRandomValues(); for ( int i = 0; i < iterations; i++ ) { generateNode( randoms, visitor ); @@ -165,7 +165,7 @@ private void initExpectedException( int numberOfSupportedTokens ) "tokens is not supported." ); } - private void generateRelationship( Randoms randoms, InputEntityVisitor relationship ) throws IOException + private void generateRelationship( RandomValues randoms, InputEntityVisitor relationship ) throws IOException { generateProperties( randoms, relationship ); relationship.startId( randomId( randoms ), generateGroup() ); @@ -174,12 +174,12 @@ private void generateRelationship( Randoms randoms, InputEntityVisitor relations relationship.endOfEntity(); } - private void generateNode( Randoms random, InputEntityVisitor node ) throws IOException + private void generateNode( RandomValues random, InputEntityVisitor node ) throws IOException { generateNode( random, node, true ); } - private void generateNode( Randoms random, InputEntityVisitor node, boolean propertiesAndLabels ) throws IOException + private void generateNode( RandomValues random, InputEntityVisitor node, boolean propertiesAndLabels ) throws IOException { node.id( randomId( random ), generateGroup() ); if ( propertiesAndLabels ) @@ -210,20 +210,20 @@ private String getUniqueString() return uniqueIdGenerator.getAndIncrement() + ""; } - private void generateProperties( Randoms random, InputEntityVisitor entity ) + private void generateProperties( RandomValues random, InputEntityVisitor entity ) { int length = 1; for ( int i = 0; i < length; i++ ) { String key = getUniqueString(); - String value = random.propertyValue() + ""; + String value = random.nextValue().asObject() + ""; entity.property( key, value ); } } - private Object randomId( Randoms random ) + private Object randomId( RandomValues random ) { - return abs( random.random().nextLong() ); + return abs( random.nextLong() ); } private RecordFormats mockRecordFormats( long maxPropertyKeyId, long maxLabelId, long maxRelationshipTypeId, @@ -248,9 +248,9 @@ private RecordFormat getRecordFormatMock( long maxId ) return recordFormat; } - private Randoms getRandoms() + private RandomValues getRandomValues() { - return new Randoms( randomRule.random(), Randoms.DEFAULT ); + return randomRule.randomValues(); } private InputNodeCacheWriter getNodeCacher( RecordFormats recordFormats ) diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/RandomEntityDataGenerator.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/RandomEntityDataGenerator.java index 35a4436438be8..9258425fcbce1 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/RandomEntityDataGenerator.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/input/RandomEntityDataGenerator.java @@ -20,10 +20,8 @@ package org.neo4j.unsafe.impl.batchimport.input; import java.util.List; -import java.util.Random; import org.neo4j.helpers.ArrayUtil; -import org.neo4j.test.Randoms; import org.neo4j.unsafe.impl.batchimport.GeneratingInputIterator; import org.neo4j.unsafe.impl.batchimport.InputIterator; import org.neo4j.unsafe.impl.batchimport.RandomsStates; @@ -31,6 +29,7 @@ import org.neo4j.unsafe.impl.batchimport.input.csv.Header; import org.neo4j.unsafe.impl.batchimport.input.csv.Header.Entry; import org.neo4j.unsafe.impl.batchimport.input.csv.Type; +import org.neo4j.values.storable.RandomValues; import static java.lang.Integer.min; import static org.neo4j.unsafe.impl.batchimport.input.InputEntity.NO_LABELS; @@ -38,7 +37,7 @@ /** * Data generator as {@link InputIterator}, parallelizable */ -public class RandomEntityDataGenerator extends GeneratingInputIterator +public class RandomEntityDataGenerator extends GeneratingInputIterator { public RandomEntityDataGenerator( long nodeCount, long count, int batchSize, long seed, long startId, Header header, Distribution labels, Distribution relationshipTypes, float factorBadNodeData, float factorBadRelationshipData ) @@ -67,7 +66,7 @@ public RandomEntityDataGenerator( long nodeCount, long count, int batchSize, lon visitor.property( entry.name(), randomProperty( entry, randoms ) ); break; case LABEL: - visitor.labels( randomLabels( randoms.random(), labels ) ); + visitor.labels( randomLabels( randoms, labels ) ); break; case START_ID: case END_ID: @@ -95,7 +94,7 @@ public RandomEntityDataGenerator( long nodeCount, long count, int batchSize, lon } break; case TYPE: - visitor.type( randomRelationshipType( randoms.random(), relationshipTypes ) ); + visitor.type( randomRelationshipType( randoms, relationshipTypes ) ); break; default: throw new IllegalArgumentException( entry.toString() ); @@ -114,18 +113,18 @@ private static Object idValue( Entry entry, long id ) } } - private static String randomRelationshipType( Random random, Distribution relationshipTypes ) + private static String randomRelationshipType( RandomValues random, Distribution relationshipTypes ) { return relationshipTypes.random( random ); } - private static Object randomProperty( Entry entry, Randoms random ) + private static Object randomProperty( Entry entry, RandomValues random ) { String type = entry.extractor().name(); switch ( type ) { case "String": - return random.string( 5, 20, Randoms.CSA_LETTERS_AND_DIGITS ); + return random.nextAlphaNumericTextValue( 5, 20 ).stringValue(); case "long": return random.nextInt( Integer.MAX_VALUE ); case "int": @@ -135,7 +134,7 @@ private static Object randomProperty( Entry entry, Randoms random ) } } - private static String[] randomLabels( Random random, Distribution labels ) + private static String[] randomLabels( RandomValues random, Distribution labels ) { int length = random.nextInt( min( 3, labels.length() ) ); if ( length == 0 ) diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/staging/HumanUnderstandableExecutionMonitorIT.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/staging/HumanUnderstandableExecutionMonitorIT.java index f21c4f9027289..b11c0fcd3ee85 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/staging/HumanUnderstandableExecutionMonitorIT.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/staging/HumanUnderstandableExecutionMonitorIT.java @@ -39,7 +39,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; - import static org.neo4j.kernel.configuration.Config.defaults; import static org.neo4j.kernel.impl.store.format.standard.Standard.LATEST_RECORD_FORMATS; import static org.neo4j.unsafe.impl.batchimport.AdditionalInitialIds.EMPTY; diff --git a/community/lucene-index/pom.xml b/community/lucene-index/pom.xml index 6dbbe58291026..0a4f9af454c80 100644 --- a/community/lucene-index/pom.xml +++ b/community/lucene-index/pom.xml @@ -149,6 +149,11 @@ the relevant Commercial Agreement. org.mockito mockito-core - + + org.neo4j + neo4j-random-values + ${project.version} + test + diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexUniquenessVerificationIT.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexUniquenessVerificationIT.java index 8e770d969bdb4..bc78731a4484c 100644 --- a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexUniquenessVerificationIT.java +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexUniquenessVerificationIT.java @@ -50,9 +50,9 @@ import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; import org.neo4j.kernel.configuration.Config; -import org.neo4j.test.Randoms; import org.neo4j.test.rule.TestDirectory; import org.neo4j.test.rule.fs.DefaultFileSystemRule; +import org.neo4j.values.storable.RandomValues; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Values; @@ -360,21 +360,19 @@ private Set randomDoubles( double min, double max ) private Set randomArrays( int minLength, int maxLength ) { - Randoms randoms = new Randoms( ThreadLocalRandom.current(), new ArraySizeConfig( minLength, maxLength ) ); + RandomValues randoms = RandomValues.create( new ArraySizeConfig( minLength, maxLength ) ); return IntStream.range( 0, nodesToCreate ) - .mapToObj( i -> randoms.array() ) - .map( Values::of ) + .mapToObj( i -> randoms.nextArray() ) .collect( toSet() ); } private Set randomValues() { - Randoms randoms = new Randoms( ThreadLocalRandom.current(), new ArraySizeConfig( 5, 100 ) ); + RandomValues randoms = RandomValues.create( new ArraySizeConfig( 5, 100 ) ); return IntStream.range( 0, nodesToCreate ) - .mapToObj( i -> randoms.propertyValue() ) - .map( Values::of ) + .mapToObj( i -> randoms.nextValue() ) .collect( toSet() ); } @@ -424,7 +422,7 @@ private static double randomDoubleInRange( double min, double max ) return ThreadLocalRandom.current().nextDouble( min, max ); } - private static class ArraySizeConfig extends Randoms.Default + private static class ArraySizeConfig extends RandomValues.Default { final int minLength; final int maxLength; diff --git a/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/NativeStringIndexingIT.java b/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/NativeStringIndexingIT.java index cb3a2fb40e3a9..3c8f8bdfdcb3a 100644 --- a/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/NativeStringIndexingIT.java +++ b/community/neo4j/src/test/java/org/neo4j/kernel/impl/index/schema/NativeStringIndexingIT.java @@ -48,7 +48,6 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.neo4j.test.Randoms.CSA_LETTERS_AND_DIGITS; public class NativeStringIndexingIT { @@ -76,7 +75,7 @@ public void shouldHandleSizesCloseToTheLimit() String string; do { - string = random.string( 3_000, 4_000, CSA_LETTERS_AND_DIGITS ); + string = random.nextAlphaNumericString( 3_000, 4_000 ); } while ( strings.containsKey( string ) ); @@ -111,7 +110,7 @@ public void shouldFailBeforeCommitOnSizesLargerThanLimit() { try ( Transaction tx = db.beginTx() ) { - db.createNode( LABEL ).setProperty( KEY, random.string( length, length, CSA_LETTERS_AND_DIGITS ) ); + db.createNode( LABEL ).setProperty( KEY, random.nextAlphaNumericString( length, length ) ); tx.success(); } fail( "Should have failed" ); @@ -131,8 +130,8 @@ public void shouldHandleCompositeSizesCloseToTheLimit() throws KernelException // when a string longer than native string limit, but within lucene limit int length = 20_000; - String string1 = random.string( length, length, CSA_LETTERS_AND_DIGITS ); - String string2 = random.string( length, length, CSA_LETTERS_AND_DIGITS ); + String string1 = random.nextAlphaNumericString( length, length ); + String string2 = random.nextAlphaNumericString( length, length ); Node node; try ( Transaction tx = db.beginTx() ) { @@ -177,8 +176,8 @@ public void shouldFailBeforeCommitOnCompositeSizesLargerThanLimit() try ( Transaction tx = db.beginTx() ) { Node node = db.createNode( LABEL ); - node.setProperty( KEY, random.string( length, length, CSA_LETTERS_AND_DIGITS ) ); - node.setProperty( KEY2, random.string( length, length, CSA_LETTERS_AND_DIGITS ) ); + node.setProperty( KEY, random.nextAlphaNumericString( length, length ) ); + node.setProperty( KEY2, random.nextAlphaNumericString( length, length ) ); tx.success(); } fail( "Should have failed" ); diff --git a/community/neo4j/src/test/java/org/neo4j/unsafe/impl/batchimport/ParallelBatchImporterTest.java b/community/neo4j/src/test/java/org/neo4j/unsafe/impl/batchimport/ParallelBatchImporterTest.java index d0d799eda69b7..4c06efb00c158 100644 --- a/community/neo4j/src/test/java/org/neo4j/unsafe/impl/batchimport/ParallelBatchImporterTest.java +++ b/community/neo4j/src/test/java/org/neo4j/unsafe/impl/batchimport/ParallelBatchImporterTest.java @@ -33,7 +33,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.function.Function; @@ -58,7 +57,6 @@ import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.standard.Standard; import org.neo4j.logging.NullLogProvider; -import org.neo4j.test.Randoms; import org.neo4j.test.TestGraphDatabaseFactory; import org.neo4j.test.rule.RandomRule; import org.neo4j.test.rule.TestDirectory; @@ -71,6 +69,7 @@ import org.neo4j.unsafe.impl.batchimport.input.InputEntityVisitor; import org.neo4j.unsafe.impl.batchimport.input.Inputs; import org.neo4j.unsafe.impl.batchimport.staging.ExecutionMonitor; +import org.neo4j.values.storable.RandomValues; import org.neo4j.values.storable.Values; import static java.lang.Math.toIntExact; @@ -167,7 +166,7 @@ public void shouldImportCsvData() throws Exception { // GIVEN ExecutionMonitor processorAssigner = eagerRandomSaturation( config.maxNumberOfProcessors() ); - File storeDir = directory.directory( "dir" + random.string( 8, 8, Randoms.CSA_LETTERS_AND_DIGITS ) ); + File storeDir = directory.directory( "dir" + random.nextAlphaNumericString( 8, 8 ) ); storeDir.mkdirs(); final BatchImporter inserter = new ParallelBatchImporter( storeDir, fileSystemRule.get(), null, config, NullLogService.getInstance(), @@ -264,15 +263,15 @@ public abstract static class InputIdGenerator { abstract void reset(); - abstract Object nextNodeId( Random random, long item ); + abstract Object nextNodeId( RandomValues random, long item ); - abstract ExistingId randomExisting( Random random ); + abstract ExistingId randomExisting( RandomValues random ); - abstract Object miss( Random random, Object id, float chance ); + abstract Object miss( RandomValues random, Object id, float chance ); abstract boolean isMiss( Object id ); - String randomType( Random random ) + String randomType( RandomValues random ) { return "TYPE" + random.nextInt( RELATIONSHIP_TYPES ); } @@ -292,20 +291,20 @@ void reset() } @Override - synchronized Object nextNodeId( Random random, long item ) + synchronized Object nextNodeId( RandomValues random, long item ) { return item; } @Override - ExistingId randomExisting( Random random ) + ExistingId randomExisting( RandomValues random ) { long index = random.nextInt( NODE_COUNT ); return new ExistingId( index, index ); } @Override - Object miss( Random random, Object id, float chance ) + Object miss( RandomValues random, Object id, float chance ) { return random.nextFloat() < chance ? (Long) id + 100_000_000 : id; } @@ -328,24 +327,23 @@ void reset() } @Override - Object nextNodeId( Random random, long item ) + Object nextNodeId( RandomValues random, long item ) { - byte[] randomBytes = new byte[10]; - random.nextBytes( randomBytes ); + byte[] randomBytes = random.nextByteArray( 10, 10 ).asObjectCopy(); String result = UUID.nameUUIDFromBytes( randomBytes ).toString(); strings[toIntExact( item )] = result; return result; } @Override - ExistingId randomExisting( Random random ) + ExistingId randomExisting( RandomValues random ) { int index = random.nextInt( strings.length ); return new ExistingId( strings[index], index ); } @Override - Object miss( Random random, Object id, float chance ) + Object miss( RandomValues random, Object id, float chance ) { return random.nextFloat() < chance ? "_" + id : id; } @@ -530,20 +528,20 @@ private InputIterable relationships( final long randomSeed, final long count, in return replayable( () -> new GeneratingInputIterator<>( count, batchSize, new RandomsStates( randomSeed ), ( randoms, visitor, id ) -> { randomProperties( randoms, "Name " + id, visitor ); - ExistingId startNodeExistingId = idGenerator.randomExisting( randoms.random() ); + ExistingId startNodeExistingId = idGenerator.randomExisting( randoms ); Group startNodeGroup = groups.groupOf( startNodeExistingId.nodeIndex ); - ExistingId endNodeExistingId = idGenerator.randomExisting( randoms.random() ); + ExistingId endNodeExistingId = idGenerator.randomExisting( randoms ); Group endNodeGroup = groups.groupOf( endNodeExistingId.nodeIndex ); // miss some - Object startNode = idGenerator.miss( randoms.random(), startNodeExistingId.id, 0.001f ); - Object endNode = idGenerator.miss( randoms.random(), endNodeExistingId.id, 0.001f ); + Object startNode = idGenerator.miss( randoms, startNodeExistingId.id, 0.001f ); + Object endNode = idGenerator.miss( randoms, endNodeExistingId.id, 0.001f ); visitor.startId( startNode, startNodeGroup ); visitor.endId( endNode, endNodeGroup ); - String type = idGenerator.randomType( randoms.random() ); - if ( randoms.random().nextFloat() < 0.00005 ) + String type = idGenerator.randomType( randoms ); + if ( randoms.nextFloat() < 0.00005 ) { // Let there be a small chance of introducing a one-off relationship // with a type that no, or at least very few, other relationships have. @@ -558,7 +556,7 @@ private InputIterable nodes( final long randomSeed, final long count, int batchS { return replayable( () -> new GeneratingInputIterator<>( count, batchSize, new RandomsStates( randomSeed ), ( randoms, visitor, id ) -> { - Object nodeId = inputIdGenerator.nextNodeId( randoms.random(), id ); + Object nodeId = inputIdGenerator.nextNodeId( randoms, id ); Group group = groups.groupOf( id ); visitor.id( nodeId, group ); randomProperties( randoms, uniqueId( group, nodeId ), visitor ); @@ -568,12 +566,12 @@ private InputIterable nodes( final long randomSeed, final long count, int batchS private static final String[] TOKENS = {"token1", "token2", "token3", "token4", "token5", "token6", "token7"}; - private void randomProperties( Randoms randoms, Object id, InputEntityVisitor visitor ) + private void randomProperties( RandomValues randoms, Object id, InputEntityVisitor visitor ) { String[] keys = randoms.selection( TOKENS, 0, TOKENS.length, false ); for ( String key : keys ) { - visitor.property( key, randoms.propertyValue() ); + visitor.property( key, randoms.nextValue().asObject() ); } visitor.property( "id", id ); } diff --git a/community/neo4j/src/test/java/schema/MultipleIndexPopulationStressIT.java b/community/neo4j/src/test/java/schema/MultipleIndexPopulationStressIT.java index 13ab9663e7ecf..809dc35b53d37 100644 --- a/community/neo4j/src/test/java/schema/MultipleIndexPopulationStressIT.java +++ b/community/neo4j/src/test/java/schema/MultipleIndexPopulationStressIT.java @@ -19,7 +19,6 @@ */ package schema; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; @@ -51,7 +50,6 @@ import org.neo4j.kernel.impl.store.format.RecordFormatSelector; import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.logging.NullLogProvider; -import org.neo4j.test.Randoms; import org.neo4j.test.TestGraphDatabaseFactory; import org.neo4j.test.rule.CleanupRule; import org.neo4j.test.rule.RandomRule; @@ -97,7 +95,6 @@ public class MultipleIndexPopulationStressIT private final TestDirectory directory = TestDirectory.testDirectory(); private final RandomRule random = new RandomRule(); - private RandomValues randomValues; private final CleanupRule cleanup = new CleanupRule(); private final RepeatRule repeat = new RepeatRule(); private final DefaultFileSystemRule fileSystemRule = new DefaultFileSystemRule(); @@ -106,12 +103,6 @@ public class MultipleIndexPopulationStressIT public final RuleChain ruleChain = RuleChain.outerRule( random ).around( repeat ).around( directory ) .around( cleanup ).around( fileSystemRule ); - @Before - public void setup() - { - this.randomValues = RandomValues.create( random.random(), getConfiguration() ); - } - @Test public void populateMultipleIndexWithSeveralNodesSingleThreaded() throws Exception { @@ -286,7 +277,7 @@ private void changeRandomNode( GraphDatabaseService db, int nodeCount, RandomVal Node node = db.getNodeById( nodeId ); Object[] keys = Iterables.asCollection( node.getPropertyKeys() ).toArray(); String key = (String) random.among( keys ); - if ( random.nextFloatValue().value() < 0.1 ) + if ( random.nextFloat() < 0.1 ) { // REMOVE node.removeProperty( key ); } @@ -312,9 +303,9 @@ private void createRandomData( int count ) throws IOException importer.doImport( new RandomDataInput( count ) ); } - private class RandomNodeGenerator extends GeneratingInputIterator + private class RandomNodeGenerator extends GeneratingInputIterator { - RandomNodeGenerator( int count, Generator randomsGenerator ) + RandomNodeGenerator( int count, Generator randomsGenerator ) { super( count, 1_000, new RandomsStates( random.seed() ), randomsGenerator, 0 ); } @@ -339,12 +330,12 @@ public InputIterable relationships() public InputIterable nodes() { return InputIterable.replayable( () -> new RandomNodeGenerator( count, ( state, visitor, id ) -> { - String[] keys = random.randoms().selection( TOKENS, 1, TOKENS.length, false ); + String[] keys = random.randomValues().selection( TOKENS, 1, TOKENS.length, false ); for ( String key : keys ) { - visitor.property( key, randomValues.nextValue() ); + visitor.property( key, random.nextValueAsObject() ); } - visitor.labels( random.randoms().selection( TOKENS, 1, TOKENS.length, false ) ); + visitor.labels( random.selection( TOKENS, 1, TOKENS.length, false ) ); } ) ); } @@ -375,35 +366,4 @@ public Estimates calculateEstimates( ToIntFunction valueSizeCalculator } } - private RandomValues.Configuration getConfiguration() - { - return new RandomValues.Configuration() - { - private Randoms.Configuration conf = random.configuration(); - - @Override - public int stringMinLength() - { - return conf.stringMinLength(); - } - - @Override - public int stringMaxLength() - { - return conf.stringMaxLength(); - } - - @Override - public int arrayMinLength() - { - return conf.arrayMinLength(); - } - - @Override - public int arrayMaxLength() - { - return conf.arrayMaxLength(); - } - }; - } } diff --git a/community/random-values/pom.xml b/community/random-values/pom.xml index b3784576eacd8..09216a0b64877 100644 --- a/community/random-values/pom.xml +++ b/community/random-values/pom.xml @@ -4,7 +4,7 @@ org.neo4j parent - 3.4.0-SNAPSHOT + 3.5.0-SNAPSHOT ../.. @@ -50,16 +50,21 @@ + + org.neo4j neo4j-values ${project.version} + junit junit - test + provided + true + org.hamcrest hamcrest-core diff --git a/community/random-values/src/main/java/org/neo4j/values/Generator.java b/community/random-values/src/main/java/org/neo4j/values/Generator.java deleted file mode 100644 index 4ae5f062ae04a..0000000000000 --- a/community/random-values/src/main/java/org/neo4j/values/Generator.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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; - -/** - * This class is meant as a gap so that we don't need a direct dependency on a random number generator. - *

- * For example by wrapping in a generator we can support both {@code java.util.Random} and {@code java.util - * .SplittableRandom} - */ -public interface Generator -{ - /** - * Return a pseudorandom normally distributed long - * @return a pseudorandom normally distributed long - */ - long nextLong(); - - /** - * Return a pseudorandom normally distributed boolean - * @return a pseudorandom normally distributed boolean - */ - boolean nextBoolean(); - - /** - * Return a pseudorandom normally distributed int - * @return a pseudorandom normally distributed int - */ - int nextInt(); - - /** - * Return a pseudorandom normally distributed long between 0 (inclusive) and the given bound(exlusive) - * @param bound the exclusive upper bound for the number generation - * @return a pseudorandom normally distributed int - */ - int nextInt( int bound ); - - /** - * Return a pseudorandom normally distributed float - * @return a pseudorandom normally distributed float - */ - float nextFloat(); - - /** - * Return a pseudorandom normally distributed double - * @return a pseudorandom normally distributed double - */ - double nextDouble(); -} diff --git a/community/random-values/src/main/java/org/neo4j/values/RandomGenerator.java b/community/random-values/src/main/java/org/neo4j/values/RandomGenerator.java deleted file mode 100644 index cc24f9d26c9cb..0000000000000 --- a/community/random-values/src/main/java/org/neo4j/values/RandomGenerator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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; - -public class RandomGenerator implements Generator -{ - private final Random random; - - public RandomGenerator( Random random ) - { - this.random = random; - } - - @Override - public long nextLong() - { - return random.nextLong(); - } - - @Override - public boolean nextBoolean() - { - return random.nextBoolean(); - } - - @Override - public int nextInt() - { - return random.nextInt(); - } - - @Override - public int nextInt( int bound ) - { - return random.nextInt( bound ); - } - - @Override - public float nextFloat() - { - return random.nextFloat(); - } - - @Override - public double nextDouble() - { - return random.nextDouble(); - } -} diff --git a/community/random-values/src/main/java/org/neo4j/values/SplittableRandomGenerator.java b/community/random-values/src/main/java/org/neo4j/values/SplittableRandomGenerator.java deleted file mode 100644 index 5e1bf70784840..0000000000000 --- a/community/random-values/src/main/java/org/neo4j/values/SplittableRandomGenerator.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.SplittableRandom; - -public class SplittableRandomGenerator implements Generator -{ - private final SplittableRandom random; - - public SplittableRandomGenerator( SplittableRandom random ) - { - this.random = random; - } - - @Override - public long nextLong() - { - return random.nextLong(); - } - - @Override - public boolean nextBoolean() - { - return random.nextBoolean(); - } - - @Override - public int nextInt() - { - return random.nextInt(); - } - - @Override - public int nextInt( int bound ) - { - return random.nextInt( bound ); - } - - @Override - public float nextFloat() - { - //this is a safe cast since nextDouble returns values in [0,1.0) - return (float) random.nextDouble(); - } - - @Override - public double nextDouble() - { - return random.nextDouble(); - } -} diff --git a/community/random-values/src/main/java/org/neo4j/values/storable/RandomValues.java b/community/random-values/src/main/java/org/neo4j/values/storable/RandomValues.java index f4cb34b34c9ed..a596f9b1cf227 100644 --- a/community/random-values/src/main/java/org/neo4j/values/storable/RandomValues.java +++ b/community/random-values/src/main/java/org/neo4j/values/storable/RandomValues.java @@ -19,6 +19,7 @@ */ package org.neo4j.values.storable; +import java.lang.reflect.Array; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -34,10 +35,6 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.function.Consumer; -import org.neo4j.values.Generator; -import org.neo4j.values.RandomGenerator; -import org.neo4j.values.SplittableRandomGenerator; - import static java.lang.Math.abs; import static java.time.LocalDate.ofEpochDay; import static java.time.LocalDateTime.ofInstant; @@ -126,6 +123,8 @@ public int arrayMaxLength() } } + public static Configuration DEFAULT_CONFIGURATION = new Default(); + private final Generator generator; private final Configuration configuration; @@ -133,7 +132,7 @@ public int arrayMaxLength() private RandomValues( Generator generator ) { - this( generator, new Default() ); + this( generator, DEFAULT_CONFIGURATION ); } private RandomValues( Generator generator, Configuration configuration ) @@ -250,6 +249,16 @@ public BooleanValue nextBooleanValue() return Values.booleanValue( generator.nextBoolean() ); } + /** + * Returns the next pseudorandom uniformly distributed {@code boolean} + * + * @return the next pseudorandom uniformly distributed {@code boolean} + */ + public boolean nextBoolean() + { + return generator.nextBoolean(); + } + /** * Returns the next pseudorandom uniformly distributed {@link IntValue} * @@ -260,6 +269,16 @@ public IntValue nextIntValue() return intValue( generator.nextInt() ); } + /** + * Returns the next pseudorandom uniformly distributed {@code int} + * + * @return the next pseudorandom uniformly distributed {@code int} + */ + public int nextInt() + { + return generator.nextInt(); + } + /** * Returns the next pseudorandom uniformly distributed {@link IntValue} between 0 (inclusive) and the specified * value (exclusive) @@ -333,7 +352,8 @@ public ByteValue nextByteValue( byte bound ) } /** - * Returns the next pseudorandom uniformly distributed {@link FloatValue} + * Returns the next pseudorandom uniformly distributed {@link FloatValue} between 0 (inclusive) and the specified + * 1.0 (exclusive) * * @return the next pseudorandom uniformly distributed {@link FloatValue} */ @@ -342,6 +362,17 @@ public FloatValue nextFloatValue() return floatValue( generator.nextFloat() ); } + /** + * Returns the next pseudorandom uniformly distributed {@code float} between 0 (inclusive) and the specified + * 1.0 (exclusive) + * + * @return the next pseudorandom uniformly distributed {@code float} + */ + public float nextFloat() + { + return generator.nextFloat(); + } + /** * Returns the next pseudorandom uniformly distributed {@link DoubleValue} * @@ -419,9 +450,9 @@ public TextValue nextDigitString( int minLength, int maxLength ) * * @return a {@link TextValue} consisting only of ascii alphabetic characters. */ - public TextValue nextAlphaString() + public TextValue nextAlphaTextValue() { - return nextAlphaString( configuration.stringMinLength(), configuration.stringMaxLength() ); + return nextAlphaTextValue( configuration.stringMinLength(), configuration.stringMaxLength() ); } /** @@ -431,7 +462,7 @@ public TextValue nextAlphaString() * @param maxLength the maximum length of the string * @return a {@link TextValue} consisting only of ascii alphabetic characters. */ - public TextValue nextAlphaString( int minLength, int maxLength ) + public TextValue nextAlphaTextValue( int minLength, int maxLength ) { int length = intBetween( minLength, maxLength ); byte[] bytes = new byte[length]; @@ -458,9 +489,9 @@ public TextValue nextAlphaString( int minLength, int maxLength ) * * @return a {@link TextValue} consisting only of ascii alphabetic and numerical characters. */ - public TextValue nextAlphaNumericString() + public TextValue nextAlphaNumericTextValue() { - return nextAlphaNumericString( configuration.stringMinLength(), configuration.stringMaxLength() ); + return nextAlphaNumericTextValue( configuration.stringMinLength(), configuration.stringMaxLength() ); } /** @@ -470,7 +501,7 @@ public TextValue nextAlphaNumericString() * @param maxLength the maximum length of the string * @return a {@link TextValue} consisting only of ascii alphabetic and numerical characters. */ - public TextValue nextAlphaNumericString( int minLength, int maxLength ) + public TextValue nextAlphaNumericTextValue( int minLength, int maxLength ) { int length = intBetween( minLength, maxLength ); byte[] bytes = new byte[length]; @@ -506,9 +537,9 @@ public TextValue nextAlphaNumericString( int minLength, int maxLength ) * * @return a {@link TextValue} consisting only of ascii characters. */ - public TextValue nextAsciiString() + public TextValue nextAsciiTextValue() { - return nextAsciiString( configuration.stringMinLength(), configuration.stringMaxLength() ); + return nextAsciiTextValue( configuration.stringMinLength(), configuration.stringMaxLength() ); } /** @@ -518,7 +549,7 @@ public TextValue nextAsciiString() * @param maxLength the maximum length of the string * @return a {@link TextValue} consisting only of ascii characters. */ - public TextValue nextAsciiString( int minLength, int maxLength ) + public TextValue nextAsciiTextValue( int minLength, int maxLength ) { int length = intBetween( minLength, maxLength ); byte[] bytes = new byte[length]; @@ -538,9 +569,9 @@ public TextValue nextAsciiString( int minLength, int maxLength ) * * @return a {@link TextValue} consisting only of printable ascii characters. */ - public TextValue nextPrintableAsciiString() + public TextValue nextPrintableAsciiTextValue() { - return nextPrintableAsciiString( configuration.stringMinLength(), configuration.stringMaxLength() ); + return nextPrintableAsciiTextValue( configuration.stringMinLength(), configuration.stringMaxLength() ); } /** @@ -550,7 +581,7 @@ public TextValue nextPrintableAsciiString() * @param maxLength the maximum length of the string * @return a {@link TextValue} consisting only of printable ascii characters. */ - public TextValue nextPrintableAsciiString( int minLength, int maxLength ) + public TextValue nextPrintableAsciiTextValue( int minLength, int maxLength ) { int length = intBetween( minLength, maxLength ); byte[] bytes = new byte[length]; @@ -570,9 +601,9 @@ public TextValue nextPrintableAsciiString( int minLength, int maxLength ) * * @return a generator {@link TextValue}. */ - public TextValue nextString() + public TextValue nextTextValue() { - return nextString( configuration.stringMinLength(), configuration.stringMaxLength() ); + return nextTextValue( configuration.stringMinLength(), configuration.stringMaxLength() ); } /** @@ -582,7 +613,7 @@ public TextValue nextString() * @param maxLength the maximum length of the string * @return a generator {@link TextValue}. */ - public TextValue nextString( int minLength, int maxLength ) + public TextValue nextTextValue( int minLength, int maxLength ) { int length = intBetween( minLength, maxLength ); UTF8StringValueBuilder builder = new UTF8StringValueBuilder( nextPowerOf2( length ) ); @@ -634,7 +665,7 @@ public Value nextValue() case SHORT: return nextShortValue(); case STRING: - return nextString(); + return nextTextValue(); case INT: return nextIntValue(); case LONG: @@ -1097,7 +1128,7 @@ public TextArray nextStringArray( int minLength, int maxLength ) String[] strings = new String[length]; for ( int i = 0; i < length; i++ ) { - strings[i] = nextString().stringValue(); + strings[i] = nextTextValue().stringValue(); } return Values.stringArray( strings ); } @@ -1289,26 +1320,71 @@ public void among( List among, Consumer action ) } } - private Instant randomInstant() + public int intBetween( int min, int max ) { - return Instant.ofEpochSecond( - nextLong( LocalDateTime.MIN.toEpochSecond( UTC ), LocalDateTime.MAX.toEpochSecond( UTC ) ), - nextLong( NANOS_PER_SECOND ) ); + return min + generator.nextInt( max - min + 1 ); } - private int nextPowerOf2( int i ) + public long nextLong( long bound ) { - return 1 << (32 - Integer.numberOfLeadingZeros( i )); + return abs( generator.nextLong() ) % bound; } - private int intBetween( int min, int max ) + public long nextLong( ) { - return min + generator.nextInt( max - min + 1 ); + return generator.nextLong(); } - private long nextLong( long bound ) + @SuppressWarnings( "unchecked" ) + public T[] selection( T[] among, int min, int max, boolean allowDuplicates ) { - return abs( generator.nextLong() ) % bound; + assert min <= max; + int diff = min == max ? 0 : generator.nextInt( max - min ); + int length = min + diff; + T[] result = (T[]) Array.newInstance( among.getClass().getComponentType(), length ); + for ( int i = 0; i < length; i++ ) + { + while ( true ) + { + T candidate = among( among ); + if ( !allowDuplicates && contains( result, candidate ) ) + { // Try again + continue; + } + result[i] = candidate; + break; + } + } + return result; + } + + private static boolean contains( T[] array, T contains ) + { + for ( T item : array ) + { + if ( nullSafeEquals( item, contains ) ) + { + return true; + } + } + return false; + } + + private static boolean nullSafeEquals( T first, T other ) + { + return first == null ? other == null : first.equals( other ); + } + + private Instant randomInstant() + { + return Instant.ofEpochSecond( + nextLong( LocalDateTime.MIN.toEpochSecond( UTC ), LocalDateTime.MAX.toEpochSecond( UTC ) ), + nextLong( NANOS_PER_SECOND ) ); + } + + private int nextPowerOf2( int i ) + { + return 1 << (32 - Integer.numberOfLeadingZeros( i )); } private long nextLong( long origin, long bound ) diff --git a/community/random-values/src/main/java/org/neo4j/values/storable/UTF8StringValueBuilder.java b/community/random-values/src/main/java/org/neo4j/values/storable/UTF8StringValueBuilder.java index 182fd8f6f3395..e7ddc28b7cfd9 100644 --- a/community/random-values/src/main/java/org/neo4j/values/storable/UTF8StringValueBuilder.java +++ b/community/random-values/src/main/java/org/neo4j/values/storable/UTF8StringValueBuilder.java @@ -89,8 +89,8 @@ else if ( codePoint < 0x10000 ) else { //Require four bytes - will be laid out like: - //b1 b2 b3 - //11110xxx 10xxxxxx 10xxxxxx + //b1 b2 b3 b4 + //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx add( (byte) (0b1111_0000 | (0b0001_1111 & (codePoint >> 18))) ); add( (byte) (0b1000_0000 | (0b0011_1111 & (codePoint >> 12))) ); add( (byte) (0b1000_0000 | (0b0011_1111 & (codePoint >> 6))) ); diff --git a/community/random-values/src/test/java/org/neo4j/values/storable/RandomValuesTest.java b/community/random-values/src/test/java/org/neo4j/values/storable/RandomValuesTest.java index ab089752edda9..b68e3bb399546 100644 --- a/community/random-values/src/test/java/org/neo4j/values/storable/RandomValuesTest.java +++ b/community/random-values/src/test/java/org/neo4j/values/storable/RandomValuesTest.java @@ -222,7 +222,7 @@ public void nextAlphaString() .collect( Collectors.toSet() ); for ( int i = 0; i < ITERATIONS; i++ ) { - TextValue textValue = randomValues.nextAlphaString( 5, 10 ); + TextValue textValue = randomValues.nextAlphaTextValue( 5, 10 ); String asString = textValue.stringValue(); for ( int j = 0; j < asString.length(); j++ ) { @@ -241,7 +241,7 @@ public void nextAlphaNumericString() .collect( Collectors.toSet() ); for ( int i = 0; i < ITERATIONS; i++ ) { - TextValue textValue = randomValues.nextAlphaNumericString( 10, 20 ); + TextValue textValue = randomValues.nextAlphaNumericTextValue( 10, 20 ); String asString = textValue.stringValue(); for ( int j = 0; j < asString.length(); j++ ) { @@ -259,7 +259,7 @@ public void nextAsciiString() { for ( int i = 0; i < ITERATIONS; i++ ) { - TextValue textValue = randomValues.nextAsciiString( 10, 20 ); + TextValue textValue = randomValues.nextAsciiTextValue( 10, 20 ); String asString = textValue.stringValue(); int length = asString.length(); assertThat( length, greaterThanOrEqualTo( 10 ) ); @@ -272,7 +272,7 @@ public void nextPrintableAsciiString() { for ( int i = 0; i < ITERATIONS; i++ ) { - TextValue textValue = randomValues.nextPrintableAsciiString( 10, 20 ); + TextValue textValue = randomValues.nextPrintableAsciiTextValue( 10, 20 ); String asString = textValue.stringValue(); int length = asString.length(); assertThat( length, greaterThanOrEqualTo( 10 ) ); @@ -285,7 +285,7 @@ public void nextString() { for ( int i = 0; i < ITERATIONS; i++ ) { - TextValue textValue = randomValues.nextString( 10, 20 ); + TextValue textValue = randomValues.nextTextValue( 10, 20 ); String asString = textValue.stringValue(); int length = asString.codePointCount( 0, asString.length() ); assertThat( length, greaterThanOrEqualTo( 10 ) ); diff --git a/stresstests/pom.xml b/stresstests/pom.xml index 551c169f5583a..fb9091eda8cec 100644 --- a/stresstests/pom.xml +++ b/stresstests/pom.xml @@ -80,7 +80,13 @@ test-jar test - + + org.neo4j + neo4j-random-values + ${project.version} + test + + org.neo4j neo4j-io ${project.version} diff --git a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java index ab1da8a417ba0..cccf00958d7f0 100644 --- a/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java +++ b/stresstests/src/test/java/org/neo4j/causalclustering/stresstests/CreateNodesWithProperties.java @@ -30,7 +30,7 @@ import org.neo4j.helper.Workload; import org.neo4j.kernel.impl.util.CappedLogger; import org.neo4j.logging.Log; -import org.neo4j.test.Randoms; +import org.neo4j.values.storable.RandomValues; class CreateNodesWithProperties extends Workload { @@ -65,7 +65,7 @@ public void prepare() protected void doWork() { txLogger.info( "SuccessCount: " + txSuccessCount + " FailCount: " + txFailCount ); - Randoms randoms = new Randoms(); + RandomValues randomValues = RandomValues.create(); try { @@ -74,7 +74,7 @@ protected void doWork() Node node = db.createNode( label ); for ( int i = 1; i <= 8; i++ ) { - node.setProperty( prop( i ), randoms.propertyValue() ); + node.setProperty( prop( i ), randomValues.nextValue().asObject() ); } tx.success(); } );