@Override protected RelationshipRecord createNullRecord( long id ) { RelationshipRecord record = new RelationshipRecord( id, false, 0, 0, 0, 0, 0, 0, 0, false, false ); record.setNextProp( 0 ); return record; }
@Override public long createRelationship( long node1, long node2, RelationshipType type, Map<String, Object> properties ) { long id = relationshipStore.nextId(); int typeId = getOrCreateRelationshipTypeId( type.name() ); relationshipCreator.relationshipCreate( id, typeId, node1, node2, recordAccess, noopLockClient ); if ( properties != null && !properties.isEmpty() ) { RelationshipRecord record = recordAccess.getRelRecords().getOrLoad( id, null ).forChangingData(); record.setNextProp( propertyCreator.createPropertyChain( record, propertiesIterator( properties ), recordAccess.getPropertyRecords() ) ); } flushStrategy.flush(); return id; }
@Override public void setRelationshipProperties( long rel, Map<String, Object> properties ) { RelationshipRecord record = recordAccess.getRelRecords().getOrLoad( rel, null ).forChangingData(); if ( record.getNextProp() != Record.NO_NEXT_PROPERTY.intValue() ) { propertyDeletor.deletePropertyChain( record, recordAccess.getPropertyRecords() ); } record.setNextProp( propertyCreator.createPropertyChain( record, propertiesIterator( properties ), recordAccess.getPropertyRecords() ) ); flushStrategy.flush(); }
@Test void shouldNotReportAnythingForRelationshipsWithDifferentPropertyChains() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordAccessStub records = new RecordAccessStub(); RelationshipRecord relationship1 = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship1.setNextProp( 7 ); RelationshipRecord relationship2 = records.add( inUse( new RelationshipRecord( 2, 0, 1, 0 ) ) ); relationship2.setNextProp( 8 ); // when ConsistencyReport.RelationshipConsistencyReport report1 = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship1, records ); ConsistencyReport.RelationshipConsistencyReport report2 = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship2, records ); // then verifyZeroInteractions( report1 ); verifyZeroInteractions( report2 ); }
@Test void shouldReportTwoRelationshipsWithSamePropertyChain() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordAccessStub records = new RecordAccessStub(); RelationshipRecord relationship1 = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship1.setNextProp( 7 ); RelationshipRecord relationship2 = records.add( inUse( new RelationshipRecord( 2, 0, 1, 0 ) ) ); relationship2.setNextProp( relationship1.getNextProp() ); // when ConsistencyReport.RelationshipConsistencyReport report1 = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship1, records ); ConsistencyReport.RelationshipConsistencyReport report2 = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship2, records ); // then verifyZeroInteractions( report1 ); verify( report2 ).multipleOwners( relationship1 ); }
@Test void shouldReportNodeStoreReferencingSameChainAsRelationship() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck = decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() ); RecordAccessStub records = new RecordAccessStub(); NeoStoreRecord master = records.add( new NeoStoreRecord() ); master.setNextProp( 7 ); RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship.setNextProp( 7 ); // when ConsistencyReport.RelationshipConsistencyReport relationshipReport = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship, records ); ConsistencyReport.NeoStoreConsistencyReport masterReport = check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records ); // then verifyZeroInteractions( relationshipReport ); verify( masterReport ).multipleOwners( relationship ); }
@Test void shouldReportPropertyNotInUse() { // given checkSingleDirection(); RelationshipRecord relationship = inUse( new RelationshipRecord( 42, 1, 2, 4 ) ); add( inUse( new RelationshipTypeTokenRecord( 4 ) ) ); relationship.setNextProp( 11 ); add( inUse( new NodeRecord( 1, false, 42, NONE ) ) ); add( inUse( new NodeRecord( 2, false, 42, NONE ) ) ); PropertyRecord property = add( notInUse( new PropertyRecord( 11 ) ) ); // when RelationshipConsistencyReport report = check( relationship ); // then verify( report ).propertyNotInUse( property ); verifyNoMoreInteractions( report ); }
@Test void shouldNotReportOrphanIfOwnedByRelationship() { // given RecordAccessStub records = new RecordAccessStub(); OwnerCheck decorator = new OwnerCheck( true ); PropertyRecord record = inUse( new PropertyRecord( 42 ) ); ConsistencyReport.PropertyConsistencyReport report = check( ConsistencyReport.PropertyConsistencyReport.class, decorator.decoratePropertyChecker( dummyPropertyChecker() ), record, records ); RelationshipRecord relationship = inUse( new RelationshipRecord( 10, 1, 1, 0 ) ); relationship.setNextProp( 42 ); ConsistencyReport.RelationshipConsistencyReport relationshipReport = check( ConsistencyReport.RelationshipConsistencyReport.class, decorator.decorateRelationshipChecker( dummyRelationshipChecker() ), relationship, records ); // when decorator.scanForOrphanChains( ProgressMonitorFactory.NONE ); records.checkDeferred(); // then verifyNoMoreInteractions( report ); verifyNoMoreInteractions( relationshipReport ); }
@Test void shouldReportRelationshipWithSamePropertyChainAsNode() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker = decorator.decorateNodeChecker( dummyNodeCheck() ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordAccessStub records = new RecordAccessStub(); NodeRecord node = records.add( inUse( new NodeRecord( 1, false, NONE, 7 ) ) ); RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship.setNextProp( node.getNextProp() ); // when ConsistencyReport.NodeConsistencyReport nodeReport = check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records ); ConsistencyReport.RelationshipConsistencyReport relationshipReport = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship, records ); // then verifyZeroInteractions( nodeReport ); verify( relationshipReport ).multipleOwners( node ); }
@Test void shouldReportRelationshipWithReferenceToTheGraphGlobalChain() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck = decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() ); RecordAccessStub records = new RecordAccessStub(); NeoStoreRecord master = records.add( new NeoStoreRecord() ); master.setNextProp( 7 ); RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship.setNextProp( 7 ); // when ConsistencyReport.NeoStoreConsistencyReport masterReport = check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records ); ConsistencyReport.RelationshipConsistencyReport relationshipReport = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship, records ); // then verifyZeroInteractions( masterReport ); verify( relationshipReport ).multipleOwners( master ); }
@Test void shouldReportNodeWithSamePropertyChainAsRelationship() { // given OwnerCheck decorator = new OwnerCheck( true ); RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker = decorator.decorateNodeChecker( dummyNodeCheck() ); RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker = decorator.decorateRelationshipChecker( dummyRelationshipChecker() ); RecordAccessStub records = new RecordAccessStub(); NodeRecord node = records.add( inUse( new NodeRecord( 1, false, NONE, 7 ) ) ); RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) ); relationship.setNextProp( node.getNextProp() ); // when ConsistencyReport.RelationshipConsistencyReport relationshipReport = check( ConsistencyReport.RelationshipConsistencyReport.class, relationshipChecker, relationship, records ); ConsistencyReport.NodeConsistencyReport nodeReport = check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records ); // then verifyZeroInteractions( relationshipReport ); verify( nodeReport ).multipleOwners( relationship ); }
@Test void shouldReportPropertyNotFirstInChain() { // given checkSingleDirection(); RelationshipRecord relationship = inUse( new RelationshipRecord( 42, 1, 2, 4 ) ); add( inUse( new RelationshipTypeTokenRecord( 4 ) ) ); relationship.setNextProp( 11 ); add( inUse( new NodeRecord( 1, false, 42, NONE ) ) ); add( inUse( new NodeRecord( 2, false, 42, NONE ) ) ); PropertyRecord property = add( inUse( new PropertyRecord( 11 ) ) ); property.setPrevProp( 6 ); // when RelationshipConsistencyReport report = check( relationship ); // then verify( report ).propertyNotFirstInChain( property ); verifyNoMoreInteractions( report ); }
record.setSecondPrevRel( channel.getLong() ); record.setSecondNextRel( channel.getLong() ); record.setNextProp( channel.getLong() ); byte extraByte = channel.get(); record.setFirstInFirstChain( (extraByte & 0x1) > 0 );
record.setSecondPrevRel( channel.getLong() ); record.setSecondNextRel( channel.getLong() ); record.setNextProp( channel.getLong() ); byte extraByte = channel.get(); record.setFirstInFirstChain( (extraByte & 0x1) > 0 );
@Test public void shouldReportCircularRelationshipPropertyRecordChain() throws Exception { int relType = createRelType(); shouldReportCircularPropertyRecordChain( RecordType.RELATIONSHIP, ( tx, next, propertyRecordId ) -> { long node = next.node(); long relationship = next.relationship(); tx.create( new NodeRecord( node ).initialize( true, -1, false, relationship, Record.NO_LABELS_FIELD.longValue() ) ); RelationshipRecord relationshipRecord = new RelationshipRecord( relationship ); relationshipRecord.setFirstNode( node ); relationshipRecord.setSecondNode( node ); relationshipRecord.setType( relType ); relationshipRecord.setNextProp( propertyRecordId ); tx.create( relationshipRecord ); } ); }
record.setSecondPrevRel( channel.getLong() ); record.setSecondNextRel( channel.getLong() ); record.setNextProp( channel.getLong() ); byte extraByte = channel.get(); record.setFirstInFirstChain( (extraByte & 0x1) > 0 );
record.setSecondPrevRel( channel.getLong() ); record.setSecondNextRel( channel.getLong() ); record.setNextProp( channel.getLong() ); byte extraByte = channel.get(); record.setFirstInFirstChain( (extraByte & 0x1) > 0 );
master.setNextProp( 1 );
@Override protected void transactionData( GraphStoreFixture.TransactionDataBuilder tx, GraphStoreFixture.IdGenerator next ) { long nodeId1 = next.node(); long nodeId2 = next.node(); long relId = next.relationship(); long propId = next.property(); NodeRecord node1 = new NodeRecord( nodeId1, true, false, relId, NO_NEXT_PROPERTY.intValue(), NO_LABELS_FIELD.intValue() ); NodeRecord node2 = new NodeRecord( nodeId2, true, false, relId, NO_NEXT_PROPERTY.intValue(), NO_LABELS_FIELD.intValue() ); // structurally correct, but does not have the 'mandatory' property with the 'M' rel type RelationshipRecord relationship = new RelationshipRecord( relId, true, nodeId1, nodeId2, M, NO_PREV_RELATIONSHIP.intValue(), NO_NEXT_RELATIONSHIP.intValue(), NO_PREV_RELATIONSHIP.intValue(), NO_NEXT_RELATIONSHIP.intValue(), true, true ); relationship.setNextProp( propId ); PropertyRecord property = new PropertyRecord( propId, relationship ); property.setInUse( true ); PropertyBlock block = new PropertyBlock(); block.setSingleBlock( key1 | (((long) PropertyType.INT.intValue()) << 24) | (1337L << 28) ); property.addPropertyBlock( block ); tx.create( node1 ); tx.create( node2 ); tx.create( relationship ); tx.create( property ); tx.incrementRelationshipCount( ANY_LABEL, ANY_RELATIONSHIP_TYPE, ANY_LABEL, 1 ); tx.incrementRelationshipCount( ANY_LABEL, M, ANY_LABEL, 1 ); } } );
add( inUse( new NodeRecord( 3, false, NONE, NONE ) ) ); add( inUse( new PropertyRecord( 101 ) ) ); relationship.setNextProp( 101 ); RelationshipRecord sNext = add( inUse( new RelationshipRecord( 51, 1, 3, 4 ) ) ); RelationshipRecord tNext = add( inUse( new RelationshipRecord( 52, 2, 3, 4 ) ) );