Skip to content

Commit

Permalink
Merge pull request #7800 from MishaDemianenko/3.1-rel-type-id-limit
Browse files Browse the repository at this point in the history
Update relationship type to take up to 24 bits in high limit format
  • Loading branch information
tinwelint committed Sep 14, 2016
2 parents a42a182 + c7bc207 commit 9da1520
Show file tree
Hide file tree
Showing 20 changed files with 256 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.helpers.progress.ProgressMonitorFactory;
import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.logging.NullLogService;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.standard.StandardV3_0;
import org.neo4j.logging.NullLogProvider;
import org.neo4j.test.Randoms;
Expand Down Expand Up @@ -162,7 +162,7 @@ public void shouldImportCsvData() throws Exception
ExecutionMonitor processorAssigner = eagerRandomSaturation( config.maxNumberOfProcessors() );
final BatchImporter inserter = new ParallelBatchImporter( directory.graphDbDir(),
new DefaultFileSystemAbstraction(), config, NullLogService.getInstance(),
processorAssigner, EMPTY, new Config( MapUtil.stringMap( GraphDatabaseSettings.record_format.name(), getFormatName() ) ) );
processorAssigner, EMPTY, Config.empty(), getFormat() );

boolean successful = false;
IdGroupDistribution groups = new IdGroupDistribution( NODE_COUNT, 5, random.random() );
Expand Down Expand Up @@ -234,9 +234,9 @@ private void assertConsistent( File storeDir ) throws ConsistencyCheckIncomplete
result.isSuccessful() );
}

protected String getFormatName()
protected RecordFormats getFormat()
{
return StandardV3_0.NAME;
return StandardV3_0.RECORD_FORMATS;
}

public abstract static class InputIdGenerator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
import org.neo4j.kernel.impl.api.CountsAccessor;
import org.neo4j.kernel.impl.store.counts.CountsTracker;
import org.neo4j.kernel.impl.store.counts.ReadOnlyCountsTracker;
import org.neo4j.kernel.impl.store.format.CapabilityType;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormatSelector;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.id.IdGeneratorFactory;
import org.neo4j.kernel.impl.store.id.IdType;
Expand Down Expand Up @@ -168,12 +171,12 @@ private void verifyRecordFormat()
{
try
{
String expectedStoreVersion = recordFormats.storeVersion();
String actualStoreVersion = versionLongToString( getRecord( pageCache, neoStoreFileName, STORE_VERSION ) );
if ( !expectedStoreVersion.equals( actualStoreVersion ) )
String storeVersion = versionLongToString( getRecord( pageCache, neoStoreFileName, STORE_VERSION ) );
RecordFormats storeFormat = RecordFormatSelector.selectForVersion( storeVersion );
if ( !isCompatibleFormats( storeFormat ) )
{
throw new StoreUpgrader.UnexpectedUpgradingStoreVersionException( neoStoreFileName.getName(),
actualStoreVersion );
storeVersion );
}
}
catch ( NoSuchFileException e )
Expand All @@ -188,6 +191,13 @@ private void verifyRecordFormat()
}
}

private boolean isCompatibleFormats( RecordFormats storeFormat )
{
return FormatFamily.isSameFamily( recordFormats, storeFormat ) &&
recordFormats.hasSameCapabilities( storeFormat, CapabilityType.FORMAT ) &&
recordFormats.generation() >= storeFormat.generation();
}

