Skip to content

Commit

Permalink
LimitedRecordGenerators uses Randoms to be more usable elsewhere
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint committed Apr 17, 2016
1 parent fbe5c5f commit 1beb8bf
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 35 deletions.
Expand Up @@ -31,28 +31,31 @@
import org.neo4j.kernel.impl.store.record.RelationshipRecord;
import org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord;
import org.neo4j.test.RandomRule;
import org.neo4j.test.Randoms;

import static java.lang.Long.max;
import static java.lang.Math.abs;
import static java.lang.Math.toIntExact;

public class LimitedRecordGenerators implements RecordGenerators
{
static final long NULL = -1;

private final RandomRule random;
private final Randoms random;
private final int entityBits;
private final int propertyBits;
private final int nodeLabelBits;
private final int tokenBits;
private final long nullValue;
private final float fractionNullValues;

public LimitedRecordGenerators( RandomRule random, int entityBits, int propertyBits, int nodeLabelBits,
public LimitedRecordGenerators( Randoms random, int entityBits, int propertyBits, int nodeLabelBits,
int tokenBits, long nullValue )
{
this( random, entityBits, propertyBits, nodeLabelBits, tokenBits, nullValue, 0.2f );
}

public LimitedRecordGenerators( RandomRule random, int entityBits, int propertyBits, int nodeLabelBits,
public LimitedRecordGenerators( Randoms random, int entityBits, int propertyBits, int nodeLabelBits,
int tokenBits, long nullValue, float fractionNullValues )
{
this.random = random;
Expand All @@ -67,19 +70,16 @@ public LimitedRecordGenerators( RandomRule random, int entityBits, int propertyB
@Override
public Generator<RelationshipTypeTokenRecord> relationshipTypeToken()
{
return (recordSize, format) -> new RelationshipTypeTokenRecord( randomId() ).initialize( random.nextBoolean(),
return (recordSize, format, recordId) -> new RelationshipTypeTokenRecord( toIntExact( recordId ) ).initialize(
random.nextBoolean(),
randomInt( tokenBits ) );
}

private int randomId()
{
return random.nextInt( 5 );
}

@Override
public Generator<RelationshipGroupRecord> relationshipGroup()
{
return (recordSize, format) -> new RelationshipGroupRecord( randomId() ).initialize( random.nextBoolean(),
return (recordSize, format, recordId) -> new RelationshipGroupRecord( recordId ).initialize(
random.nextBoolean(),
randomInt( tokenBits ),
randomLongOrOccasionallyNull( entityBits ),
randomLongOrOccasionallyNull( entityBits ),
Expand All @@ -91,7 +91,8 @@ public Generator<RelationshipGroupRecord> relationshipGroup()
@Override
public Generator<RelationshipRecord> relationship()
{
return (recordSize, format) -> new RelationshipRecord( randomId() ).initialize( random.nextBoolean(),
return (recordSize, format, recordId) -> new RelationshipRecord( recordId ).initialize(
random.nextBoolean(),
randomLongOrOccasionallyNull( propertyBits ),
random.nextLong( entityBits ), random.nextLong( entityBits ), randomInt( tokenBits ),
randomLongOrOccasionallyNull( entityBits ), randomLongOrOccasionallyNull( entityBits ),
Expand All @@ -102,15 +103,17 @@ public Generator<RelationshipRecord> relationship()
@Override
public Generator<PropertyKeyTokenRecord> propertyKeyToken()
{
return (recordSize, format) -> new PropertyKeyTokenRecord( randomId() ).initialize( random.nextBoolean(),
random.nextInt( tokenBits ), abs( random.nextInt() ) );
return (recordSize, format, recordId) -> new PropertyKeyTokenRecord( toIntExact( recordId ) ).initialize(
random.nextBoolean(),
random.nextInt( tokenBits ),
abs( random.nextInt() ) );
}

@Override
public Generator<PropertyRecord> property()
{
return (recordSize, format) -> {
PropertyRecord record = new PropertyRecord( randomId() );
return (recordSize, format, recordId) -> {
PropertyRecord record = new PropertyRecord( recordId );
int maxProperties = random.intBetween( 1, 4 );
StandaloneDynamicRecordAllocator stringAllocator = new StandaloneDynamicRecordAllocator();
StandaloneDynamicRecordAllocator arrayAllocator = new StandaloneDynamicRecordAllocator();
Expand Down Expand Up @@ -139,27 +142,30 @@ public Generator<PropertyRecord> property()
@Override
public Generator<NodeRecord> node()
{
return (recordSize, format) -> new NodeRecord( randomId() ).initialize(
random.nextBoolean(), randomLongOrOccasionallyNull( propertyBits ), random.nextBoolean(),
return (recordSize, format, recordId) -> new NodeRecord( recordId ).initialize(
random.nextBoolean(),
randomLongOrOccasionallyNull( propertyBits ),
random.nextBoolean(),
randomLongOrOccasionallyNull( entityBits ),
randomLongOrOccasionallyNull( nodeLabelBits, 0 ) );
}

@Override
public Generator<LabelTokenRecord> labelToken()
{
return (recordSize, format) -> new LabelTokenRecord( randomId() ).initialize(
random.nextBoolean(), random.nextInt( tokenBits ) );
return (recordSize, format, recordId) -> new LabelTokenRecord( toIntExact( recordId ) ).initialize(
random.nextBoolean(),
random.nextInt( tokenBits ) );
}

@Override
public Generator<DynamicRecord> dynamic()
{
return (recordSize, format) -> {
return (recordSize, format, recordId) -> {
int dataSize = recordSize - format.getRecordHeaderSize();
int length = random.nextBoolean() ? dataSize : random.nextInt( dataSize );
long next = length == dataSize ? randomLong( propertyBits ) : nullValue;
DynamicRecord record = new DynamicRecord( random.nextInt( 1, 5 ) ).initialize( random.nextBoolean(),
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 );
Expand Down
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.kernel.impl.store.format;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
Expand Down Expand Up @@ -47,12 +48,14 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import static org.neo4j.io.ByteUnit.kibiBytes;
import static org.neo4j.kernel.impl.store.record.RecordLoad.NORMAL;

@Ignore( "Not a test, a base class for testing formats" )
public abstract class RecordFormatTest
{
private static final int PAGE_SIZE = 1_024;
private static final int PAGE_SIZE = (int) kibiBytes( 1 );

// Whoever is hit first
private static final long TEST_ITERATIONS = 20_000;
Expand All @@ -72,12 +75,21 @@ public abstract class RecordFormatTest
public RecordKeys keys = FullyCoveringRecordKeys.INSTANCE;

private final RecordFormats formats;
private final RecordGenerators generators;
private final int entityBits;
private final int propertyBits;
private RecordGenerators generators;

protected RecordFormatTest( RecordFormats formats, RecordGenerators generators )
protected RecordFormatTest( RecordFormats formats, int entityBits, int propertyBits )
{
this.formats = formats;
this.generators = generators;
this.entityBits = entityBits;
this.propertyBits = propertyBits;
}

@Before
public void before()
{
generators = new LimitedRecordGenerators( random.randoms(), entityBits, propertyBits, 40, 16, -1 );
}

@Test
Expand Down Expand Up @@ -158,7 +170,7 @@ private <R extends AbstractBaseRecord> void verifyWriteAndRead(
long i = 0;
for ( ; i < TEST_ITERATIONS && currentTimeMillis() < endTime; i++ )
{
R written = generator.get( recordSize, format );
R written = generator.get( recordSize, format, i % 5 );
R read = format.newRecord();
try
{
Expand Down
Expand Up @@ -33,7 +33,7 @@ public interface RecordGenerators
{
interface Generator<RECORD extends AbstractBaseRecord>
{
RECORD get( int recordSize, RecordFormat<RECORD> format );
RECORD get( int recordSize, RecordFormat<RECORD> format, long id );
}

Generator<NodeRecord> node();
Expand Down
Expand Up @@ -23,10 +23,8 @@

public class StandardRecordFormatTest extends RecordFormatTest
{
private static final RecordGenerators LOW_LIMITS = new LimitedRecordGenerators( random, 35, 36, 40, 16, NULL );

public StandardRecordFormatTest()
{
super( StandardV3_0.RECORD_FORMATS, LOW_LIMITS );
super( StandardV3_0.RECORD_FORMATS, 35, 36 );
}
}
31 changes: 31 additions & 0 deletions community/kernel/src/test/java/org/neo4j/test/Randoms.java
Expand Up @@ -26,6 +26,7 @@
import org.neo4j.helpers.ArrayUtil;

import static java.lang.Integer.bitCount;
import static java.lang.Math.abs;

/**
* Set of useful randomizing utilities, for example randomizing a string or property value of random type and value.
Expand Down Expand Up @@ -252,4 +253,34 @@ private char symbol()
throw new IllegalArgumentException( "Unknown symbol range " + range );
}
}

public long nextLong( long bound )
{
return abs( random.nextLong() ) % bound;
}

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();
}
}
Expand Up @@ -19,16 +19,12 @@
*/
package org.neo4j.kernel.impl.store.format.highlimit;

import org.neo4j.kernel.impl.store.format.LimitedRecordGenerators;
import org.neo4j.kernel.impl.store.format.RecordFormatTest;
import org.neo4j.kernel.impl.store.format.RecordGenerators;

public class HighLimitRecordFormatTest extends RecordFormatTest
{
private static final RecordGenerators HIGH_LIMITS = new LimitedRecordGenerators( random, 50, 50, 50, 16, NULL );

public HighLimitRecordFormatTest()
{
super( HighLimit.RECORD_FORMATS, HIGH_LIMITS );
super( HighLimit.RECORD_FORMATS, 50, 50 );
}
}

0 comments on commit 1beb8bf

Please sign in to comment.