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 ); } }
/** * @deprecated use {@link #initialize(boolean, boolean, long, int, int)} instead. */ @Deprecated public static DynamicRecord dynamicRecord( long id, boolean inUse, boolean isStartRecord, long nextBlock, int type, byte [] data ) { DynamicRecord record = new DynamicRecord( id ); record.setInUse( inUse ); record.setStartRecord( isStartRecord ); record.setNextBlock( nextBlock ); record.setType( type ); record.setData( data ); return record; }
@Override public SchemaRecord clone() { List<DynamicRecord> list = new ArrayList<>( records.size() ); for ( DynamicRecord record : records ) { list.add( record.clone() ); } return new SchemaRecord( list ); } }
public static DynamicRecord allocateRecord( long id ) { DynamicRecord record = new DynamicRecord( id ); record.setCreated(); record.setInUse( true ); return record; } }
@Override public DynamicRecord nextRecord() { DynamicRecord record = recordIterator.next(); if ( !record.inUse() ) { record.setCreated(); } record.setInUse( true ); return record; }
/** * @deprecated use {@link #initialize(boolean, boolean, long, int, int)} instead. */ @Deprecated public static DynamicRecord dynamicRecord( long id, boolean inUse ) { DynamicRecord record = new DynamicRecord( id ); record.setInUse( inUse ); return record; }
@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 protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { DynamicRecord string = new DynamicRecord( next.stringProperty() ); string.setInUse( true ); string.setCreated(); string.setType( PropertyType.STRING.intValue() ); string.setNextBlock( next.stringProperty() ); string.setData( UTF8.encode( "hello world" ) ); PropertyBlock block = new PropertyBlock(); block.setSingleBlock( (((long) PropertyType.STRING.intValue()) << 24) | (string.getId() << 28) ); block.addValueRecord( string ); PropertyRecord property = new PropertyRecord( next.property() ); property.addPropertyBlock( block ); tx.create( property ); } } );
@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() ); }; } }
@Override protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { DynamicRecord schema = new DynamicRecord( next.schema() ); DynamicRecord schemaBefore = schema.clone(); schema.setNextBlock( next.schema() ); // Point to a record that isn't in use. StoreIndexDescriptor rule = indexRule( schema.getId(), label1, key1, DESCRIPTOR ); schema.setData( SchemaRuleSerialization.serialize( rule ) ); tx.createSchema( asList( schemaBefore ), asList( schema ), rule ); } } );
@Override public DynamicRecord clone() { DynamicRecord clone = new DynamicRecord( getId() ).initialize( inUse(), startRecord, nextBlock, type, length ); if ( data != null ) { clone.setData( data.clone() ); } return clone; } }
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() ); } }
@Test public void shouldReportSelfReferentialNext() { // given DynamicRecord property = add( inUse( fill( record( 42 ) ) ) ); property.setNextBlock( property.getId() ); // when ConsistencyReport.DynamicConsistencyReport report = check( property ); // then verify( report ).selfReferentialNext(); verifyNoMoreInteractions( report ); }
public static SchemaRuleCommand createIndexRule( IndexProviderDescriptor provider, long id, LabelSchemaDescriptor descriptor ) { SchemaRule rule = IndexDescriptorFactory.forSchema( descriptor, provider ).withId( id ); DynamicRecord record = new DynamicRecord( id ); record.setInUse( true ); record.setCreated(); record.setData( SchemaRuleSerialization.serialize( rule ) ); return new SchemaRuleCommand( Collections.emptyList(), singletonList( record ), rule ); }
@Test public void allocatePreviouslyUsedRecord() { DynamicRecord dynamicRecord = new DynamicRecord( 1 ); dynamicRecord.setInUse( true ); ReusableRecordsAllocator recordsAllocator = new ReusableRecordsAllocator( 10, dynamicRecord ); DynamicRecord allocatedRecord = recordsAllocator.nextRecord(); assertSame( "Records should be the same.", allocatedRecord, dynamicRecord ); assertTrue( "Record should be marked as used.", allocatedRecord.inUse() ); assertFalse( "Record should be marked as created.", allocatedRecord.isCreated() ); }
RecordAccess records ) if ( !record.inUse() ) if ( record.getLength() == 0 ) else if ( record.getLength() < 0 ) if ( !Record.NO_NEXT_BLOCK.is( record.getNextBlock() ) ) if ( record.getNextBlock() == record.getId() ) engine.comparativeCheck( dereference.lookup( records, record.getNextBlock() ), this ); if ( record.getLength() < blockSize )
@Test void shouldReportDynamicRecordOwnedByTwoOtherDynamicRecords() { // given RecordAccessStub records = new RecordAccessStub(); OwnerCheck decorator = new OwnerCheck( true, DynamicStore.STRING ); RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> checker = decorator .decorateDynamicChecker( RecordType.STRING_PROPERTY, dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.STRING ) ); DynamicRecord record1 = records.add( inUse( string( new DynamicRecord( 1 ) ) ) ); DynamicRecord record2 = records.add( inUse( string( new DynamicRecord( 2 ) ) ) ); DynamicRecord record3 = records.add( inUse( string( new DynamicRecord( 3 ) ) ) ); record1.setNextBlock( record3.getId() ); record2.setNextBlock( record3.getId() ); // when ConsistencyReport.DynamicConsistencyReport report1 = check( ConsistencyReport.DynamicConsistencyReport.class, checker, record1, records ); ConsistencyReport.DynamicConsistencyReport report2 = check( ConsistencyReport.DynamicConsistencyReport.class, checker, record2, records ); // then verifyNoMoreInteractions( report1 ); verify( report2 ).nextMultipleOwners( record1 ); verifyNoMoreInteractions( report2 ); }
Dynamic( RecordType type, DynamicRecord record ) { this.type = type; this.id = record.getId(); }
@Override DynamicRecord record( long id ) { DynamicRecord result = new DynamicRecord( id ); result.setType( SCHEMA_RECORD_TYPE ); return result; }
@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; }; }