@Override public MultipleIndexUpdater newPopulatingUpdater( NodePropertyAccessor accessor ) { Map<SchemaDescriptor,Pair<IndexPopulation,IndexUpdater>> updaters = new HashMap<>(); forEachPopulation( population -> { IndexUpdater updater = population.populator.newPopulatingUpdater( accessor ); updaters.put( population.schema(), Pair.of( population, updater ) ); } ); return new MultipleIndexUpdater( this, updaters, logProvider ); }
private static IndexPopulator createIndexPopulator( IndexUpdater indexUpdater ) { IndexPopulator indexPopulator = createIndexPopulator(); when( indexPopulator.newPopulatingUpdater( any( NodePropertyAccessor.class ) ) ).thenReturn( indexUpdater ); return indexPopulator; }
@Override public IndexUpdater newPopulatingUpdater( NodePropertyAccessor accessor ) { LazyInstanceSelector<IndexUpdater> updaterSelector = new LazyInstanceSelector<>( slot -> instanceSelector.select( slot ).newPopulatingUpdater( accessor ) ); return new FusionIndexUpdater( slotSelector, updaterSelector ); }
private static void updatePopulator( IndexPopulator populator, Iterable<IndexEntryUpdate<?>> updates, NodePropertyAccessor accessor ) throws IOException, IndexEntryConflictException { try ( IndexUpdater updater = populator.newPopulatingUpdater( accessor ) ) { for ( IndexEntryUpdate<?> update : updates ) { updater.process( update ); } } } }
@Test public void populateFromQueueDoesNothingIfThresholdNotReached() throws Exception { setProperty( QUEUE_THRESHOLD_NAME, 5 ); BatchingMultipleIndexPopulator batchingPopulator = new BatchingMultipleIndexPopulator( mock( IndexStoreView.class ), immediateExecutor(), NullLogProvider.getInstance(), mock( SchemaState.class ) ); IndexPopulator populator = addPopulator( batchingPopulator, index1 ); IndexUpdater updater = mock( IndexUpdater.class ); when( populator.newPopulatingUpdater( any() ) ).thenReturn( updater ); IndexEntryUpdate<?> update1 = add( 1, index1.schema(), "foo" ); IndexEntryUpdate<?> update2 = add( 2, index1.schema(), "bar" ); batchingPopulator.queueUpdate( update1 ); batchingPopulator.queueUpdate( update2 ); batchingPopulator.populateFromQueueBatched( 42 ); verify( updater, never() ).process( any() ); verify( populator, never() ).newPopulatingUpdater( any() ); }
@Test public void testMultiplePopulatorUpdater() throws IndexEntryConflictException, FlipFailedKernelException { IndexUpdater indexUpdater1 = mock( IndexUpdater.class ); IndexPopulator indexPopulator1 = createIndexPopulator( indexUpdater1 ); IndexPopulator indexPopulator2 = createIndexPopulator(); addPopulator( indexPopulator1, 1 ); addPopulator( indexPopulator2, 2 ); doThrow(getPopulatorException() ).when( indexPopulator2 ) .newPopulatingUpdater( any( NodePropertyAccessor.class ) ); IndexUpdater multipleIndexUpdater = multipleIndexPopulator.newPopulatingUpdater( mock( NodePropertyAccessor.class ) ); IndexEntryUpdate<?> propertyUpdate = createIndexEntryUpdate( index1 ); multipleIndexUpdater.process( propertyUpdate ); checkPopulatorFailure( indexPopulator2 ); verify( indexUpdater1 ).process( propertyUpdate ); }
@Test public void populateFromQueuePopulatesWhenThresholdReached() throws Exception { setProperty( QUEUE_THRESHOLD_NAME, 2 ); NeoStores neoStores = mock( NeoStores.class ); NodeStore nodeStore = mock( NodeStore.class ); when( neoStores.getNodeStore() ).thenReturn( nodeStore ); NeoStoreIndexStoreView storeView = new NeoStoreIndexStoreView( LockService.NO_LOCK_SERVICE, neoStores ); BatchingMultipleIndexPopulator batchingPopulator = new BatchingMultipleIndexPopulator( storeView, immediateExecutor(), NullLogProvider.getInstance(), mock( SchemaState.class ) ); IndexPopulator populator1 = addPopulator( batchingPopulator, index1 ); IndexUpdater updater1 = mock( IndexUpdater.class ); when( populator1.newPopulatingUpdater( any() ) ).thenReturn( updater1 ); IndexPopulator populator2 = addPopulator( batchingPopulator, index42 ); IndexUpdater updater2 = mock( IndexUpdater.class ); when( populator2.newPopulatingUpdater( any() ) ).thenReturn( updater2 ); batchingPopulator.indexAllEntities(); IndexEntryUpdate<?> update1 = add( 1, index1.schema(), "foo" ); IndexEntryUpdate<?> update2 = add( 2, index42.schema(), "bar" ); IndexEntryUpdate<?> update3 = add( 3, index1.schema(), "baz" ); batchingPopulator.queueUpdate( update1 ); batchingPopulator.queueUpdate( update2 ); batchingPopulator.queueUpdate( update3 ); batchingPopulator.populateFromQueueBatched( 42 ); verify( updater1 ).process( update1 ); verify( updater1 ).process( update3 ); verify( updater2 ).process( update2 ); }
try ( IndexUpdater updater = populator.newPopulatingUpdater( nodePropertyAccessor ) )
when( populator.newPopulatingUpdater( storeView ) ).thenReturn( updater ); order.verify( populator ).includeSample( add( 1, "value1" ) ); order.verify( populator, times( 3 ) ).add( any( Collection.class ) ); order.verify( populator ).newPopulatingUpdater( storeView ); order.verify( updater ).close(); order.verify( populator ).sampleResult();
@Test public void shouldUpdateWithAllValuesDuringPopulation() throws Exception { // GIVEN withPopulator( indexProvider.getPopulator( descriptor, indexSamplingConfig ), p -> { try ( IndexUpdater updater = p.newPopulatingUpdater( this::valueSet1Lookup ) ) { for ( NodeAndValue entry : valueSet1 ) { updater.process( add( entry.nodeId, descriptor.schema(), entry.value ) ); } } } ); // THEN assertHasAllValues( valueSet1 ); }
private void buildReferencePopulatorSingleThreaded( Generator[] generators, Collection<IndexEntryUpdate<?>> updates ) throws IndexEntryConflictException { IndexPopulator referencePopulator = indexProvider.getPopulator( descriptor2, samplingConfig ); referencePopulator.create(); boolean referenceSuccess = false; try { for ( Generator generator : generators ) { generator.reset(); for ( int i = 0; i < BATCHES_PER_THREAD; i++ ) { referencePopulator.add( generator.batch() ); } } try ( IndexUpdater updater = referencePopulator.newPopulatingUpdater( nodePropertyAccessor ) ) { for ( IndexEntryUpdate<?> update : updates ) { updater.process( update ); } } referenceSuccess = true; } finally { referencePopulator.close( referenceSuccess ); } }
@Test public void shouldApplyUpdatesIdempotently() throws Exception { // GIVEN IndexSamplingConfig indexSamplingConfig = new IndexSamplingConfig( Config.defaults() ); final Value propertyValue = Values.of( "value1" ); withPopulator( indexProvider.getPopulator( descriptor, indexSamplingConfig ), p -> { long nodeId = 1; // update using populator... IndexEntryUpdate<SchemaDescriptor> update = add( nodeId, descriptor.schema(), propertyValue ); p.add( singletonList( update ) ); // ...is the same as update using updater try ( IndexUpdater updater = p.newPopulatingUpdater( ( node, propertyId ) -> propertyValue ) ) { updater.process( update ); } } ); // THEN try ( IndexAccessor accessor = indexProvider.getOnlineAccessor( descriptor, indexSamplingConfig ) ) { try ( IndexReader reader = new QueryResultComparingIndexReader( accessor.newReader() ) ) { int propertyKeyId = descriptor.schema().getPropertyId(); LongIterator nodes = reader.query( IndexQuery.exact( propertyKeyId, propertyValue ) ); assertEquals( asSet( 1L ), PrimitiveLongCollections.toSet( nodes ) ); } } }
@Override public MultipleIndexUpdater newPopulatingUpdater( NodePropertyAccessor accessor ) { Map<SchemaDescriptor,Pair<IndexPopulation,IndexUpdater>> updaters = new HashMap<>(); forEachPopulation( population -> { IndexUpdater updater = population.populator.newPopulatingUpdater( accessor ); updaters.put( population.schema(), Pair.of( population, updater ) ); } ); return new MultipleIndexUpdater( this, updaters, logProvider ); }
@Override public IndexUpdater newPopulatingUpdater( NodePropertyAccessor accessor ) { LazyInstanceSelector<IndexUpdater> updaterSelector = new LazyInstanceSelector<>( slot -> instanceSelector.select( slot ).newPopulatingUpdater( accessor ) ); return new FusionIndexUpdater( slotSelector, updaterSelector ); }