@@ -2763,8 +2763,19 @@ TYPED_TEST(SVSTieredIndexTestBasic, runGCAPI) {
27632763 ASSERT_EQ (tiered_index->GetSVSIndex ()->indexStorageSize (), n);
27642764 auto size_before_gc = tiered_index->getAllocationSize ();
27652765
2766+ auto jobs_before_gc = mock_thread_pool.jobQ .size ();
27662767 // Run the GC API call, expect that we will clean up the SVS index.
27672768 VecSimTieredIndex_GC (tiered_index);
2769+ // Expected that GC jobs were added to the queue.
2770+ ASSERT_EQ (mock_thread_pool.jobQ .size (), jobs_before_gc + mock_thread_pool.thread_pool_size );
2771+ // Run GC twice.
2772+ VecSimTieredIndex_GC (tiered_index);
2773+ // Expected that no new GC jobs were added to the queue.
2774+ ASSERT_EQ (mock_thread_pool.jobQ .size (), jobs_before_gc + mock_thread_pool.thread_pool_size );
2775+ // Wait for any pending jobs to complete. As far as SVS GC is done via a job.
2776+ mock_thread_pool.init_threads ();
2777+ mock_thread_pool.thread_pool_join ();
2778+ // Validate sizes after GC.
27682779 ASSERT_EQ (tiered_index->indexSize (), n - threshold);
27692780 ASSERT_EQ (tiered_index->GetBackendIndex ()->indexSize (), n - threshold);
27702781 ASSERT_EQ (tiered_index->GetSVSIndex ()->indexStorageSize (), n - threshold);
@@ -2775,6 +2786,68 @@ TYPED_TEST(SVSTieredIndexTestBasic, runGCAPI) {
27752786 EXPECT_EQ (tiered_index->statisticInfo ().numberOfMarkedDeleted , 0 );
27762787}
27772788
2789+ TYPED_TEST (SVSTieredIndexTestBasic, runGCParallel) {
2790+ // Create TieredSVS index instance with a mock queue.
2791+ size_t dim = 4 ;
2792+ size_t threshold = 1024 ;
2793+ const size_t n = threshold * 4 ;
2794+ SVSParams params = {.type = TypeParam::get_index_type (), .dim = dim, .metric = VecSimMetric_L2};
2795+ VecSimParams svs_params = CreateParams (params);
2796+ auto mock_thread_pool = tieredIndexMock ();
2797+
2798+ // Force trigger the first update job for 64 first vectors.
2799+ auto *tiered_index = this ->CreateTieredSVSIndex (svs_params, mock_thread_pool, 64 );
2800+ ASSERT_INDEX (tiered_index);
2801+ auto allocator = tiered_index->getAllocator ();
2802+
2803+ // Insert n vectors directly to SVS.
2804+ std::srand (10 ); // create pseudo random generator with any arbitrary seed.
2805+ for (size_t i = 0 ; i < n; i++) {
2806+ TEST_DATA_T vector[dim];
2807+ for (size_t j = 0 ; j < dim; j++) {
2808+ vector[j] = std::rand () / (TEST_DATA_T)RAND_MAX;
2809+ }
2810+ VecSimIndex_AddVector (tiered_index->GetBackendIndex (), vector, i);
2811+ }
2812+
2813+ ASSERT_EQ (tiered_index->indexSize (), n);
2814+ ASSERT_EQ (tiered_index->GetBackendIndex ()->indexSize (), n);
2815+
2816+ // Initialize the thread pool to start processing jobs.
2817+ mock_thread_pool.init_threads ();
2818+
2819+ // Run the mess of add, delete, GC
2820+ for (size_t i = 0 ; i < threshold; i++) {
2821+ // Run GC for every 64 iterations.
2822+ if (i % 64 == 0 ) {
2823+ VecSimTieredIndex_GC (tiered_index);
2824+ }
2825+ // Add a new vector
2826+ TEST_DATA_T vector[dim];
2827+ for (size_t j = 0 ; j < dim; j++) {
2828+ vector[j] = std::rand () / (TEST_DATA_T)RAND_MAX;
2829+ }
2830+ VecSimIndex_AddVector (tiered_index, vector, n + i);
2831+ // Delete an existing vector
2832+ tiered_index->deleteVector (i + threshold);
2833+ }
2834+ // Final GC after all operations.
2835+ VecSimTieredIndex_GC (tiered_index);
2836+ // Wait for any pending jobs to complete. As far as SVS GC is done via a job.
2837+ mock_thread_pool.thread_pool_join ();
2838+
2839+ // Validate sizes after GC.
2840+ auto tiered_size = tiered_index->indexSize ();
2841+ auto flat_size = tiered_index->GetFlatIndex ()->indexSize ();
2842+ auto backend_size = tiered_index->GetBackendIndex ()->indexSize ();
2843+ ASSERT_EQ (tiered_size, n);
2844+ ASSERT_EQ (tiered_size, backend_size + flat_size);
2845+ // Expect that GC cleaned all the deleted vectors.
2846+ ASSERT_EQ (tiered_index->GetSVSIndex ()->indexStorageSize (), backend_size);
2847+ ASSERT_EQ (tiered_index->GetSVSIndex ()->getNumMarkedDeleted (), 0 );
2848+ EXPECT_EQ (tiered_index->statisticInfo ().numberOfMarkedDeleted , 0 );
2849+ }
2850+
27782851TYPED_TEST (SVSTieredIndexTestBasic, switchDeleteModes) {
27792852 // Create TieredSVS index instance with a mock queue.
27802853 size_t dim = 16 ;
0 commit comments