@Override public long valueFrom( RelationshipGroupRecord record ) { return record.getFirstOut(); }
@Override public long getNextRel( RelationshipGroupRecord group ) { return group.getFirstOut(); }
private boolean groupIsEmpty( RelationshipGroupRecord group ) { return group.getFirstOut() == Record.NO_NEXT_RELATIONSHIP.intValue() && group.getFirstIn() == Record.NO_NEXT_RELATIONSHIP.intValue() && group.getFirstLoop() == Record.NO_NEXT_RELATIONSHIP.intValue(); }
long nextOutMod = record.getFirstOut() == Record.NO_NEXT_RELATIONSHIP.intValue() ? 0 : (record.getFirstOut() & 0x700000000L) >> 28; long nextInMod = record.getFirstIn() == Record.NO_NEXT_RELATIONSHIP.intValue() ? 0 : (record.getFirstIn() & 0x700000000L) >> 31; cursor.putInt( (int) record.getFirstOut() ); cursor.putInt( (int) record.getFirstIn() ); cursor.putInt( (int) record.getFirstLoop() );
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() ); }; }
/** * 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; }
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 assertBatch( RelationshipGroupRecord[] batch, long lastOwningNodeLastBatch ) { for ( int i = 0; i < batch.length; i++ ) { RelationshipGroupRecord record = batch[i]; assertTrue( record.getId() > Record.NULL_REFERENCE.longValue() ); assertTrue( record.getOwningNode() > lastOwningNodeLastBatch ); assertEquals( 1, record.getFirstOut() ); // the mark our store mock sets when preparing if ( record.getNext() == Record.NULL_REFERENCE.longValue() ) { // This is the last in the chain, verify that this is either: assertTrue( // - the last one in the batch, or i == batch.length - 1 || // - the last one for this node batch[i + 1].getOwningNode() > record.getOwningNode() ); } } }
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() ); }
RelationshipGroupRecord groupRecord = getRecord( groupStore, group ); assertNotEquals( groupRecord.getNext(), -1 ); assertRelationshipChain( neoStores.getRelationshipStore(), node, groupRecord.getFirstOut(), rel1.getId(), rel2.getId(), rel3.getId() ); assertRelationshipChain( neoStores.getRelationshipStore(), node, otherGroupRecord.getFirstOut(), rel4.getId(), rel5.getId(), rel6.getId() );
private static void assertDenseRelationshipCounts( RecordChangeSet recordChangeSet, long nodeId, int type, int outCount, int inCount ) { RelationshipGroupRecord group = getRelationshipGroup( recordChangeSet, recordChangeSet.getNodeRecords().getOrLoad( nodeId, null ).forReadingData(), type ).forReadingData(); assertNotNull( group ); RelationshipRecord rel; long relId = group.getFirstOut(); if ( relId != Record.NO_NEXT_RELATIONSHIP.intValue() ) { rel = recordChangeSet.getRelRecords().getOrLoad( relId, null ).forReadingData(); // count is stored in the back pointer of the first relationship in the chain assertEquals( "Stored relationship count for OUTGOING differs", outCount, rel.getFirstPrevRel() ); assertEquals( "Manually counted relationships for OUTGOING differs", outCount, manuallyCountRelationships( recordChangeSet, nodeId, relId ) ); } relId = group.getFirstIn(); if ( relId != Record.NO_NEXT_RELATIONSHIP.intValue() ) { rel = recordChangeSet.getRelRecords().getOrLoad( relId, null ).forReadingData(); assertEquals( "Stored relationship count for INCOMING differs", inCount, rel.getSecondPrevRel() ); assertEquals( "Manually counted relationships for INCOMING differs", inCount, manuallyCountRelationships( recordChangeSet, nodeId, relId ) ); } }
assertEquals( -1, groupRecord.getNext() ); assertEquals( -1, groupRecord.getPrev() ); assertRelationshipChain( neoStores.getRelationshipStore(), node, groupRecord.getFirstOut(), rel1.getId(), rel4.getId() ); assertRelationshipChain( neoStores.getRelationshipStore(), node, groupRecord.getFirstIn(), rel2.getId(), rel5.getId() ); assertRelationshipChain( neoStores.getRelationshipStore(), node, groupRecord.getFirstLoop(), rel3.getId(), rel6.getId() );
@Override public long getNextRel( RelationshipGroupRecord group ) { return group.getFirstOut(); }
@Override protected boolean canUseFixedReferences( RelationshipGroupRecord record, int recordSize ) { return isRecordBigEnoughForFixedReferences( recordSize ) && (record.getNext() == NULL || (record.getNext() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstOut() == NULL || (record.getFirstOut() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstIn() == NULL || (record.getFirstIn() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstLoop() == NULL || (record.getFirstLoop() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getOwningNode() == NULL || (record.getOwningNode() & ONE_BIT_OVERFLOW_BIT_MASK) == 0); }
@Override protected boolean canUseFixedReferences( RelationshipGroupRecord record, int recordSize ) { return isRecordBigEnoughForFixedReferences( recordSize ) && (record.getNext() == NULL || (record.getNext() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstOut() == NULL || (record.getFirstOut() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstIn() == NULL || (record.getFirstIn() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstLoop() == NULL || (record.getFirstLoop() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getOwningNode() == NULL || (record.getOwningNode() & ONE_BIT_OVERFLOW_BIT_MASK) == 0); }
@Override protected boolean canUseFixedReferences( RelationshipGroupRecord record, int recordSize ) { return isRecordBigEnoughForFixedReferences( recordSize ) && (record.getNext() == NULL || (record.getNext() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstOut() == NULL || (record.getFirstOut() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstIn() == NULL || (record.getFirstIn() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getFirstLoop() == NULL || (record.getFirstLoop() & ONE_BIT_OVERFLOW_BIT_MASK) == 0) && (record.getOwningNode() == NULL || (record.getOwningNode() & ONE_BIT_OVERFLOW_BIT_MASK) == 0); }
@Override protected byte headerBits( RelationshipGroupRecord record ) { byte header = 0; header = set( header, HAS_OUTGOING_BIT, record.getFirstOut(), NULL ); header = set( header, HAS_INCOMING_BIT, record.getFirstIn(), NULL ); header = set( header, HAS_LOOP_BIT, record.getFirstLoop(), NULL ); header = set( header, HAS_NEXT_BIT, record.getNext(), NULL ); return header; }
@Override protected byte headerBits( RelationshipGroupRecord record ) { byte header = 0; header = set( header, HAS_OUTGOING_BIT, record.getFirstOut(), NULL ); header = set( header, HAS_INCOMING_BIT, record.getFirstIn(), NULL ); header = set( header, HAS_LOOP_BIT, record.getFirstLoop(), NULL ); header = set( header, HAS_NEXT_BIT, record.getNext(), NULL ); return header; }