private void closeStore( StoreType type )
{
int i = type.ordinal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public enum Capability
*/
DENSE_NODES( CapabilityType.FORMAT, CapabilityType.STORE ),

/**
* 3 bytes relationship type support
*/
RELATIONSHIP_TYPE_3BYTES( CapabilityType.FORMAT, CapabilityType.STORE ),

/**
* Store has version trailers in the end of cleanly shut down store
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ private void migrateWithBatchImporter( File storeDir, File migrationDir, long la
BatchImporter importer = new ParallelBatchImporter( migrationDir.getAbsoluteFile(), fileSystem,
importConfig, logService,
withDynamicProcessorAssignment( migrationBatchImporterMonitor( legacyStore, progressMonitor,
importConfig ), importConfig ), additionalInitialIds, config );
importConfig ), importConfig ), additionalInitialIds, config, newFormat );
InputIterable<InputNode> nodes =
legacyNodesAsInput( legacyStore, requiresPropertyMigration, nodeInputCursors );
InputIterable<InputRelationship> relationships =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
import static java.lang.Math.max;
import static java.lang.String.format;
import static java.lang.System.currentTimeMillis;

import static org.neo4j.helpers.Format.bytes;
import static org.neo4j.helpers.collection.Iterators.asSet;
import static org.neo4j.io.ByteUnit.mebiBytes;
Expand Down Expand Up @@ -90,6 +89,7 @@ public class ParallelBatchImporter implements BatchImporter
private final ExecutionMonitor executionMonitor;
private final AdditionalInitialIds additionalInitialIds;
private final Config dbConfig;
private final RecordFormats recordFormats;

/**
* Advanced usage of the parallel batch importer, for special and very specific cases. Please use
Expand All @@ -98,13 +98,14 @@ public class ParallelBatchImporter implements BatchImporter
public ParallelBatchImporter( File storeDir, FileSystemAbstraction fileSystem, Configuration config,
LogService logService, ExecutionMonitor executionMonitor,
AdditionalInitialIds additionalInitialIds,
Config dbConfig )
Config dbConfig, RecordFormats recordFormats )
{
this.storeDir = storeDir;
this.fileSystem = fileSystem;
this.config = config;
this.logService = logService;
this.dbConfig = dbConfig;
this.recordFormats = recordFormats;
this.log = logService.getInternalLogProvider().getLog( getClass() );
this.executionMonitor = executionMonitor;
this.additionalInitialIds = additionalInitialIds;
Expand All @@ -119,7 +120,8 @@ public ParallelBatchImporter( File storeDir, Configuration config, LogService lo
ExecutionMonitor executionMonitor, Config dbConfig )
{
this( storeDir, new DefaultFileSystemAbstraction(), config, logService,
withDynamicProcessorAssignment( executionMonitor, config ), EMPTY, dbConfig );
withDynamicProcessorAssignment( executionMonitor, config ), EMPTY, dbConfig,
RecordFormatSelector.selectForConfig( dbConfig, NullLogProvider.getInstance() ));
}

@Override
Expand All @@ -135,7 +137,6 @@ public void doImport( Input input ) throws IOException
boolean hasBadEntries = false;
File badFile = new File( storeDir, Configuration.BAD_FILE_NAME );
CountingStoreUpdateMonitor storeUpdateMonitor = new CountingStoreUpdateMonitor();
RecordFormats recordFormats = RecordFormatSelector.selectForConfig( dbConfig, NullLogProvider.getInstance() );
try ( BatchingNeoStores neoStore = new BatchingNeoStores( fileSystem, storeDir, recordFormats, config, logService,
additionalInitialIds, dbConfig );
CountsAccessor.Updater countsUpdater = neoStore.getCountsStore().reset(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
*/
public class RelationshipGroupCache implements Iterable<RelationshipGroupRecord>, AutoCloseable
{
public static final int GROUP_ENTRY_SIZE = 1/*header*/ + 2/*type*/ + 6/*relationship id*/*3/*all directions*/;
public static final int GROUP_ENTRY_SIZE = 1/*header*/ + 3/*type*/ + 6/*relationship id*/*3/*all directions*/;

private final ByteArray groupCountCache;
private final ByteArray cache;
Expand Down Expand Up @@ -160,10 +160,10 @@ public boolean put( RelationshipGroupRecord groupRecord )

// Put the group at this index
cache.setByte( index, 0, (byte) 1 );
cache.setShort( index, 1, (short) groupRecord.getType() );
cache.set6ByteLong( index, 1 + 2, groupRecord.getFirstOut() );
cache.set6ByteLong( index, 1 + 2 + 6, groupRecord.getFirstIn() );
cache.set6ByteLong( index, 1 + 2 + 6 + 6, groupRecord.getFirstLoop() );
cache.set3ByteInt( index, 1, groupRecord.getType() );
cache.set6ByteLong( index, 1 + 3, groupRecord.getFirstOut() );
cache.set6ByteLong( index, 1 + 3 + 6, groupRecord.getFirstIn() );
cache.set6ByteLong( index, 1 + 3 + 6 + 6, groupRecord.getFirstLoop() );
return true;
}

Expand All @@ -183,7 +183,7 @@ private long scanForFreeFrom( long startIndex, int groupCount, int type )

if ( desiredIndex == -1 )
{
int existingType = cache.getShort( candidateIndex, 1 ) & 0xFFFF;
int existingType = cache.get3ByteInt( candidateIndex, 1 );
if ( existingType == type )
{
throw new IllegalStateException( "Tried to put multiple groups with same type " + type );
Expand Down Expand Up @@ -255,10 +255,10 @@ protected RelationshipGroupRecord fetchNextOrNull()
{
// Here we have an alive group
group = new RelationshipGroupRecord( -1 ).initialize( true,
cache.getShort( cursor, 1 ) & 0xFFFF,
cache.get6ByteLong( cursor, 1 + 2 ),
cache.get6ByteLong( cursor, 1 + 2 + 6 ),
cache.get6ByteLong( cursor, 1 + 2 + 6 + 6 ),
cache.get3ByteInt( cursor, 1 ),
cache.get6ByteLong( cursor, 1 + 3 ),
cache.get6ByteLong( cursor, 1 + 3 + 6 ),
cache.get6ByteLong( cursor, 1 + 3 + 6 + 6 ),
nodeId,
// Special: we want to convey information about how many groups are coming
// after this one so that chains can be ordered accordingly in the store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,24 @@ public interface ByteArray extends NumberArray<ByteArray>
* @param value the long value to set at the given offset at the given array index.
*/
void setLong( long index, int offset, long value );

/**
* Gets a part of an item, at the given {@code index}. An item in this array can consist of
* multiple values. This call will get a 3-byte int at the given {@code offset}.
*
* @param index array index to get.
* @param offset offset into this index to get the value from.
* @return the 3-byte int at the given offset at the given array index.
*/
int get3ByteInt( long index, int offset );

/**
* Sets a part of an item, at the given {@code index}. An item in this array can consist of
* multiple values. This call will set a 3-byte int at the given {@code offset}.
*
* @param index array index to get.
* @param offset offset into this index to set the value for.
* @param value the 3-byte int value to set at the given offset at the given array index.
*/
void set3ByteInt( long index, int offset, int value );
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.nio.ByteBuffer;

import static org.neo4j.unsafe.impl.batchimport.cache.HeapByteArray.get3ByteIntFromByteBuffer;
import static org.neo4j.unsafe.impl.batchimport.cache.HeapByteArray.get6BLongFromByteBuffer;

public class DynamicByteArray extends DynamicNumberArray<ByteArray> implements ByteArray
Expand Down Expand Up @@ -85,6 +86,14 @@ public int getInt( long index, int offset )
return chunk != null ? chunk.getInt( index, offset ) : defaultValueConvenienceBuffer.getInt( offset );
}

@Override
public int get3ByteInt( long index, int offset )
{
ByteArray chunk = chunkOrNullAt( index );
return chunk != null ? chunk.get3ByteInt( index, offset ) :
get3ByteIntFromByteBuffer( defaultValueConvenienceBuffer, offset );
}

@Override
public long get6ByteLong( long index, int offset )
{
Expand Down Expand Up @@ -136,6 +145,12 @@ public void setLong( long index, int offset, long value )
at( index ).setLong( index, offset, value );
}

@Override
public void set3ByteInt( long index, int offset, int value )
{
at( index ).set3ByteInt( index, offset, value );
}

@Override
protected ByteArray addChunk( long chunkSize, long base )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,26 @@ public int getInt( long index, int offset )
return buffer.getInt( index( index, offset ) );
}

@Override
public int get3ByteInt( long index, int offset )
{
int address = index( index, offset );
return get3ByteIntFromByteBuffer( buffer, address );
}

@Override
public long get6ByteLong( long index, int offset )
{
return get6BLongFromByteBuffer( buffer, index( index, offset ) );
}

protected static int get3ByteIntFromByteBuffer( ByteBuffer buffer, int address )
{
int lowWord = buffer.getShort( address ) & 0xFFFF;
int highByte = buffer.get( address + Short.BYTES );
return lowWord | (highByte << Short.SIZE);
}

protected static long get6BLongFromByteBuffer( ByteBuffer buffer, int startOffset )
{
long low4b = buffer.getInt( startOffset ) & 0xFFFFFFFFL;
Expand Down Expand Up @@ -168,6 +182,14 @@ public void setLong( long index, int offset, long value )
buffer.putLong( index( index, offset ), value );
}

@Override
public void set3ByteInt( long index, int offset, int value )
{
int address = index( index, offset );
buffer.putShort( address, (short) value );
buffer.put( address + Short.BYTES, (byte) (value >>> Short.SIZE) );
}

private int index( long index, int offset )
{
return toIntExact( (rebase( index ) * itemSize) + offset );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,23 @@ public void setLong( long index, int offset, long value )
UnsafeUtil.putLong( address( index, offset ), value );
}

@Override
public int get3ByteInt( long index, int offset )
{
long address = address( index, offset );
int lowWord = UnsafeUtil.getShort( address ) & 0xFFFF;
byte highByte = UnsafeUtil.getByte( address + Short.BYTES );
return lowWord | (highByte << Short.SIZE);
}

@Override
public void set3ByteInt( long index, int offset, int value )
{
long address = address( index, offset );
UnsafeUtil.putShort( address, (short) value );
UnsafeUtil.putByte( address + Short.BYTES, (byte) (value >>> Short.SIZE) );
}

private long address( long index, int offset )
{
return address + (rebase( index ) * itemSize) + offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private int[] scrambledTypes( int count )
int[] types = new int[count];
for ( int i = 0; i < count; i++ )
{
types[i] = i;
types[i] = i + Short.MAX_VALUE ;
}

for ( int i = 0; i < 10; i++ )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
@RunWith( Parameterized.class )
public class ByteArrayTest
{
private static final byte[] DEFAULT = new byte[15];
private static final byte[] DEFAULT = new byte[25];

@Parameters
public static Collection<Supplier<ByteArray>> data()
Expand Down Expand Up @@ -74,12 +74,14 @@ public void shouldSetAndGetBasicTypes() throws Exception
array.setShort( 0, 1, (short) 1234 );
array.setInt( 0, 5, 12345 );
array.setLong( 0, 9, Long.MAX_VALUE - 100 );
array.set3ByteInt( 0, 17, 76767 );

// THEN
assertEquals( (byte) 123, array.getByte( 0, 0 ) );
assertEquals( (short) 1234, array.getShort( 0, 1 ) );
assertEquals( 12345, array.getInt( 0, 5 ) );
assertEquals( Long.MAX_VALUE - 100, array.getLong( 0, 9 ) );
assertEquals( 76767, array.get3ByteInt( 0, 17 ) );
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import org.neo4j.kernel.impl.api.index.BatchingMultipleIndexPopulator;
import org.neo4j.kernel.impl.api.index.MultipleIndexPopulator;
import org.neo4j.kernel.impl.logging.NullLogService;
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.RepeatRule;
Expand Down Expand Up @@ -298,8 +300,11 @@ private void changeRandomNode( GraphDatabaseService db, int nodeCount, Randoms r

private void createRandomData( int count ) throws IOException
{
Config config = Config.empty();
RecordFormats recordFormats =
RecordFormatSelector.selectForConfig( config, NullLogProvider.getInstance() );
BatchImporter importer = new ParallelBatchImporter( directory.graphDbDir(), fs,
DEFAULT, NullLogService.getInstance(), ExecutionMonitors.invisible(), EMPTY, Config.empty() );
DEFAULT, NullLogService.getInstance(), ExecutionMonitors.invisible(), EMPTY, config, recordFormats );
importer.doImport( new RandomDataInput( count ) );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public class HighLimit extends BaseRecordFormats

public HighLimit()
{
super( STORE_VERSION, 3, Capability.DENSE_NODES, Capability.SCHEMA, Capability.LUCENE_5 );
super( STORE_VERSION, 3, Capability.DENSE_NODES, Capability.RELATIONSHIP_TYPE_3BYTES, Capability.SCHEMA,
Capability.LUCENE_5 );
}

@Override
Expand Down

0 comments on commit 9da1520

Please sign in to comment.