@Override public long valueFrom( RelationshipGroupRecord record ) { return record.getType(); }
@Override public void checkConsistency( RelationshipGroupRecord record, CheckerEngine<RelationshipGroupRecord, RelationshipGroupConsistencyReport> engine, RecordAccess records ) { if ( record.getType() < 0 ) { engine.report().illegalRelationshipType(); } else { engine.comparativeCheck( records.relationshipType( record.getType() ), this ); } }
@Override public void checkReference( RelationshipGroupRecord record, RelationshipGroupRecord referred, CheckerEngine<RelationshipGroupRecord, RelationshipGroupConsistencyReport> engine, RecordAccess records ) { if ( !referred.inUse() ) { engine.report().nextGroupNotInUse(); } else { if ( record.getType() >= referred.getType() ) { engine.report().invalidTypeSortOrder(); } if ( record.getOwningNode() != referred.getOwningNode() ) { engine.report().nextHasOtherOwner( referred ); } } } }
public RelationshipGroupPosition getRelationshipGroup( NodeRecord node, int type, RecordAccess<RelationshipGroupRecord, Integer> relGroupRecords ) { long groupId = node.getNextRel(); long previousGroupId = Record.NO_NEXT_RELATIONSHIP.intValue(); RecordProxy<RelationshipGroupRecord, Integer> previous = null; RecordProxy<RelationshipGroupRecord, Integer> current; while ( groupId != Record.NO_NEXT_RELATIONSHIP.intValue() ) { current = relGroupRecords.getOrLoad( groupId, null ); RelationshipGroupRecord record = current.forReadingData(); record.setPrev( previousGroupId ); // not persistent so not a "change" if ( record.getType() == type ) { return new RelationshipGroupPosition( previous, current ); } else if ( record.getType() > type ) { // The groups are sorted in the chain, so if we come too far we can return // empty handed right away return new RelationshipGroupPosition( previous, null ); } previousGroupId = groupId; groupId = record.getNext(); previous = current; } return new RelationshipGroupPosition( previous, null ); }
public void delete( RelationshipGroupRecord group ) { group.setInUse( false ); add( group, new RelationshipGroupRecord( group.getId(), group.getType() ) ); }
public void create( RelationshipGroupRecord group ) { group.setCreated(); update( new RelationshipGroupRecord( group.getId(), group.getType() ), group ); }
/** * Caches a relationship group into this cache, it will be cached if the * {@link RelationshipGroupRecord#getOwningNode() owner} is within the {@link #prepare(long) prepared} range, * where {@code true} will be returned, otherwise {@code false}. * * @param groupRecord {@link RelationshipGroupRecord} to cache. * @return whether or not the group was cached, i.e. whether or not it was within the prepared range. */ public boolean put( RelationshipGroupRecord groupRecord ) { long nodeId = groupRecord.getOwningNode(); assert nodeId < highNodeId; if ( nodeId < fromNodeId || nodeId >= toNodeId ) { return false; } long baseIndex = offsets.get( rebase( nodeId ) ); // grouCount is extra validation, really int groupCount = groupCount( nodeId ); long index = scanForFreeFrom( baseIndex, groupCount, groupRecord.getType(), nodeId ); // Put the group at this index cache.setByte( index, 0, (byte) 1 ); cache.set3ByteInt( index, 1, groupRecord.getType() ); cache.set6ByteLong( index, 1 + 3, groupRecord.getFirstOut() ); cache.set6ByteLong( index, 1 + 3 + 6, groupRecord.getFirstIn() ); cache.set6ByteLong( index, 1 + 3 + 6 + 6, groupRecord.getFirstLoop() ); return true; }
@Override public void checkReference( RelationshipGroupRecord record, RelationshipRecord referred, CheckerEngine<RelationshipGroupRecord, RelationshipGroupConsistencyReport> engine, RecordAccess records ) { if ( !referred.inUse() ) { relationshipNotInUse( engine.report() ); } else { if ( !isFirstInChain( referred ) ) { relationshipNotFirstInChain( engine.report() ); } if ( referred.getType() != record.getType() ) { relationshipOfOtherType( engine.report() ); } } }
private String diff( RelationshipGroupRecord expected, RelationshipGroupRecord actual ) { if ( actual.getId() == expected.getId() && actual.getType() == expected.getType() && actual.getNext() == expected.getNext() && actual.getFirstOut() == expected.getFirstOut() && actual.getFirstIn() == expected.getFirstIn() && actual.getFirstLoop() == expected.getFirstLoop() && actual.getOwningNode() == expected.getOwningNode() ) { return null; } return describeDiff( expected.toString(), actual.toString() ); }
@Override public RecordKey<RelationshipGroupRecord> relationshipGroup() { return ( written, read ) -> { assertEquals( written.getType(), read.getType() ); assertEquals( written.getFirstOut(), read.getFirstOut() ); assertEquals( written.getFirstIn(), read.getFirstIn() ); assertEquals( written.getFirstLoop(), read.getFirstLoop() ); assertEquals( written.getNext(), read.getNext() ); assertEquals( written.getOwningNode(), read.getOwningNode() ); }; }
private void assertRelationshipGroupsInOrder( NeoStores neoStores, long nodeId, int... types ) { NodeStore nodeStore = neoStores.getNodeStore(); NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), NORMAL ); assertTrue( "Node should be dense, is " + node, node.isDense() ); long groupId = node.getNextRel(); int cursor = 0; List<RelationshipGroupRecord> seen = new ArrayList<>(); while ( groupId != Record.NO_NEXT_RELATIONSHIP.intValue() ) { RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore(); RelationshipGroupRecord group = relationshipGroupStore.getRecord( groupId, relationshipGroupStore.newRecord(), NORMAL ); seen.add( group ); assertEquals( "Invalid type, seen groups so far " + seen, types[cursor++], group.getType() ); groupId = group.getNext(); } assertEquals( "Not enough relationship group records found in chain for " + node, types.length, cursor ); }
private void markRelGroupNotInUse( long nodeId, TestRelType... types ) { NodeRecord node = getNodeRecord( nodeId ); assertTrue( node.isDense() ); Set<TestRelType> typesToRemove = asSet( types ); long relGroupId = node.getNextRel(); while ( relGroupId != NO_NEXT_RELATIONSHIP.intValue() ) { RelationshipGroupRecord relGroup = getRelGroupRecord( relGroupId ); TestRelType type = relTypeForId( relGroup.getType() ); if ( typesToRemove.contains( type ) ) { relGroup.setInUse( false ); update( relGroup ); } relGroupId = relGroup.getNext(); } }
private static RecordProxy<RelationshipGroupRecord, Integer> getRelationshipGroup( RecordChangeSet recordChangeSet, NodeRecord node, int type ) { long groupId = node.getNextRel(); long previousGroupId = Record.NO_NEXT_RELATIONSHIP.intValue(); while ( groupId != Record.NO_NEXT_RELATIONSHIP.intValue() ) { RecordProxy<RelationshipGroupRecord, Integer> change = recordChangeSet.getRelGroupRecords().getOrLoad( groupId, type ); RelationshipGroupRecord record = change.forReadingData(); record.setPrev( previousGroupId ); // not persistent so not a "change" if ( record.getType() == type ) { return change; } previousGroupId = groupId; groupId = record.getNext(); } return null; }
private void markRandomRelsInGroupNotInUse( long nodeId, TestRelType type ) { NodeRecord node = getNodeRecord( nodeId ); assertTrue( node.isDense() ); long relGroupId = node.getNextRel(); while ( relGroupId != NO_NEXT_RELATIONSHIP.intValue() ) { RelationshipGroupRecord relGroup = getRelGroupRecord( relGroupId ); if ( type == relTypeForId( relGroup.getType() ) ) { markRandomRelsInChainNotInUse( relGroup.getFirstOut() ); markRandomRelsInChainNotInUse( relGroup.getFirstIn() ); markRandomRelsInChainNotInUse( relGroup.getFirstLoop() ); return; } relGroupId = relGroup.getNext(); } throw new IllegalStateException( "No relationship group with type: " + type + " found" ); }
private void writeRelationshipGroupRecord( WritableChannel channel, RelationshipGroupRecord record ) throws IOException { byte flags = bitFlags( bitFlag( record.inUse(), Record.IN_USE.byteValue() ), bitFlag( record.requiresSecondaryUnit(), Record.REQUIRE_SECONDARY_UNIT ), bitFlag( record.hasSecondaryUnitId(), Record.HAS_SECONDARY_UNIT ), bitFlag( record.isUseFixedReferences(), Record.USES_FIXED_REFERENCE_FORMAT ) ); channel.put( flags ); channel.putShort( (short) record.getType() ); channel.putLong( record.getNext() ); channel.putLong( record.getFirstOut() ); channel.putLong( record.getFirstIn() ); channel.putLong( record.getFirstLoop() ); channel.putLong( record.getOwningNode() ); if ( record.hasSecondaryUnitId() ) { channel.putLong( record.getSecondaryUnitId() ); } } }
private static void assertValidRelGroupCommand( StorageCommand command ) { assertThat( command, instanceOf( RelationshipGroupCommand.class ) ); RelationshipGroupCommand relGroupCommand = (RelationshipGroupCommand) command; RelationshipGroupRecord record = relGroupCommand.getAfter(); assertEquals( ID, record.getId() ); if ( IN_USE_FLAG == Record.IN_USE.byteValue() ) { assertTrue( record.inUse() ); } else if ( IN_USE_FLAG == Record.NOT_IN_USE.byteValue() ) { assertFalse( record.inUse() ); } else { throw new IllegalStateException( "Illegal inUse flag: " + IN_USE_FLAG ); } assertEquals( TYPE_AS_INT, record.getType() ); assertEquals( NEXT, record.getNext() ); assertEquals( FIRST_OUT, record.getFirstOut() ); assertEquals( FIRST_IN, record.getFirstIn() ); assertEquals( FIRST_LOOP, record.getNext() ); assertEquals( OWNING_NODE, record.getOwningNode() ); }
cursor.putShort( (short) record.getType() ); cursor.putInt( (int) record.getNext() ); cursor.putInt( (int) record.getFirstOut() );
state.extractCommands( commands ); RelationshipGroupCommand group = singleRelationshipGroupCommand( commands ); assertEquals( relationshipA, group.getAfter().getType() );
currentTypeId = -1; assertTrue( group.getType() > currentTypeId ); readCount++;