1+
2+ // Copyright 2024-present the vsag project
3+ //
4+ // Licensed under the Apache License, Version 2.0 (the "License");
5+ // you may not use this file except in compliance with the License.
6+ // You may obtain a copy of the License at
7+ //
8+ // http://www.apache.org/licenses/LICENSE-2.0
9+ //
10+ // Unless required by applicable law or agreed to in writing, software
11+ // distributed under the License is distributed on an "AS IS" BASIS,
12+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ // See the License for the specific language governing permissions and
14+ // limitations under the License.
15+
16+ #include " visited_list.h"
17+
18+ #include < thread>
19+
20+ #include " catch2/catch_test_macros.hpp"
21+ #include " default_allocator.h"
22+ using namespace vsag ;
23+
24+ TEST_CASE (" test visited_list basic" , " [ut][visited_list]" ) {
25+ auto allocator = std::make_shared<DefaultAllocator>();
26+ auto size = 10000 ;
27+ auto vl_ptr = std::make_shared<VisitedList>(size, allocator.get ());
28+
29+ SECTION (" test set & get normal" ) {
30+ int count = 500 ;
31+ std::unordered_set<InnerIdType> ids;
32+ for (int i = 0 ; i < count; ++i) {
33+ auto id = random () % size;
34+ ids.insert (id);
35+ vl_ptr->Set (id);
36+ }
37+ for (auto & id : ids) {
38+ REQUIRE (vl_ptr->Get (id));
39+ }
40+
41+ for (int i = 0 ; i < size; ++i) {
42+ if (ids.count (i) == 0 ) {
43+ REQUIRE (not vl_ptr->Get (i));
44+ }
45+ }
46+ }
47+
48+ SECTION (" test reset" ) {
49+ int count = 500 ;
50+ std::unordered_set<InnerIdType> ids;
51+ for (int i = 0 ; i < count; ++i) {
52+ auto id = random () % size;
53+ ids.insert (id);
54+ vl_ptr->Set (id);
55+ }
56+ vl_ptr->Reset ();
57+ for (auto & id : ids) {
58+ REQUIRE (not vl_ptr->Get (id));
59+ }
60+ }
61+ }
62+
63+ TEST_CASE (" test visited_list_pool basic" , " [ut][visited_list_pool]" ) {
64+ auto allocator = std::make_shared<DefaultAllocator>();
65+ auto init_size = 10 ;
66+ auto vl_size = 1000 ;
67+ auto pool = std::make_shared<VisitedListPool>(init_size, vl_size, allocator.get ());
68+
69+ auto TestVL = [&](std::shared_ptr<VisitedList>& vl_ptr) {
70+ int count = 500 ;
71+ std::unordered_set<InnerIdType> ids;
72+ for (int i = 0 ; i < count; ++i) {
73+ auto id = random () % vl_size;
74+ ids.insert (id);
75+ vl_ptr->Set (id);
76+ }
77+ for (auto & id : ids) {
78+ REQUIRE (vl_ptr->Get (id) == true );
79+ }
80+
81+ for (InnerIdType i = 0 ; i < vl_size; ++i) {
82+ if (ids.count (i) == 0 ) {
83+ REQUIRE (vl_ptr->Get (i) == false );
84+ }
85+ }
86+ };
87+
88+ SECTION (" test basic" ) {
89+ std::vector<std::shared_ptr<VisitedList>> lists;
90+ REQUIRE (pool->GetSize () == init_size);
91+ lists.reserve (init_size * 2 );
92+ for (auto i = 0 ; i < init_size * 2 ; ++i) {
93+ lists.emplace_back (pool->GetOne ());
94+ }
95+ REQUIRE (pool->GetSize () == 0 );
96+ for (auto & ptr : lists) {
97+ pool->ReleaseOne (ptr);
98+ }
99+ REQUIRE (pool->GetSize () == init_size * 2 );
100+
101+ auto ptr = pool->GetOne ();
102+ REQUIRE (pool->GetSize () == init_size * 2 - 1 );
103+ TestVL (ptr);
104+ }
105+
106+ SECTION (" test concurrency" ) {
107+ auto func = [&]() {
108+ int count = 10 ;
109+ int max_operators = 20 ;
110+ std::vector<std::shared_ptr<VisitedList>> results;
111+ for (int i = 0 ; i < count; ++i) {
112+ auto opt = random () % max_operators + 1 ;
113+ for (auto j = 0 ; j < opt; ++j) {
114+ results.emplace_back (pool->GetOne ());
115+ }
116+ auto test = results[random () % opt];
117+ TestVL (test);
118+ for (auto & result : results) {
119+ pool->ReleaseOne (result);
120+ }
121+ results.clear ();
122+ }
123+ };
124+ std::vector<std::shared_ptr<std::thread>> ths;
125+ auto thread_count = 2 ;
126+ for (auto i = 0 ; i < thread_count; ++i) {
127+ ths.emplace_back ((std::make_shared<std::thread>(func)));
128+ }
129+ for (auto & thread : ths) {
130+ thread->join ();
131+ }
132+ }
133+ }
0 commit comments