@Override public long getNextRecordReference( DynamicRecord record ) { return record.getNextBlock(); } }
private String illegalBlockSizeMessage( DynamicRecord record, int dataSize ) { return format( "Next block set[%d] current block illegal size[%d/%d]", record.getNextBlock(), record.getLength(), dataSize ); }
private static ByteBuffer readDynamic( AbstractDynamicStore store, long reference, ByteBuffer buffer, PageCursor page ) { if ( buffer == null ) { buffer = ByteBuffer.allocate( 512 ); } else { buffer.clear(); } DynamicRecord record = store.newRecord(); do { //We need to load forcefully here since otherwise we can have inconsistent reads //for properties across blocks, see org.neo4j.graphdb.ConsistentPropertyReadsIT store.getRecordByCursor( reference, record, RecordLoad.FORCE, page ); reference = record.getNextBlock(); byte[] data = record.getData(); if ( buffer.remaining() < data.length ) { buffer = grow( buffer, data.length ); } buffer.put( data, 0, data.length ); } while ( reference != NO_ID ); return buffer; }
public String getStringFor( RECORD nameRecord ) { ensureHeavy( nameRecord ); int recordToFind = nameRecord.getNameId(); Iterator<DynamicRecord> records = nameRecord.getNameRecords().iterator(); Collection<DynamicRecord> relevantRecords = new ArrayList<>(); while ( recordToFind != Record.NO_NEXT_BLOCK.intValue() && records.hasNext() ) { DynamicRecord record = records.next(); if ( record.inUse() && record.getId() == recordToFind ) { recordToFind = (int) record.getNextBlock(); // TODO: optimize here, high chance next is right one relevantRecords.add( record ); records = nameRecord.getNameRecords().iterator(); } } return decodeString( nameStore.readFullByteArray( relevantRecords, PropertyType.STRING ).other() ); } }
private static void assertDynamicRecordChain( DynamicRecord... records ) { if ( records.length > 0 ) { for ( int i = 1; i < records.length; i++ ) { assertEquals( records[i].getId(), records[i - 1].getNextBlock() ); } assertTrue( Record.NO_NEXT_BLOCK.is( records[records.length - 1].getNextBlock() ) ); } }
if ( !Record.NO_NEXT_BLOCK.is( record.getNextBlock() ) ) DynamicOwner prevOwner = dynamicOwners.put( record.getNextBlock(), nextOwner ); if ( prevOwner != null )
if ( !Record.NO_NEXT_BLOCK.is( record.getNextBlock() ) ) if ( record.getNextBlock() == record.getId() ) engine.comparativeCheck( dereference.lookup( records, record.getNextBlock() ), this );
@Override protected void assertRecordsEqual( DynamicRecord actualRecord, DynamicRecord expectedRecord ) { assertNotNull( "actualRecord", actualRecord ); assertNotNull( "expectedRecord", expectedRecord ); assertThat( "getData", actualRecord.getData(), is( expectedRecord.getData() ) ); assertThat( "getLength", actualRecord.getLength(), is( expectedRecord.getLength() ) ); assertThat( "getNextBlock", actualRecord.getNextBlock(), is( expectedRecord.getNextBlock() ) ); assertThat( "getType", actualRecord.getType(), is( expectedRecord.getType() ) ); assertThat( "getId", actualRecord.getId(), is( expectedRecord.getId() ) ); assertThat( "getLongId", actualRecord.getId(), is( expectedRecord.getId() ) ); assertThat( "isStartRecord", actualRecord.isStartRecord(), is( expectedRecord.isStartRecord() ) ); } }
long nextBlock = dynamicRecord.getNextBlock(); if ( Record.NO_NEXT_BLOCK.is( nextBlock ) )
@Override public RecordKey<DynamicRecord> dynamic() { return ( written, read ) -> { // Don't assert type, since that's read from the data, and the data in this test // is randomly generated. Since we assert that the data is the same then the type // is also correct. assertEquals( written.getLength(), read.getLength() ); assertEquals( written.getNextBlock(), read.getNextBlock() ); assertArrayEquals( written.getData(), read.getData() ); assertEquals( written.isStartRecord(), read.isStartRecord() ); }; } }
assertThat( "[" + i + "]getNextBlock", actualNameRecord.getNextBlock(), is( expectedNameRecord.getNextBlock() ) ); assertThat( "[" + i + "]getType", actualNameRecord.getType(), is( expectedNameRecord.getType() ) ); assertThat( "[" + i + "]getId", actualNameRecord.getId(), is( expectedNameRecord.getId() ) );
@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() ); } }
assertThat( "[" + index + "]getValueRecords[" + i + "]getLength", actualValueRecord.getLength(), is( expectedValueRecord.getLength() ) ); assertThat( "[" + index + "]getValueRecords[" + i + "]getNextBlock", actualValueRecord.getNextBlock(), is( expectedValueRecord.getNextBlock() ) ); assertThat( "[" + index + "]getValueRecords[" + i + "]getType", actualValueRecord.getType(), is( expectedValueRecord.getType() ) );
void writeDynamicRecord( WritableChannel channel, DynamicRecord record ) throws IOException { // id+type+in_use(byte)+nr_of_bytes(int)+next_block(long) if ( record.inUse() ) { byte inUse = Record.IN_USE.byteValue(); if ( record.isStartRecord() ) { inUse |= Record.FIRST_IN_CHAIN.byteValue(); } channel.putLong( record.getId() ) .putInt( record.getTypeAsInt() ) .put( inUse ) .putInt( record.getLength() ) .putLong( record.getNextBlock() ); byte[] data = record.getData(); assert data != null; channel.put( data, data.length ); } else { byte inUse = Record.NOT_IN_USE.byteValue(); channel.putLong( record.getId() ) .putInt( record.getTypeAsInt() ) .put( inUse ); } }
@Override public long getNextRecordReference( DynamicRecord record ) { return record.getNextBlock(); } }
@Override public long getNextRecordReference( DynamicRecord record ) { return record.getNextBlock(); } }
private String illegalBlockSizeMessage( DynamicRecord record, int dataSize ) { return format( "Next block set[%d] current block illegal size[%d/%d]", record.getNextBlock(), record.getLength(), dataSize ); }
public String getStringFor( RECORD nameRecord ) { ensureHeavy( nameRecord ); int recordToFind = nameRecord.getNameId(); Iterator<DynamicRecord> records = nameRecord.getNameRecords().iterator(); Collection<DynamicRecord> relevantRecords = new ArrayList<>(); while ( recordToFind != Record.NO_NEXT_BLOCK.intValue() && records.hasNext() ) { DynamicRecord record = records.next(); if ( record.inUse() && record.getId() == recordToFind ) { recordToFind = (int) record.getNextBlock(); // TODO: optimize here, high chance next is right one relevantRecords.add( record ); records = nameRecord.getNameRecords().iterator(); } } return decodeString( nameStore.readFullByteArray( relevantRecords, PropertyType.STRING ).other() ); } }
private void assertDynamicRecordChain( DynamicRecord... records ) { if ( records.length > 0) { for ( int i = 1; i < records.length; i++ ) { assertEquals( records[i].getId(), records[i - 1].getNextBlock() ); } assertTrue( Record.NO_NEXT_BLOCK.is( records[records.length - 1].getNextBlock() ) ); } }
@Override public void write( DynamicRecord record, PageCursor cursor, int recordSize ) { if ( record.inUse() ) { assert record.getLength() < (1 << 24) - 1; byte headerByte = (byte) ((record.inUse() ? IN_USE_BIT : 0) | (record.isStartRecord() ? START_RECORD_BIT : 0)); cursor.putByte( headerByte ); cursor.putShort( (short) record.getLength() ); cursor.putByte( (byte) (record.getLength() >>> 16 ) ); cursor.putLong( record.getNextBlock() ); cursor.putBytes( record.getData() ); } else { markAsUnused( cursor ); } }