Skip to content

Commit a8e0cc0

Browse files
committed
Add advanced demo
1 parent fd57fb6 commit a8e0cc0

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

demo_advanced.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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

Comments
 (0)