@Override public long getNextRecordReference( RECORD record ) { return Record.NULL_REFERENCE.intValue(); }
@Override public List<RECORD> getRecords( long firstId, RecordLoad mode ) { if ( Record.NULL_REFERENCE.is( firstId ) ) { return Collections.emptyList(); } List<RECORD> records = new ArrayList<>(); long id = firstId; try ( PageCursor cursor = openPageCursorForReading( firstId ) ) { RECORD record; do { record = newRecord(); getRecordByCursor( id, record, mode, cursor ); // Even unused records gets added and returned records.add( record ); id = getNextRecordReference( record ); } while ( !Record.NULL_REFERENCE.is( id ) ); } return records; }
public static RelationshipRecord rel( long id, Consumer<RelationshipRecord>... modifiers ) { RelationshipRecord record = new RelationshipRecord( id ); record.initialize( true, Record.NO_NEXT_PROPERTY.intValue(), -1, -1, 0, Record.NO_PREV_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), Record.NO_PREV_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), true, true ); for ( Consumer<RelationshipRecord> modifier : modifiers ) { modifier.accept( record ); } return record; }
@Override public void write( DynamicRecord record, PageCursor cursor, int recordSize ) { if ( record.inUse() ) { long nextBlock = record.getNextBlock(); int highByteInFirstInteger = nextBlock == Record.NO_NEXT_BLOCK.intValue() ? 0 : (int) ((nextBlock & 0xF00000000L) >> 8); highByteInFirstInteger |= Record.IN_USE.byteValue() << 28; highByteInFirstInteger |= (record.isStartRecord() ? 0 : 1) << 31; /* * First 4b * [x , ][ , ][ , ][ , ] 0: start record, 1: linked record * [ x, ][ , ][ , ][ , ] inUse * [ ,xxxx][ , ][ , ][ , ] high next block bits * [ , ][xxxx,xxxx][xxxx,xxxx][xxxx,xxxx] nr of bytes in the data field in this record * */ int firstInteger = record.getLength(); assert firstInteger < (1 << 24) - 1; firstInteger |= highByteInFirstInteger; cursor.putInt( firstInteger ); cursor.putInt( (int) nextBlock ); cursor.putBytes( record.getData() ); } else { cursor.putByte( Record.NOT_IN_USE.byteValue() ); } }
private static RelationshipRecord relationship( long id, long startNodeId, long endNodeId ) { return new RelationshipRecord( id ).initialize( true, Record.NO_NEXT_PROPERTY.longValue(), startNodeId, endNodeId, 0, NULL_REFERENCE.longValue(), NULL_REFERENCE.longValue(), NULL_REFERENCE.longValue(), NULL_REFERENCE.longValue(), false, false ); } }
private DynamicRecord readDynamicRecord( ReadableChannel channel ) throws IOException { // id+type+in_use(byte)+nr_of_bytes(int)+next_block(long) long id = channel.getLong(); assert id >= 0 && id <= (1L << 36) - 1 : id + " is not a valid dynamic record id"; int type = channel.getInt(); byte inUseFlag = channel.get(); boolean inUse = (inUseFlag & Record.IN_USE.byteValue()) != 0; DynamicRecord record = new DynamicRecord( id ); record.setInUse( inUse, type ); if ( inUse ) { record.setStartRecord( (inUseFlag & Record.FIRST_IN_CHAIN.byteValue()) != 0 ); int nrOfBytes = channel.getInt(); assert nrOfBytes >= 0 && nrOfBytes < ((1 << 24) - 1) : nrOfBytes + " is not valid for a number of bytes field of " + "a dynamic record"; long nextBlock = channel.getLong(); assert (nextBlock >= 0 && nextBlock <= (1L << 36 - 1)) || (nextBlock == Record.NO_NEXT_BLOCK.intValue()) : nextBlock + " is not valid for a next record field of " + "a dynamic record"; record.setNextBlock( nextBlock ); byte[] data = new byte[nrOfBytes]; channel.get( data, nrOfBytes ); record.setData( data ); } return record; }
private RelationshipRecord getRelationship( long relId, boolean inUse, int type ) { return new RelationshipRecord( relId ).initialize( inUse, NO_NEXT_PROPERTY.longValue(), 0, 0, type, NO_NEXT_RELATIONSHIP.longValue(), NO_NEXT_RELATIONSHIP.longValue(), NO_NEXT_RELATIONSHIP.longValue(), NO_NEXT_RELATIONSHIP.longValue(), true, false ); } }
private void writeLabelTokenRecord( WritableChannel channel, LabelTokenRecord record ) throws IOException { // id+in_use(byte)+type_blockId(int)+nr_type_records(int) byte inUse = record.inUse() ? Record.IN_USE.byteValue() : Record.NOT_IN_USE.byteValue(); channel.put( inUse ).putInt( record.getNameId() ); writeDynamicRecords( channel, record.getNameRecords() ); } }
@Override public long getNextRecordReference( RECORD record ) { return Record.NULL_REFERENCE.intValue(); }
private boolean visitPropertyRecordChain( long firstPropertyRecordId, Visitor<PropertyRecord,RuntimeException> visitor ) throws CircularPropertyRecordChainException { if ( Record.NO_NEXT_PROPERTY.is( firstPropertyRecordId ) ) { return false; } MutableLongSet visitedPropertyRecordIds = new LongHashSet( 8 ); visitedPropertyRecordIds.add( firstPropertyRecordId ); long nextProp = firstPropertyRecordId; while ( !Record.NO_NEXT_PROPERTY.is( nextProp ) ) { PropertyRecord propRecord = propertyStore.getRecord( nextProp, propertyStore.newRecord(), FORCE ); nextProp = propRecord.getNextProp(); if ( !Record.NO_NEXT_PROPERTY.is( nextProp ) && !visitedPropertyRecordIds.add( nextProp ) ) { throw new CircularPropertyRecordChainException( propRecord ); } if ( visitor.visit( propRecord ) ) { return true; } } return false; }
private DynamicRecord readDynamicRecord( ReadableChannel channel ) throws IOException { // id+type+in_use(byte)+nr_of_bytes(int)+next_block(long) long id = channel.getLong(); assert id >= 0 && id <= (1L << 36) - 1 : id + " is not a valid dynamic record id"; int type = channel.getInt(); byte inUseFlag = channel.get(); boolean inUse = (inUseFlag & Record.IN_USE.byteValue()) != 0; DynamicRecord record = new DynamicRecord( id ); record.setInUse( inUse, type ); if ( inUse ) { record.setStartRecord( (inUseFlag & Record.FIRST_IN_CHAIN.byteValue()) != 0 ); int nrOfBytes = channel.getInt(); assert nrOfBytes >= 0 && nrOfBytes < ((1 << 24) - 1) : nrOfBytes + " is not valid for a number of bytes field of " + "a dynamic record"; long nextBlock = channel.getLong(); assert (nextBlock >= 0 && nextBlock <= (1L << 36 - 1)) || (nextBlock == Record.NO_NEXT_BLOCK.intValue()) : nextBlock + " is not valid for a next record field of " + "a dynamic record"; record.setNextBlock( nextBlock ); byte[] data = new byte[nrOfBytes]; channel.get( data, nrOfBytes ); record.setData( data ); } return record; }
public static RelationshipGroupRecord relGroup( long id, Consumer<RelationshipGroupRecord>... modifiers ) { RelationshipGroupRecord record = new RelationshipGroupRecord( id ); record.initialize( true, 0, Record.NO_NEXT_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), -1, Record.NO_NEXT_RELATIONSHIP.longValue() ); for ( Consumer<RelationshipGroupRecord> modifier : modifiers ) { modifier.accept( record ); } return record; }
private PropertyKeyTokenRecord readPropertyKeyTokenRecord( int id, ReadableChannel channel ) throws IOException { // in_use(byte)+count(int)+key_blockId(int) byte inUseFlag = channel.get(); boolean inUse = false; if ( (inUseFlag & Record.IN_USE.byteValue()) == Record.IN_USE.byteValue() ) { inUse = true; } else if ( inUseFlag != Record.NOT_IN_USE.byteValue() ) { throw new IOException( "Illegal in use flag: " + inUseFlag ); } PropertyKeyTokenRecord record = new PropertyKeyTokenRecord( id ); record.setInUse( inUse ); record.setPropertyCount( channel.getInt() ); record.setNameId( channel.getInt() ); if ( readDynamicRecords( channel, record, PROPERTY_INDEX_DYNAMIC_RECORD_ADDER ) == -1 ) { return null; } return record; }
@Override public void checkConsistency( NodeRecord node, CheckerEngine<NodeRecord, NodeConsistencyReport> engine, RecordAccess records ) { if ( !Record.NO_NEXT_RELATIONSHIP.is( node.getNextRel() ) ) { engine.comparativeCheck( records.relationshipGroup( node.getNextRel() ), this ); } }
private DynamicRecord readDynamicRecord( ReadableChannel channel ) throws IOException { // id+type+in_use(byte)+nr_of_bytes(int)+next_block(long) long id = channel.getLong(); assert id >= 0 && id <= (1L << 36) - 1 : id + " is not a valid dynamic record id"; int type = channel.getInt(); byte inUseFlag = channel.get(); boolean inUse = (inUseFlag & Record.IN_USE.byteValue()) != 0; DynamicRecord record = new DynamicRecord( id ); record.setInUse( inUse, type ); if ( inUse ) { record.setStartRecord( (inUseFlag & Record.FIRST_IN_CHAIN.byteValue()) != 0 ); int nrOfBytes = channel.getInt(); assert nrOfBytes >= 0 && nrOfBytes < ((1 << 24) - 1) : nrOfBytes + " is not valid for a number of bytes field of " + "a dynamic record"; long nextBlock = channel.getLong(); assert (nextBlock >= 0 && nextBlock <= (1L << 36 - 1)) || (nextBlock == Record.NO_NEXT_BLOCK.intValue()) : nextBlock + " is not valid for a next record field of " + "a dynamic record"; record.setNextBlock( nextBlock ); byte[] data = new byte[nrOfBytes]; channel.get( data, nrOfBytes ); record.setData( data ); } return record; }
private NodeRecord getNode( int nodeId, boolean inUse ) { NodeRecord nodeRecord = new NodeRecord( nodeId ); nodeRecord = nodeRecord.initialize( inUse, NO_NEXT_PROPERTY.longValue(), false, NO_NEXT_RELATIONSHIP.longValue(), NO_LABELS_FIELD.longValue() ); InlineNodeLabels labelFieldWriter = new InlineNodeLabels( nodeRecord ); labelFieldWriter.put( new long[]{ENTITY_TOKEN}, null, null ); return nodeRecord; }
private PropertyKeyTokenRecord readPropertyKeyTokenRecord( int id, ReadableChannel channel ) throws IOException { // in_use(byte)+count(int)+key_blockId(int) byte inUseFlag = channel.get(); boolean inUse = false; if ( (inUseFlag & Record.IN_USE.byteValue()) == Record.IN_USE.byteValue() ) { inUse = true; } else if ( inUseFlag != Record.NOT_IN_USE.byteValue() ) { throw new IOException( "Illegal in use flag: " + inUseFlag ); } PropertyKeyTokenRecord record = new PropertyKeyTokenRecord( id ); record.setInUse( inUse ); record.setPropertyCount( channel.getInt() ); record.setNameId( channel.getInt() ); if ( readDynamicRecords( channel, record, PROPERTY_INDEX_DYNAMIC_RECORD_ADDER ) == -1 ) { return null; } return record; }