@Override public void updateRecord( R record ) { actual.updateRecord( record ); }
private <RECORD extends AbstractBaseRecord> void updateStore( RecordStore<RECORD> store, BaseCommand<RECORD> command ) { store.updateRecord( selectRecordByCommandVersion( command ) ); }
private static <RECORD extends AbstractBaseRecord> void migrate( RecordStore<RECORD> from, RecordStore<RECORD> to ) { to.setHighestPossibleIdInUse( from.getHighestPossibleIdInUse() ); from.scanAllRecords( record -> { to.prepareForCommit( record ); to.updateRecord( record ); return false; } ); }
protected S initialiseStore( NeoStores neoStores ) { S store = getStore( neoStores ); store.updateRecord( createExistingRecord( false ) ); return store; }
@Test public void recordWithReservedIdIsSkipped() { RecordStore<NodeRecord> store = mock( NodeStore.class ); StageControl stageControl = mock( StageControl.class ); UpdateRecordsStep<NodeRecord> step = new UpdateRecordsStep<>( stageControl, Configuration.DEFAULT, store, new StorePrepareIdSequence() ); NodeRecord node1 = new NodeRecord( 1 ); node1.setInUse( true ); NodeRecord node2 = new NodeRecord( 2 ); node2.setInUse( true ); NodeRecord nodeWithReservedId = new NodeRecord( IdGeneratorImpl.INTEGER_MINUS_ONE ); NodeRecord[] batch = {node1, node2, nodeWithReservedId}; step.process( batch, mock( BatchSender.class ) ); verify( store ).prepareForCommit( eq( node1 ), any( IdSequence.class ) ); verify( store ).updateRecord( node1 ); verify( store ).prepareForCommit( eq( node2 ), any( IdSequence.class ) ); verify( store ).updateRecord( node2 ); verify( store, never() ).prepareForCommit( eq( nodeWithReservedId ), any( IdSequence.class ) ); verify( store, never() ).updateRecord( nodeWithReservedId ); } }
@SuppressWarnings( "unchecked" ) @Test public void shouldProcessAllTheRecordsInAStore() throws Exception { // given RecordStore<NodeRecord> nodeStore = stores.builder().build().getNodeStore(); ConsistencyReport.Reporter reporter = mock( ConsistencyReport.Reporter.class ); StoreProcessor processor = new StoreProcessor( CheckDecorator.NONE, reporter, Stage.SEQUENTIAL_FORWARD, CacheAccess.EMPTY ); nodeStore.updateRecord( node( 0, false, 0, 0 ) ); nodeStore.updateRecord( node( 1, false, 0, 0 ) ); nodeStore.updateRecord( node( 2, false, 0, 0 ) ); nodeStore.setHighestPossibleIdInUse( 2 ); // when processor.applyFiltered( nodeStore ); // then verify( reporter, times( 3 ) ).forNode( any( NodeRecord.class ), any( RecordCheck.class ) ); }
nodeStore.updateRecord( node( 0, false, 0, 0 ) ); nodeStore.updateRecord( node( 1, false, 0, 0 ) ); nodeStore.updateRecord( node( 2, false, 0, 0 ) ); nodeStore.updateRecord( node( 3, false, 0, 0 ) ); nodeStore.updateRecord( node( 4, false, 0, 0 ) ); nodeStore.setHighestPossibleIdInUse( 4 );
@Override protected void process( RECORD[] batch, BatchSender sender ) { LongFunction<IdSequence> idSequence = prepareIdSequence.apply( store ); int recordsUpdatedInThisBatch = 0; for ( RECORD record : batch ) { if ( record != null && record.inUse() && !IdValidator.isReservedId( record.getId() ) ) { store.prepareForCommit( record, idSequence.apply( record.getId() ) ); store.updateRecord( record ); recordsUpdatedInThisBatch++; } } recordsUpdated.add( recordsUpdatedInThisBatch ); }
private void createNodeRelationships() { RelationshipStore relationshipStore = neoStores.getRelationshipStore(); if ( dense ) { RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore(); relationshipGroupStore.updateRecord( createRelationshipGroup( 1, 1 ) ); relationshipGroupStore.updateRecord( createRelationshipGroup( 2, 2 ) ); relationshipGroupStore.updateRecord( createRelationshipGroup( 3, 3 ) ); } relationshipStore.updateRecord( createRelationship( 1, NO_NEXT_RELATIONSHIP.intValue() ) ); relationshipStore.updateRecord( createRelationship( 2, NO_NEXT_RELATIONSHIP.intValue() ) ); relationshipStore.updateRecord( createRelationship( 3, NO_NEXT_RELATIONSHIP.intValue() ) ); }
private void createRelationshipChain( int recordsInChain ) { RelationshipStore relationshipStore = neoStores.getRelationshipStore(); for ( int i = 1; i < recordsInChain; i++ ) { relationshipStore.updateRecord( createRelationship( i, i + 1 ) ); } relationshipStore.updateRecord( createRelationship( recordsInChain, NO_NEXT_RELATIONSHIP.intValue() ) ); if ( dense ) { RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore(); for ( int i = 1; i < recordsInChain; i++ ) { relationshipGroupStore.updateRecord( createRelationshipGroup( i, i ) ); } relationshipGroupStore .updateRecord( createRelationshipGroup( recordsInChain, NO_NEXT_RELATIONSHIP.intValue() ) ); } }
@Test public void checkingIfRecordIsInUseMustHappenAfterConsistentRead() { AtomicBoolean nextReadIsInconsistent = new AtomicBoolean( false ); PageCache pageCache = pageCacheRule.getPageCache( fs, config().withInconsistentReads( nextReadIsInconsistent ) ); StoreFactory factory = factory( null, pageCache ); try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore(); RelationshipGroupRecord record = new RelationshipGroupRecord( 1 ).initialize( true, 2, 3, 4, 5, 6, Record.NO_NEXT_RELATIONSHIP.intValue() ); relationshipGroupStore.updateRecord( record ); nextReadIsInconsistent.set( true ); // Now the following should not throw any RecordNotInUse exceptions RelationshipGroupRecord readBack = relationshipGroupStore.getRecord( 1, relationshipGroupStore.newRecord(), NORMAL ); assertThat( readBack.toString(), equalTo( record.toString() ) ); } }
private <RECORD extends AbstractBaseRecord> void createRecordIn( RecordStore<RECORD> store ) { RECORD record = store.newRecord(); record.setId( store.nextId() ); record.setInUse( true ); if ( record instanceof PropertyRecord ) { // Special hack for property store, since it's not enough to simply set a record as in use there PropertyBlock block = new PropertyBlock(); ((PropertyStore)store).encodeValue( block, 0, Values.of( 10 ) ); ((PropertyRecord) record).addPropertyBlock( block ); } store.updateRecord( record ); }
private static void breakTheChain( RecordStore<RelationshipRecord> relationshipStore ) { RelationshipRecord record = relationshipStore.getRecord( 10, relationshipStore.newRecord(), NORMAL ); long relationshipTowardsEndOfChain = record.getFirstNode(); while ( record.inUse() && !record.isFirstInFirstChain() ) { record = relationshipStore.getRecord( relationshipTowardsEndOfChain, relationshipStore.newRecord(), FORCE ); relationshipTowardsEndOfChain = record.getFirstPrevRel(); } relationshipStore.updateRecord( new RelationshipRecord( relationshipTowardsEndOfChain, 0, 0, 0 ) ); }
@Test public void shouldReportIndexInconsistencies() throws Exception { // given for ( Long indexedNodeId : indexedNodes ) { fixture.directStoreAccess().nativeStores().getNodeStore().updateRecord( notInUse( new NodeRecord( indexedNodeId, false, -1, -1 ) ) ); } // when ConsistencySummaryStatistics stats = check(); // then on( stats ).verify( RecordType.INDEX, 3 ) // 3 index entries are pointing to nodes not in use .verify( RecordType.LABEL_SCAN_DOCUMENT, 2 ) // the label scan is pointing to 2 nodes not in use .verify( RecordType.COUNTS, 3 ) .andThatsAllFolks(); }
@Test public void shouldReportRelationshipTypeInconsistencies() throws Exception { // given StoreAccess access = fixture.directStoreAccess().nativeStores(); RecordStore<RelationshipTypeTokenRecord> relTypeStore = access.getRelationshipTypeTokenStore(); RelationshipTypeTokenRecord record = relTypeStore.getRecord( (int) relTypeStore.nextId(), relTypeStore.newRecord(), FORCE ); record.setNameId( 20 ); record.setInUse( true ); relTypeStore.updateRecord( record ); // when ConsistencySummaryStatistics stats = check(); // then access.close(); on( stats ).verify( RecordType.RELATIONSHIP_TYPE, 1 ) .andThatsAllFolks(); }
@Test public void shouldReportLabelInconsistencies() throws Exception { // given StoreAccess access = fixture.directStoreAccess().nativeStores(); LabelTokenRecord record = access.getLabelTokenStore().getRecord( 1, access.getLabelTokenStore().newRecord(), FORCE ); record.setNameId( 20 ); record.setInUse( true ); access.getLabelTokenStore().updateRecord( record ); // when ConsistencySummaryStatistics stats = check(); // then on( stats ).verify( RecordType.LABEL, 1 ) .andThatsAllFolks(); }
nodeRecord.setLabelField( dynamicPointer( duplicatedLabel ), duplicatedLabel ); nodeRecord.setInUse( true ); storeAccess.getNodeStore().updateRecord( nodeRecord );
@Test public void shouldReportPropertyKeyInconsistencies() throws Exception { // given final Reference<Integer> inconsistentKey = new Reference<>(); fixture.apply( new GraphStoreFixture.Transaction() { @Override protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { inconsistentKey.set( next.propertyKey() ); tx.propertyKey( inconsistentKey.get(), "FOO" ); } } ); StoreAccess access = fixture.directStoreAccess().nativeStores(); DynamicRecord record = access.getPropertyKeyNameStore().getRecord( inconsistentKey.get() + 1, access.getPropertyKeyNameStore().newRecord(), FORCE ); record.setInUse( false ); access.getPropertyKeyNameStore().updateRecord( record ); // when ConsistencySummaryStatistics stats = check(); // then on( stats ).verify( RecordType.PROPERTY_KEY, 1 ) .andThatsAllFolks(); }
@Test public void shouldReportRelationshipLabelNameInconsistencies() throws Exception { // given final Reference<Integer> inconsistentName = new Reference<>(); fixture.apply( new GraphStoreFixture.Transaction() { @Override protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { inconsistentName.set( next.relationshipType() ); tx.relationshipType( inconsistentName.get(), "FOO" ); } } ); StoreAccess access = fixture.directStoreAccess().nativeStores(); DynamicRecord record = access.getRelationshipTypeNameStore().getRecord( inconsistentName.get(), access.getRelationshipTypeNameStore().newRecord(), FORCE ); record.setNextBlock( record.getId() ); access.getRelationshipTypeNameStore().updateRecord( record ); // when ConsistencySummaryStatistics stats = check(); // then on( stats ).verify( RecordType.RELATIONSHIP_TYPE_NAME, 1 ) .andThatsAllFolks(); }
@Test public void shouldReportPropertyKeyNameInconsistencies() throws Exception { // given final Reference<Integer> inconsistentName = new Reference<>(); fixture.apply( new GraphStoreFixture.Transaction() { @Override protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { inconsistentName.set( next.propertyKey() ); tx.propertyKey( inconsistentName.get(), "FOO" ); } } ); StoreAccess access = fixture.directStoreAccess().nativeStores(); DynamicRecord record = access.getPropertyKeyNameStore().getRecord( inconsistentName.get() + 1, access.getPropertyKeyNameStore().newRecord(), FORCE ); record.setNextBlock( record.getId() ); access.getPropertyKeyNameStore().updateRecord( record ); // when ConsistencySummaryStatistics stats = check(); // then on( stats ).verify( RecordType.PROPERTY_KEY_NAME, 1 ) .andThatsAllFolks(); }