Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
dynmap_example.C
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
111#include <iostream>
112#include <iomanip>
113#include <string>
114#include <vector>
115#include <chrono>
116#include <random>
117#include <tpl_dynMapTree.H>
118#include <tclap/CmdLine.h>
119
120using namespace std;
121using namespace Aleph;
122
127{
128 cout << "\n" << string(60, '=') << endl;
129 cout << "DynMapTree: Basic Operations" << endl;
130 cout << string(60, '=') << endl;
131
132 // Default uses AVL tree
134
135 cout << "\n--- Insertion ---" << endl;
136
137 // Different ways to insert
138 ages.insert("Alice", 30);
139 ages.insert("Bob", 25);
140 ages["Charlie"] = 35; // Creates if not exists
141 ages["Diana"] = 28;
142 ages.insert(make_pair("Eve", 42));
143
144 cout << "Inserted 5 entries" << endl;
145 cout << "Size: " << ages.size() << endl;
146
147 cout << "\n--- Access ---" << endl;
148
149 // Direct access (inserts default value if not found)
150 cout << "Alice's age: " << ages["Alice"] << endl;
151 cout << "Bob's age: " << ages.find("Bob") << endl;
152
153 // Safe access with search
154 auto* result = ages.search("Charlie");
155 if (result != nullptr)
156 cout << "Charlie found: " << result->second << endl;
157
158 result = ages.search("Unknown");
159 cout << "Unknown found: " << (result ? "yes" : "no") << endl;
160
161 cout << "\n--- Modification ---" << endl;
162
163 ages["Alice"] = 31; // Update existing
164 cout << "Updated Alice's age to " << ages["Alice"] << endl;
165
166 cout << "\n--- Iteration (sorted by key) ---" << endl;
167
168 for (auto it = ages.get_it(); it.has_curr(); it.next())
169 {
170 auto& pair = it.get_curr();
171 cout << " " << pair.first << " -> " << pair.second << endl;
172 }
173
174 cout << "\n--- Removal ---" << endl;
175
176 ages.remove("Bob");
177 cout << "Removed Bob, new size: " << ages.size() << endl;
178
179 cout << "\n--- Contains check ---" << endl;
180 cout << "Has Alice: " << (ages.has("Alice") ? "yes" : "no") << endl;
181 cout << "Has Bob: " << (ages.has("Bob") ? "yes" : "no") << endl;
182}
183
188{
189 cout << "\n" << string(60, '=') << endl;
190 cout << "Different Tree Backend Implementations" << endl;
191 cout << string(60, '=') << endl;
192
193 // AVL Tree (default)
195 avl_map[1] = "one";
196 avl_map[2] = "two";
197 avl_map[3] = "three";
198 cout << "\n1. Avl_Tree (strictly balanced):" << endl;
199 cout << " Height guarantee: <= 1.44 * log2(n)" << endl;
200 cout << " Size: " << avl_map.size() << endl;
201
202 // Red-Black Tree
204 rb_map[1] = "one";
205 rb_map[2] = "two";
206 rb_map[3] = "three";
207 cout << "\n2. Rb_Tree (red-black):" << endl;
208 cout << " Height guarantee: <= 2 * log2(n)" << endl;
209 cout << " Size: " << rb_map.size() << endl;
210
211 // Splay Tree
213 splay_map[1] = "one";
214 splay_map[2] = "two";
215 splay_map[3] = "three";
216 cout << "\n3. Splay_Tree (self-adjusting):" << endl;
217 cout << " Amortized O(log n), good for locality" << endl;
218 cout << " Size: " << splay_map.size() << endl;
219
220 // Treap
222 treap_map[1] = "one";
223 treap_map[2] = "two";
224 treap_map[3] = "three";
225 cout << "\n4. Treap (tree + heap):" << endl;
226 cout << " Expected O(log n), randomized" << endl;
227 cout << " Size: " << treap_map.size() << endl;
228
229 // Rand Tree
231 rand_map[1] = "one";
232 rand_map[2] = "two";
233 rand_map[3] = "three";
234 cout << "\n5. Rand_Tree (randomized):" << endl;
235 cout << " Expected O(log n), randomized" << endl;
236 cout << " Size: " << rand_map.size() << endl;
237
238 cout << "\nAll backends provide the same interface!" << endl;
239}
240
245{
246 cout << "\n" << string(60, '=') << endl;
247 cout << "Practical Example: Word Frequency Counter" << endl;
248 cout << string(60, '=') << endl;
249
251
252 // Sample text
253 vector<string> words = {
254 "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog",
255 "the", "fox", "is", "quick", "and", "the", "dog", "is", "lazy",
256 "quick", "foxes", "are", "brown", "lazy", "dogs", "are", "cute"
257 };
258
259 cout << "\nProcessing " << words.size() << " words..." << endl;
260
261 for (const auto& word : words)
262 {
263 if (freq.has(word))
264 freq[word]++;
265 else
266 freq[word] = 1;
267 }
268
269 cout << "\nWord frequencies (alphabetically sorted):" << endl;
270 for (auto it = freq.get_it(); it.has_curr(); it.next())
271 {
272 auto& p = it.get_curr();
273 cout << " " << setw(8) << p.first << ": " << p.second << endl;
274 }
275
276 cout << "\nUnique words: " << freq.size() << endl;
277}
278
283{
284 cout << "\n" << string(60, '=') << endl;
285 cout << "Practical Example: Configuration Store" << endl;
286 cout << string(60, '=') << endl;
287
288 // Using string keys for configuration
290
291 // Load configuration
292 config["app.name"] = "MyApplication";
293 config["app.version"] = "1.0.0";
294 config["database.host"] = "localhost";
295 config["database.port"] = "5432";
296 config["database.name"] = "mydb";
297 config["logging.level"] = "INFO";
298 config["logging.file"] = "/var/log/app.log";
299 config["cache.enabled"] = "true";
300 config["cache.ttl"] = "3600";
301
302 cout << "\nAll configuration (sorted by key):" << endl;
303 for (auto it = config.get_it(); it.has_curr(); it.next())
304 {
305 auto& p = it.get_curr();
306 cout << " " << p.first << " = " << p.second << endl;
307 }
308
309 // Access specific sections
310 cout << "\n--- Accessing Specific Values ---" << endl;
311 cout << "App name: " << config["app.name"] << endl;
312 cout << "DB host: " << config["database.host"] << endl;
313
314 // Check for optional config
315 auto* log_file = config.search("logging.file");
316 if (log_file)
317 cout << "Log file: " << log_file->second << endl;
318
319 // Default value pattern
320 auto* optional = config.search("optional.feature");
321 string value = optional ? optional->second : "default_value";
322 cout << "Optional feature: " << value << endl;
323}
324
329{
330 cout << "\n" << string(60, '=') << endl;
331 cout << "Functional Programming Features" << endl;
332 cout << string(60, '=') << endl;
333
335 scores["Alice"] = 85;
336 scores["Bob"] = 92;
337 scores["Charlie"] = 78;
338 scores["Diana"] = 95;
339 scores["Eve"] = 88;
340
341 cout << "\nOriginal scores:" << endl;
342 scores.for_each([](auto& p) {
343 cout << " " << p.first << ": " << p.second << endl;
344 });
345
346 // Count elements satisfying condition
347 size_t high_scorers = 0;
348 scores.for_each([&high_scorers](const auto& p) {
349 if (p.second >= 90) ++high_scorers;
350 });
351 cout << "\nStudents with score >= 90: " << high_scorers << endl;
352
353 // Check if all satisfy condition
354 bool all_passed = scores.all([](const auto& p) {
355 return p.second >= 60;
356 });
357 cout << "All passed (>= 60): " << (all_passed ? "yes" : "no") << endl;
358
359 // Check if any satisfies condition
360 bool any_perfect = scores.exists([](const auto& p) {
361 return p.second == 100;
362 });
363 cout << "Any perfect score: " << (any_perfect ? "yes" : "no") << endl;
364
365 // Filter (create new map with qualifying entries)
366 cout << "\nHigh scorers (>= 90):" << endl;
367 auto high = scores.filter([](const auto& p) { return p.second >= 90; });
368 high.for_each([](auto& p) {
369 cout << " " << p.first << ": " << p.second << endl;
370 });
371
372 // Fold (reduce to single value)
373 int total = scores.foldl<int>(0, [](int acc, const auto& p) {
374 return acc + p.second;
375 });
376 cout << "\nTotal score: " << total << endl;
377 cout << "Average: " << (total / (double)scores.size()) << endl;
378}
379
384{
385 cout << "\n" << string(60, '=') << endl;
386 cout << "Performance Comparison (n = " << n << ")" << endl;
387 cout << string(60, '=') << endl;
388
389 random_device rd;
390 mt19937 gen(rd());
392
393 vector<int> keys(n);
394 for (int i = 0; i < n; ++i)
395 keys[i] = dis(gen);
396
397 auto benchmark = [&](auto& map, const string& name) {
398 auto start = chrono::high_resolution_clock::now();
399
400 // Insert
401 for (int k : keys)
402 map[k] = k * 2;
403
404 auto mid = chrono::high_resolution_clock::now();
405
406 // Lookup
407 volatile int dummy = 0;
408 for (int k : keys)
409 {
410 auto* p = map.search(k);
411 if (p) dummy = p->second;
412 }
413
414 auto end = chrono::high_resolution_clock::now();
415
416 auto insert_us = chrono::duration_cast<chrono::microseconds>(mid - start).count();
417 auto lookup_us = chrono::duration_cast<chrono::microseconds>(end - mid).count();
418
419 cout << setw(12) << name << ": "
420 << "Insert " << setw(6) << insert_us << " us, "
421 << "Lookup " << setw(6) << lookup_us << " us" << endl;
422
423 (void)dummy; // Suppress warning
424 };
425
426 {
428 benchmark(map, "Avl_Tree");
429 }
430
431 {
433 benchmark(map, "Rb_Tree");
434 }
435
436 {
438 benchmark(map, "Splay_Tree");
439 }
440
441 {
443 benchmark(map, "Treap");
444 }
445
446 {
448 benchmark(map, "Rand_Tree");
449 }
450
451 cout << "\n--- Analysis ---" << endl;
452 cout << "All backends are O(log n) average case" << endl;
453 cout << "AVL: Most balanced, slightly slower updates" << endl;
454 cout << "Red-Black: Good balance, faster updates" << endl;
455 cout << "Splay: Best for repeated access patterns" << endl;
456 cout << "Treap/Rand: Good average, simple implementation" << endl;
457}
458
459int main(int argc, char* argv[])
460{
461 try
462 {
463 TCLAP::CmdLine cmd("DynMapTree Example", ' ', "1.0");
464
465 TCLAP::ValueArg<int> nArg("n", "count",
466 "Number of elements for performance test", false, 10000, "int");
467 TCLAP::SwitchArg basicArg("b", "basic",
468 "Show basic operations", false);
469 TCLAP::SwitchArg backendsArg("t", "trees",
470 "Show different tree backends", false);
471 TCLAP::SwitchArg freqArg("w", "words",
472 "Show word frequency example", false);
473 TCLAP::SwitchArg configArg("c", "config",
474 "Show configuration store example", false);
475 TCLAP::SwitchArg funcArg("f", "functional",
476 "Show functional programming features", false);
477 TCLAP::SwitchArg perfArg("p", "performance",
478 "Run performance comparison", false);
479 TCLAP::SwitchArg allArg("a", "all",
480 "Run all demos", false);
481
482 cmd.add(nArg);
483 cmd.add(basicArg);
484 cmd.add(backendsArg);
485 cmd.add(freqArg);
486 cmd.add(configArg);
487 cmd.add(funcArg);
488 cmd.add(perfArg);
489 cmd.add(allArg);
490
491 cmd.parse(argc, argv);
492
493 int n = nArg.getValue();
494 bool runBasic = basicArg.getValue();
495 bool runBackends = backendsArg.getValue();
496 bool runFreq = freqArg.getValue();
497 bool runConfig = configArg.getValue();
498 bool runFunc = funcArg.getValue();
499 bool runPerf = perfArg.getValue();
500 bool runAll = allArg.getValue();
501
504 runAll = true;
505
506 cout << "=== DynMapTree: Key-Value Mappings ===" << endl;
507
508 if (runAll or runBasic)
510
513
514 if (runAll or runFreq)
516
517 if (runAll or runConfig)
519
520 if (runAll or runFunc)
522
523 if (runAll or runPerf)
525
526 cout << "\n=== Summary ===" << endl;
527 cout << "DynMapTree provides ordered key-value storage" << endl;
528 cout << "Choose backend based on access patterns:" << endl;
529 cout << " - AVL for predictable performance" << endl;
530 cout << " - Splay for locality-heavy workloads" << endl;
531 cout << " - Treap for simplicity with good average case" << endl;
532
533 return 0;
534 }
535 catch (TCLAP::ArgException& e)
536 {
537 cerr << "Error: " << e.error() << " for arg " << e.argId() << endl;
538 return 1;
539 }
540}
541
int main()
void demo_performance()
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T remove()
Remove the first item of the list.
Definition htlist.H:1611
Generic key-value map implemented on top of a binary search tree.
Pair * search(const Key &key) const noexcept
Collect all keys.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1034
Aleph::DynList< T > filter(Operation &operation) const
Filter the elements of a container according to a matching criteria.
Definition ah-dry.H:1135
bool exists(Operation &op) const
Test for existence in the container of an element satisfying a criteria.
Definition ah-dry.H:846
bool all(Operation &operation) const
Check if all the elements of container satisfy a condition.
Definition ah-dry.H:816
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
void demo_config_store()
Practical example: Configuration store.
void demo_basic_operations()
Demonstrate basic map operations.
void demo_tree_backends()
Demonstrate different tree backends.
void demo_functional()
Functional programming with maps.
void demo_word_frequency()
Practical example: Word frequency counter.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
Definition ahPair.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Dynamic key-value map based on balanced binary search trees.