private NodeRecord loadNode( long nodeId ) { if ( nodeRecord == null ) { nodeRecord = nodeStore.newRecord(); } nodeStore.getRecord( nodeId, nodeRecord, RecordLoad.NORMAL ); return nodeRecord; }
@Test void scanForHighIdOnlyOnceWhenProcessCache() { NeoStores neoStores = mock( NeoStores.class, Mockito.RETURNS_MOCKS ); NodeStore nodeStore = mock( NodeStore.class ); NodeRecord nodeRecord = mock( NodeRecord.class ); StoreProcessor storeProcessor = mock( StoreProcessor.class ); when( neoStores.getNodeStore() ).thenReturn( nodeStore ); when( nodeStore.getHighId() ).thenReturn( 10L ); when( nodeStore.getRecord( anyLong(), any( NodeRecord.class ), any( RecordLoad.class ) ) ).thenReturn( nodeRecord ); when( nodeStore.newRecord() ).thenReturn( nodeRecord ); StoreAccess storeAccess = new StoreAccess( neoStores ); storeAccess.initialize(); CacheTask.CheckNextRel cacheTask = new CacheTask.CheckNextRel( Stage.SEQUENTIAL_FORWARD, new DefaultCacheAccess( Counts.NONE, 1 ), storeAccess, storeProcessor ); cacheTask.processCache(); verify( nodeStore, times( 1 ) ).getHighId(); } }
@Override public Value getNodePropertyValue( long nodeId, int propertyKeyId ) { NodeRecord nodeRecord = nodeStore.newRecord(); if ( nodeStore.getRecord( nodeId, nodeRecord, FORCE ).inUse() ) { SpecificValueVisitor visitor = new SpecificValueVisitor( propertyKeyId ); try { if ( visitPropertyRecordChain( nodeRecord.getNextProp(), visitor ) ) { return visitor.foundPropertyValue; } } catch ( CircularPropertyRecordChainException e ) { // If we discover a circular reference and still haven't found the property then we won't find it. // There are other places where this circular reference will be logged as an inconsistency, // so simply catch this exception here and let this method return NO_VALUE below. } } return Values.NO_VALUE; }
private <RECEIVER extends PropertyReceiver> void nodeLoadProperties( long nodeId, RECEIVER receiver ) { NodeRecord nodeRecord = nodeStore.getRecord( nodeId, nodeStore.newRecord(), NORMAL ); loadProperties( nodeRecord.getNextProp(), receiver ); }
@Override public Value getNodePropertyValue( long nodeId, int propertyKeyId ) throws EntityNotFoundException { NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), FORCE ); if ( !node.inUse() ) { throw new EntityNotFoundException( EntityType.NODE, nodeId ); } long firstPropertyId = node.getNextProp(); if ( firstPropertyId == Record.NO_NEXT_PROPERTY.intValue() ) { return Values.NO_VALUE; } for ( PropertyRecord propertyRecord : propertyStore.getPropertyRecordChain( firstPropertyId ) ) { PropertyBlock propertyBlock = propertyRecord.getPropertyBlock( propertyKeyId ); if ( propertyBlock != null ) { return propertyBlock.newPropertyValue( propertyStore ); } } return Values.NO_VALUE; }
inUseRecord.setInUse( true ); when( nodeStore.newRecord() ).thenReturn( emptyRecord ); when( nodeStore.getRecord( anyLong(), any( NodeRecord.class ), any( RecordLoad.class ) ) ).thenReturn( inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord, inUseRecord );
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 ); }
if ( type == EntityType.NODE ) entity = nodeStore.getRecord( entityId, nodeStore.newRecord(), FORCE );
@Override public EntityUpdates nodeAsUpdates( long nodeId ) { NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), FORCE ); if ( !node.inUse() ) { return null; } long firstPropertyId = node.getNextProp(); if ( firstPropertyId == Record.NO_NEXT_PROPERTY.intValue() ) { return null; // no properties => no updates (it's not going to be in any index) } long[] labels = parseLabelsField( node ).get( nodeStore ); if ( labels.length == 0 ) { return null; // no labels => no updates (it's not going to be in any index) } EntityUpdates.Builder update = EntityUpdates.forEntity( nodeId ).withTokens( labels ); for ( PropertyRecord propertyRecord : propertyStore.getPropertyRecordChain( firstPropertyId ) ) { for ( PropertyBlock property : propertyRecord ) { Value value = property.getType().value( property, propertyStore ); update.added( property.getKeyIndexId(), value ); } } return update.build(); }
@Test public void shouldCombineProperFiveByteLabelField() throws Exception { // GIVEN // -- a store EphemeralFileSystemAbstraction fs = efs.get(); nodeStore = newNodeStore( fs ); // -- a record with the msb carrying a negative value long nodeId = 0; long labels = 0x8000000001L; NodeRecord record = new NodeRecord( nodeId, false, NO_NEXT_RELATIONSHIP.intValue(), NO_NEXT_PROPERTY.intValue() ); record.setInUse( true ); record.setLabelField( labels, Collections.emptyList() ); nodeStore.updateRecord( record ); // WHEN // -- reading that record back NodeRecord readRecord = nodeStore.getRecord( nodeId, nodeStore.newRecord(), NORMAL ); // THEN // -- the label field must be the same assertEquals( labels, readRecord.getLabelField() ); }
@Test public void shouldNotCreateSameLabelTwiceOnSameNode() { // GIVEN BatchInserter inserter = globalInserter; // WHEN long nodeId = inserter.createNode( map( "itemId", 1000L ), label( "Item" ), label( "Item" ) ); // THEN NodeStore nodeStore = getFlushedNeoStores( inserter ).getNodeStore(); NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), NORMAL ); NodeLabels labels = NodeLabelsField.parseLabelsField( node ); long[] labelIds = labels.get( nodeStore ); assertEquals( 1, labelIds.length ); }
@Test public void shouldSortLabelIdsWhenGetOrCreate() { // GIVEN BatchInserter inserter = globalInserter; // WHEN long nodeId = inserter.createNode( map( "Item", 123456789123L ), label( "AA" ), label( "BB" ), label( "CC" ), label( "DD" ) ); inserter.setNodeLabels( nodeId, label( "CC" ), label( "AA" ), label( "DD" ), label( "EE" ), label( "FF" ) ); // THEN NodeStore nodeStore = getFlushedNeoStores( inserter ).getNodeStore(); NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), RecordLoad.NORMAL ); NodeLabels labels = NodeLabelsField.parseLabelsField( node ); long[] labelIds = labels.get( nodeStore ); long[] sortedLabelIds = labelIds.clone(); Arrays.sort( sortedLabelIds ); assertArrayEquals( sortedLabelIds, labelIds ); }
nodeStore.getRecord( i, record, NORMAL ); assertTrue( "record[" + i + "] should be in use", record.inUse() ); assertThat( "record[" + i + "] should have nextRelId of " + i,
record = stores.getNodeStore().getRecord( nodeId, record, RecordLoad.NORMAL ); long propId = record.getNextProp(); record.setNextProp( AbstractBaseRecord.NO_ID );
private NodeRecord loadNode( long nodeId ) { if ( nodeRecord == null ) { nodeRecord = nodeStore.newRecord(); } nodeStore.getRecord( nodeId, nodeRecord, RecordLoad.NORMAL ); return nodeRecord; }
@Override public Value getNodePropertyValue( long nodeId, int propertyKeyId ) throws EntityNotFoundException { NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), FORCE ); if ( !node.inUse() ) { throw new EntityNotFoundException( EntityType.NODE, nodeId ); } long firstPropertyId = node.getNextProp(); if ( firstPropertyId == Record.NO_NEXT_PROPERTY.intValue() ) { return Values.NO_VALUE; } for ( PropertyRecord propertyRecord : propertyStore.getPropertyRecordChain( firstPropertyId ) ) { PropertyBlock propertyBlock = propertyRecord.getPropertyBlock( propertyKeyId ); if ( propertyBlock != null ) { return propertyBlock.newPropertyValue( propertyStore ); } } return Values.NO_VALUE; }
if ( type == EntityType.NODE ) entity = nodeStore.getRecord( entityId, nodeStore.newRecord(), FORCE );
@Override public EntityUpdates nodeAsUpdates( long nodeId ) { NodeRecord node = nodeStore.getRecord( nodeId, nodeStore.newRecord(), FORCE ); if ( !node.inUse() ) { return null; } long firstPropertyId = node.getNextProp(); if ( firstPropertyId == Record.NO_NEXT_PROPERTY.intValue() ) { return null; // no properties => no updates (it's not going to be in any index) } long[] labels = parseLabelsField( node ).get( nodeStore ); if ( labels.length == 0 ) { return null; // no labels => no updates (it's not going to be in any index) } EntityUpdates.Builder update = EntityUpdates.forEntity( nodeId ).withTokens( labels ); for ( PropertyRecord propertyRecord : propertyStore.getPropertyRecordChain( firstPropertyId ) ) { for ( PropertyBlock property : propertyRecord ) { Value value = property.getType().value( property, propertyStore ); update.added( property.getKeyIndexId(), value ); } } return update.build(); }