private String illegalBlockSizeMessage( DynamicRecord record, int dataSize ) { return format( "Next block set[%d] current block illegal size[%d/%d]", record.getNextBlock(), record.getLength(), dataSize ); }
/** * @return a {@link ByteBuffer#slice() sliced} {@link ByteBuffer} wrapping {@code target} or, * if necessary a new larger {@code byte[]} and containing exactly all concatenated data read from records */ public static ByteBuffer concatData( Collection<DynamicRecord> records, byte[] target ) { int totalLength = 0; for ( DynamicRecord record : records ) { totalLength += record.getLength(); } if ( target.length < totalLength ) { target = new byte[totalLength]; } ByteBuffer buffer = ByteBuffer.wrap( target, 0, totalLength ); for ( DynamicRecord record : records ) { buffer.put( record.getData() ); } buffer.position( 0 ); return buffer; }
public static void readData( DynamicRecord record, PageCursor cursor ) { int len = record.getLength(); if ( len == 0 ) // don't go though the trouble of acquiring the window if we would read nothing { record.setData( NO_DATA ); return; } byte[] data = record.getData(); if ( data == null || data.length != len ) { data = new byte[len]; } cursor.getBytes( data ); record.setData( data ); }
@Override public void checkReference( PropertyRecord record, DynamicRecord referred, CheckerEngine<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> engine, RecordAccess records ) { if ( !referred.inUse() ) { notUsed( engine.report(), referred ); } else { if ( referred.getLength() <= 0 ) { empty( engine.report(), referred ); } } }
@Override public void checkReference( RECORD record, DynamicRecord name, CheckerEngine<RECORD, REPORT> engine, RecordAccess records ) { if ( !name.inUse() ) { nameNotInUse( engine.report(), name ); } else { if ( name.getLength() <= 0 ) { emptyName( engine.report(), name ); } } }
@Override public void checkReference( DynamicRecord record, DynamicRecord next, CheckerEngine<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> engine, RecordAccess records ) { if ( !next.inUse() ) { engine.report().nextNotInUse( next ); } else { if ( next.getLength() <= 0 ) { engine.report().emptyNextBlock( next ); } } } }
@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() ) ); } }
@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 + "]getLength", actualNameRecord.getLength(), is( expectedNameRecord.getLength() ) ); assertThat( "[" + i + "]getNextBlock", actualNameRecord.getNextBlock(), is( expectedNameRecord.getNextBlock() ) ); assertThat( "[" + i + "]getType", actualNameRecord.getType(), is( expectedNameRecord.getType() ) );
@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() ); } }
@Override public Generator<DynamicRecord> dynamic() { 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( max( 1, recordId ) ).initialize( random.nextBoolean(), random.nextBoolean(), next, random.nextInt( PropertyType.values().length ), length ); byte[] bytes = random.nextByteArray( record.getLength(), record.getLength() ).asObjectCopy(); record.setData( bytes ); return record; }; }
assertThat( "[" + index + "]getValueRecords[" + i + "]getData", actualValueRecord.getData(), is( expectedValueRecord.getData() ) ); assertThat( "[" + index + "]getValueRecords[" + i + "]getLength", actualValueRecord.getLength(), is( expectedValueRecord.getLength() ) ); assertThat( "[" + index + "]getValueRecords[" + i + "]getNextBlock", actualValueRecord.getNextBlock(), is( expectedValueRecord.getNextBlock() ) );
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 ); } }
private String illegalBlockSizeMessage( DynamicRecord record, int dataSize ) { return format( "Next block set[%d] current block illegal size[%d/%d]", record.getNextBlock(), record.getLength(), dataSize ); }
/** * @return a {@link ByteBuffer#slice() sliced} {@link ByteBuffer} wrapping {@code target} or, * if necessary a new larger {@code byte[]} and containing exactly all concatenated data read from records */ public static ByteBuffer concatData( Collection<DynamicRecord> records, byte[] target ) { int totalLength = 0; for ( DynamicRecord record : records ) { totalLength += record.getLength(); } if ( target.length < totalLength ) { target = new byte[totalLength]; } ByteBuffer buffer = ByteBuffer.wrap( target, 0, totalLength ); for ( DynamicRecord record : records ) { buffer.put( record.getData() ); } buffer.position( 0 ); return buffer; }
@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 ); } }
public static void readData( DynamicRecord record, PageCursor cursor ) { int len = record.getLength(); if ( len == 0 ) // don't go though the trouble of acquiring the window if we would read nothing { record.setData( NO_DATA ); return; } byte[] data = record.getData(); if ( data == null || data.length != len ) { data = new byte[len]; } cursor.getBytes( data ); record.setData( data ); }
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 ); } }