/** * @param fromId entity id to start at, exclusive, i.e. the given {@code fromId} will not be included in the result. * @param labelIds label token ids. * @return node ids with any of the given label ids. */ PrimitiveLongResourceIterator nodesWithAnyOfLabels( long fromId, int[] labelIds );
@Override public PrimitiveLongResourceIterator nodesGetForLabel( int labelId ) { return getLabelScanReader().nodesWithLabel( labelId ); }
@Override public void close() { labelScanReader.close(); }
@Test public void shouldFindDecentAmountOfNodesForALabel() throws Exception { // GIVEN // 16 is the magic number of the page iterator // 32 is the number of nodes in each lucene document final int labelId = 1; int nodeCount = 32 * 16 + 10; start(); write( new PrefetchingIterator<NodeLabelUpdate>() { private int i = -1; @Override protected NodeLabelUpdate fetchNextOrNull() { return ++i < nodeCount ? labelChanges( i, NO_LABELS, new long[]{labelId} ) : null; } } ); // WHEN Set<Long> nodeSet = new TreeSet<>(); LabelScanReader reader = store.newReader(); LongIterator nodes = reader.nodesWithLabel( labelId ); while ( nodes.hasNext() ) { nodeSet.add( nodes.next() ); } reader.close(); // THEN assertEquals( "Found gaps in node id range: " + gaps( nodeSet, nodeCount ), nodeCount, nodeSet.size() ); }
@Override public void nodeLabelIntersectionScan( NodeLabelIndexCursor cursor, int... labels ) { ktx.assertOpen(); DefaultNodeLabelIndexCursor client = (DefaultNodeLabelIndexCursor) cursor; client.setRead( this ); client.intersectionScan( new NodeLabelIndexProgressor( labelScanReader().nodesWithAllLabels( labels ), client ), false, labels ); }
PrimitiveLongCollections.asArray( reader.nodesWithAllLabels( new int[] {labelId1, labelId2} ) ) ); assertArrayEquals( new long[] {4, 5}, PrimitiveLongCollections.asArray( reader.nodesWithAllLabels( new int[] {labelId1, labelId3} ) ) ); assertArrayEquals( new long[] {5}, PrimitiveLongCollections.asArray( reader.nodesWithAllLabels( new int[] {labelId1, labelId2, labelId3} ) ) );
@Override public final void nodeLabelScan( int label, NodeLabelIndexCursor cursor ) { ktx.assertOpen(); DefaultNodeLabelIndexCursor indexCursor = (DefaultNodeLabelIndexCursor) cursor; indexCursor.setRead( this ); labelScanReader().nodesWithLabel( indexCursor, label); }
LabelScanViewIdIterator( LabelScanReader labelScanReader, int[] labelIds, CURSOR entityCursor ) { this.labelScanReader = labelScanReader; this.entityCursor = entityCursor; this.idIterator = labelScanReader.nodesWithAnyOfLabels( labelIds ); this.labelIds = labelIds; }
private void closeSchemaResources() { if ( indexReaderFactory != null ) { indexReaderFactory.close(); // we can actually keep this object around } if ( labelScanReader != null ) { labelScanReader.close(); labelScanReader = null; } }
@Override public void nodeLabelIntersectionScan( NodeLabelIndexCursor cursor, int... labels ) { ktx.assertOpen(); DefaultNodeLabelIndexCursor client = (DefaultNodeLabelIndexCursor) cursor; client.setRead( this ); client.intersectionScan( new NodeLabelIndexProgressor( labelScanReader().nodesWithAllLabels( labels ), client ), false, labels ); }
private long[] readNodesForLabel( LabelScanStore labelScanStore ) { try ( LabelScanReader reader = labelScanStore.newReader() ) { return PrimitiveLongCollections.asArray( reader.nodesWithLabel( labelId ) ); } }
@Override public void invalidateCache() { this.idIterator.close(); this.idIterator = labelScanReader.nodesWithAnyOfLabels( lastReturnedId, labelIds ); } }
@Test public void shouldCloseOpenedLabelScanReader() { // given Supplier<LabelScanReader> scanStore = mock( Supplier.class ); LabelScanReader scanReader = mock( LabelScanReader.class ); when( scanStore.get() ).thenReturn( scanReader ); RecordStorageReader statement = new RecordStorageReader( null, null, MockedNeoStores.basicMockedNeoStores(), null, null, mock( Supplier.class ), scanStore, mock( RecordStorageCommandCreationContext.class ) ); statement.acquire(); // when LabelScanReader actualReader = statement.getLabelScanReader(); // then assertEquals( scanReader, actualReader ); // when statement.close(); // then verify( scanStore ).get(); verifyNoMoreInteractions( scanStore ); verify( scanReader ).close(); verifyNoMoreInteractions( scanReader ); } }
private void assertLabelScanStoreContains( LabelScanStore labelScanStore, int labelId, long... nodes ) { try ( LabelScanReader labelScanReader = labelScanStore.newReader() ) { List<Long> actualNodeIds = extractPrimitiveLongIteratorAsList( labelScanReader.nodesWithLabel( labelId ) ); List<Long> expectedNodeIds = Arrays.stream( nodes ).boxed().collect( Collectors.toList() ); assertEquals( expectedNodeIds, actualNodeIds ); } }
@Override public void nodeLabelUnionScan( NodeLabelIndexCursor cursor, int... labels ) { ktx.assertOpen(); DefaultNodeLabelIndexCursor client = (DefaultNodeLabelIndexCursor) cursor; client.setRead( this ); client.unionScan( new NodeLabelIndexProgressor( labelScanReader().nodesWithAnyOfLabels( labels ), client ), false, labels ); }
@Override public void close() { labelScanReader.close(); }
private void assertNodesForLabel( int labelId, long... expectedNodeIds ) { Set<Long> nodeSet = new HashSet<>(); LongIterator nodes = store.newReader().nodesWithLabel( labelId ); while ( nodes.hasNext() ) { nodeSet.add( nodes.next() ); } for ( long expectedNodeId : expectedNodeIds ) { assertTrue( "Expected node " + expectedNodeId + " not found in scan store", nodeSet.remove( expectedNodeId ) ); } assertTrue( "Unexpected nodes in scan store " + nodeSet, nodeSet.isEmpty() ); }
@Test public void visitOnlyLabeledNodes() throws Exception { LabelScanReader labelScanReader = mock( LabelScanReader.class ); when( labelScanStore.newReader() ).thenReturn( labelScanReader ); when( nodeLabelRanges.maxCount() ).thenReturn( 1L ); PrimitiveLongResourceIterator labeledNodesIterator = PrimitiveLongResourceCollections.iterator( null, 1, 2, 3, 4, 5, 6, 7, 8 ); when( nodeStore.getHighestPossibleIdInUse() ).thenReturn( 200L ); when( nodeStore.getHighId() ).thenReturn( 20L ); when( labelScanReader.nodesWithAnyOfLabels( new int[] {2, 6} ) ).thenReturn( labeledNodesIterator ); when( nodeStore.openPageCursorForReading( anyLong() ) ).thenReturn( mock( PageCursor.class ) ); mockLabelNodeCount( countStore, 2 ); mockLabelNodeCount( countStore, 6 ); DynamicIndexStoreView storeView = dynamicIndexStoreView(); StoreScan<Exception> storeScan = storeView .visitNodes( new int[]{2, 6}, propertyKeyIdFilter, propertyUpdateVisitor, labelUpdateVisitor, false ); storeScan.run(); Mockito.verify( nodeStore, times( 8 ) ) .getRecordByCursor( anyLong(), any( NodeRecord.class ), any( RecordLoad.class ), any( PageCursor.class ) ); }
private void closeSchemaResources() { if ( indexReaderFactory != null ) { indexReaderFactory.close(); // we can actually keep this object around } if ( labelScanReader != null ) { labelScanReader.close(); labelScanReader = null; } }
@Test public void shouldWorkWithAFullRange() { // given long labelId = 0; List<NodeLabelUpdate> updates = new ArrayList<>(); Set<Long> nodes = new HashSet<>(); for ( int i = 0; i < 34; i++ ) { updates.add( NodeLabelUpdate.labelChanges( i, new long[]{}, new long[]{labelId} ) ); nodes.add( (long) i ); } start( updates ); // when LabelScanReader reader = store.newReader(); Set<Long> nodesWithLabel = PrimitiveLongCollections.toSet( reader.nodesWithLabel( (int) labelId ) ); // then assertEquals( nodes, nodesWithLabel ); }