1+ #include " ConcurrentHashMap.h"
2+ #include < iostream>
3+ #include < string>
4+ #include < thread>
5+ #include < vector>
6+ #include < atomic>
7+ #include < mutex>
8+
9+ std::mutex coutMutex;
10+
11+ void stressTest (ConcurrentHashMap<std::string, int > &map, int threadId)
12+ {
13+ // Concurrent insertions/updates
14+ for (int i = 0 ; i < 10 ; ++i)
15+ {
16+ std::string key = " key-" + std::to_string (threadId) + " -" + std::to_string (i);
17+ map.insert (key, i);
18+ // Update shared key to test write contention
19+ map.insert (" shared-key" , threadId * 100 + i);
20+ }
21+
22+ // Concurrent reads
23+ for (int i = 0 ; i < 5 ; ++i)
24+ {
25+ std::string key = " key-" + std::to_string (threadId) + " -" + std::to_string (i);
26+
27+ if (auto val = map.get (key))
28+ {
29+ std::lock_guard<std::mutex> coutLock (coutMutex);
30+ std::cout << " Thread " << threadId << " found " << key << " = " << *val << " \n " ;
31+ }
32+ }
33+ }
34+
35+ int main ()
36+ {
37+ ConcurrentHashMap<std::string, int > concurrentMap;
38+ std::atomic<bool > startFlag{false };
39+ std::mutex coutMutex;
40+ // === Basic Functionality Test ===
41+ std::cout << " === Basic Operations ===\n " ;
42+ concurrentMap.insert (" apple" , 10 );
43+ concurrentMap.insert (" banana" , 20 );
44+ // Test duplicate insertion
45+ concurrentMap.insert (" apple" , 15 );
46+
47+ if (auto val = concurrentMap.get (" apple" ))
48+ {
49+ std::cout << " Apple: " << *val << " (should be 15)\n " ;
50+ }
51+
52+ // Test non-existent key
53+ if (!concurrentMap.get (" mango" ))
54+ {
55+ std::cout << " Mango correctly not found\n " ;
56+ }
57+
58+ concurrentMap.print ();
59+ // === Concurrent Stress Test ===
60+ std::cout << " \n === Starting Concurrent Stress Test ===\n " ;
61+ constexpr int NUM_THREADS = 8 ;
62+ std::vector<std::thread> threads;
63+
64+ // Create worker threads
65+ for (int i = 0 ; i < NUM_THREADS; ++i)
66+ {
67+ threads.emplace_back ([ &, i]()
68+ {
69+ // Wait for all threads to be ready
70+ while (!startFlag)
71+ {
72+ std::this_thread::yield ();
73+ }
74+
75+ stressTest (concurrentMap, i);
76+ });
77+ }
78+
79+ // Start all threads simultaneously
80+ startFlag = true ;
81+ // Let threads work for 500ms
82+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
83+ // Concurrent modifications while threads are running
84+ concurrentMap.remove (" apple" );
85+ concurrentMap.insert (" shared-key" , -1 ); // Last writer should win
86+
87+ // Wait for all threads to finish
88+ for (auto &t : threads)
89+ {
90+ t.join ();
91+ }
92+
93+ // === Post-Test Verification ===
94+ std::cout << " \n === Final Verification ===\n " ;
95+
96+ // Verify shared key (last writer should be main thread)
97+ if (auto val = concurrentMap.get (" shared-key" ))
98+ {
99+ std::cout << " Shared key value: " << *val << " (should be -1)\n " ;
100+ }
101+
102+ // Verify removed key
103+ if (!concurrentMap.get (" apple" ))
104+ {
105+ std::cout << " Apple correctly removed\n " ;
106+ }
107+
108+ // Verify thread-specific keys
109+ bool allFound = true ;
110+
111+ for (int t = 0 ; t < NUM_THREADS; ++t)
112+ {
113+ for (int i = 0 ; i < 10 ; ++i)
114+ {
115+ std::string key = " key-" + std::to_string (t) + " -" + std::to_string (i);
116+
117+ if (!concurrentMap.get (key))
118+ {
119+ allFound = false ;
120+ std::cout << " Missing: " << key << " \n " ;
121+ }
122+ }
123+ }
124+
125+ if (allFound)
126+ {
127+ std::cout << " All thread-specific keys preserved\n " ;
128+ }
129+
130+ // Final print
131+ std::cout << " \n === Final Map State ===\n " ;
132+ concurrentMap.print ();
133+ return 0 ;
134+ }
0 commit comments