Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
map_arena_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
167#include <iostream>
168#include <iomanip>
169#include <string>
170#include <cstring>
171#include <filesystem>
172
173#include <ah-map-arena.H>
174
175using namespace std;
176using namespace Aleph;
177namespace fs = std::filesystem;
178
179// ============================================================================
180// Helper functions
181// ============================================================================
182
183void print_header(const string& title)
184{
185 cout << "\n";
186 cout << "+" << string(70, '-') << "+" << endl;
187 cout << "| " << left << setw(68) << title << " |" << endl;
188 cout << "+" << string(70, '-') << "+" << endl;
189}
190
191void print_subheader(const string& subtitle)
192{
193 cout << "\n " << subtitle << endl;
194 cout << " " << string(subtitle.length(), '-') << endl;
195}
196
197void print_arena_status(const MapArena& arena, const string& label)
198{
199 cout << " " << label << ":" << endl;
200 cout << " Size (committed): " << arena.size() << " bytes" << endl;
201 cout << " Capacity (mapped): " << arena.capacity() << " bytes" << endl;
202 cout << " Available: " << arena.avail() << " bytes" << endl;
203 cout << " Is empty: " << (arena.empty() ? "yes" : "no") << endl;
204}
205
206// ============================================================================
207// Example 1: Basic Arena Operations
208// ============================================================================
209
211{
212 print_header("Example 1: Basic Arena Operations");
213
214 const string arena_file = "/tmp/aleph_arena_basic.dat";
215
216 // Always start fresh
217 fs::remove(arena_file);
218
219 MapArena arena(arena_file);
220
221 print_subheader("Initial state");
222 print_arena_status(arena, "New arena");
223
224 print_subheader("Reserve and commit memory");
225
226 // Reserve space for a string
227 const char* message = "Hola desde Colombia!";
228 size_t msg_len = strlen(message) + 1;
229
230 char* ptr = arena.reserve(msg_len);
231 if (ptr) {
232 memcpy(ptr, message, msg_len);
233 arena.commit(msg_len);
234 cout << " Stored: \"" << message << "\" (" << msg_len << " bytes)" << endl;
235 }
236
237 // Store more data
238 const char* cities[] = {"Bogota", "Medellin", "Cali", "Barranquilla"};
239 for (const char* city : cities) {
240 size_t len = strlen(city) + 1;
241 char* p = arena.reserve(len);
242 if (p) {
243 memcpy(p, city, len);
244 arena.commit(len);
245 }
246 }
247
248 print_arena_status(arena, "After storing data");
249
250 print_subheader("Reading stored strings");
251
252 cout << " Stored strings:" << endl;
253 char* read_ptr = arena.begin();
254 while (read_ptr < arena.end()) {
255 cout << " -> \"" << read_ptr << "\"" << endl;
256 read_ptr += strlen(read_ptr) + 1;
257 }
258
259 // Sync to ensure persistence
260 arena.sync();
261 cout << "\n Data synced to disk" << endl;
262
263 // Cleanup
264 fs::remove(arena_file);
265}
266
267// ============================================================================
268// Example 2: Storing Structured Data
269// ============================================================================
270
272 char name[32];
273 int population; // thousands
274 double area; // km²
275 int altitude; // meters
276};
277
279{
280 print_header("Example 2: Storing Structured Data");
281
282 const string arena_file = "/tmp/aleph_arena_struct.dat";
283 fs::remove(arena_file);
284
285 MapArena arena(arena_file);
286
287 print_subheader("Store city records");
288
289 // Colombian city data
290 CityRecord cities[] = {
291 {"Bogota", 8281, 1775.98, 2640},
292 {"Medellin", 2569, 380.64, 1495},
293 {"Cali", 2228, 564.33, 1018},
294 {"Barranquilla", 1274, 154.00, 18},
295 {"Cartagena", 1047, 609.10, 2}
296 };
297
298 size_t count = sizeof(cities) / sizeof(cities[0]);
299
300 // Store the count first
301 char* ptr = arena.reserve(sizeof(size_t));
302 memcpy(ptr, &count, sizeof(size_t));
303 arena.commit(sizeof(size_t));
304
305 // Store each record
306 for (const auto& city : cities) {
307 ptr = arena.reserve(sizeof(CityRecord));
308 memcpy(ptr, &city, sizeof(CityRecord));
309 arena.commit(sizeof(CityRecord));
310 }
311
312 print_arena_status(arena, "After storing records");
313
314 print_subheader("Read and display records");
315
316 // Read count
317 char* read_ptr = arena.begin();
318 size_t stored_count;
319 memcpy(&stored_count, read_ptr, sizeof(size_t));
320 read_ptr += sizeof(size_t);
321
322 cout << "\n Retrieved " << stored_count << " city records:" << endl;
323 cout << " " << string(60, '-') << endl;
324 cout << " " << left << setw(15) << "City"
325 << right << setw(10) << "Pop (k)"
326 << setw(12) << "Area (km2)"
327 << setw(12) << "Alt (m)" << endl;
328 cout << " " << string(60, '-') << endl;
329
330 for (size_t i = 0; i < stored_count; ++i) {
332 memcpy(&rec, read_ptr, sizeof(CityRecord));
333 read_ptr += sizeof(CityRecord);
334
335 cout << " " << left << setw(15) << rec.name
336 << right << setw(10) << rec.population
337 << setw(12) << fixed << setprecision(2) << rec.area
338 << setw(12) << rec.altitude << endl;
339 }
340
341 fs::remove(arena_file);
342}
343
344// ============================================================================
345// Example 3: Arena Growth
346// ============================================================================
347
349{
350 print_header("Example 3: Arena Growth (Automatic Remapping)");
351
352 const string arena_file = "/tmp/aleph_arena_growth.dat";
353 fs::remove(arena_file);
354
355 MapArena arena(arena_file);
356
357 cout << "\n Initial capacity: " << arena.capacity() << " bytes" << endl;
358 cout << " (Initial region size: " << MapArena::initial_rgn_size << " bytes)" << endl;
359
360 print_subheader("Allocate beyond initial capacity");
361
362 // Keep track of capacity changes
363 size_t prev_capacity = arena.capacity();
364 int growth_count = 0;
365
366 // Allocate chunks until we've grown several times
367 const size_t chunk_size = 1000;
368
369 for (int i = 0; i < 20; ++i) {
370 char* ptr = arena.reserve(chunk_size);
371 if (ptr) {
372 // Fill with pattern
373 memset(ptr, 'A' + (i % 26), chunk_size);
374 arena.commit(chunk_size);
375
376 if (arena.capacity() > prev_capacity) {
377 growth_count++;
378 cout << " Growth #" << growth_count
379 << ": " << prev_capacity << " -> " << arena.capacity()
380 << " bytes (after " << arena.size() << " allocated)" << endl;
381 prev_capacity = arena.capacity();
382 }
383 }
384 }
385
386 print_subheader("Final state");
387 print_arena_status(arena, "Arena after growth");
388
389 // Verify data integrity
390 cout << "\n Verifying data integrity..." << endl;
391 char* ptr = arena.begin();
392 bool valid = true;
393 for (int i = 0; i < 20 && valid; ++i) {
394 char expected = 'A' + (i % 26);
395 for (size_t j = 0; j < chunk_size && valid; ++j) {
396 if (ptr[j] != expected) {
397 valid = false;
398 cout << " ERROR: Data corruption at chunk " << i << endl;
399 }
400 }
401 ptr += chunk_size;
402 }
403 if (valid)
404 cout << " All data verified successfully!" << endl;
405
406 fs::remove(arena_file);
407}
408
409// ============================================================================
410// Example 4: Log Buffer Pattern
411// ============================================================================
412
414{
415 print_header("Example 4: Log Buffer Pattern");
416
417 const string arena_file = "/tmp/aleph_arena_log.dat";
418 fs::remove(arena_file);
419
420 MapArena arena(arena_file);
421
422 print_subheader("Write log entries");
423
424 // Simulate log entries with timestamps
425 const char* log_entries[] = {
426 "[2024-01-15 08:00:00] Sistema iniciado en Bogota",
427 "[2024-01-15 08:00:01] Conexion con servidor Medellin",
428 "[2024-01-15 08:00:02] Usuario: Juan Perez",
429 "[2024-01-15 08:00:05] Transaccion #1001: $150,000 COP",
430 "[2024-01-15 08:00:07] Sincronizacion con Cali",
431 "[2024-01-15 08:00:10] Backup iniciado",
432 "[2024-01-15 08:00:15] Backup completado",
433 "[2024-01-15 08:00:20] Alerta: Memoria al 75%"
434 };
435
436 size_t num_entries = sizeof(log_entries) / sizeof(log_entries[0]);
437
438 for (const char* entry : log_entries) {
439 size_t len = strlen(entry) + 1;
440 char* ptr = arena.reserve(len);
441 if (ptr) {
442 memcpy(ptr, entry, len);
443 arena.commit(len);
444 }
445 }
446
447 cout << " Written " << num_entries << " log entries" << endl;
448 print_arena_status(arena, "Log buffer");
449
450 print_subheader("Read log entries");
451
452 cout << "\n Log contents:" << endl;
453 cout << " " << string(55, '-') << endl;
454
455 char* ptr = arena.begin();
456 int count = 0;
457 while (ptr < arena.end()) {
458 cout << " " << ptr << endl;
459 ptr += strlen(ptr) + 1;
460 count++;
461 }
462
463 cout << " " << string(55, '-') << endl;
464 cout << " Total entries: " << count << endl;
465
466 fs::remove(arena_file);
467}
468
469// ============================================================================
470// Example 5: Move Semantics
471// ============================================================================
472
474{
475 print_header("Example 5: Move Semantics");
476
477 const string arena_file = "/tmp/aleph_arena_move.dat";
478 fs::remove(arena_file);
479
480 print_subheader("Create and populate arena");
481
483
484 const char* data = "Datos importantes de Colombia";
485 char* ptr = arena1.reserve(strlen(data) + 1);
486 memcpy(ptr, data, strlen(data) + 1);
487 arena1.commit(strlen(data) + 1);
488
489 cout << " arena1 size: " << arena1.size() << endl;
490 cout << " arena1 is_initialized: " << arena1.is_initialized() << endl;
491
492 print_subheader("Move construction");
493
494 MapArena arena2(std::move(arena1));
495
496 cout << " After move construction:" << endl;
497 cout << " arena1 is_initialized: " << arena1.is_initialized() << endl;
498 cout << " arena2 is_initialized: " << arena2.is_initialized() << endl;
499 cout << " arena2 size: " << arena2.size() << endl;
500 cout << " arena2 data: \"" << arena2.begin() << "\"" << endl;
501
502 print_subheader("Move assignment");
503
505 cout << " arena3 (before): is_initialized = " << arena3.is_initialized() << endl;
506
507 arena3 = std::move(arena2);
508
509 cout << " After move assignment:" << endl;
510 cout << " arena2 is_initialized: " << arena2.is_initialized() << endl;
511 cout << " arena3 is_initialized: " << arena3.is_initialized() << endl;
512 cout << " arena3 data: \"" << arena3.begin() << "\"" << endl;
513
514 fs::remove(arena_file);
515}
516
517// ============================================================================
518// Example 6: Memory Statistics
519// ============================================================================
520
522{
523 print_header("Example 6: Memory Statistics and Efficiency");
524
525 const string arena_file = "/tmp/aleph_arena_stats.dat";
526 fs::remove(arena_file);
527
528 MapArena arena(arena_file);
529
530 print_subheader("Arena efficiency analysis");
531
532 // Simulate various allocation sizes
533 int allocations[] = {10, 50, 100, 500, 1000, 2000};
534
535 cout << "\n Allocation pattern analysis:" << endl;
536 cout << " " << string(50, '-') << endl;
537 cout << " " << setw(10) << "Alloc Size"
538 << setw(12) << "Committed"
539 << setw(12) << "Capacity"
540 << setw(15) << "Utilization" << endl;
541 cout << " " << string(50, '-') << endl;
542
543 for (int size : allocations) {
544 char* ptr = arena.reserve(size);
545 if (ptr) {
546 memset(ptr, 'X', size);
547 arena.commit(size);
548
549 double utilization = 100.0 * arena.size() / arena.capacity();
550
551 cout << " " << setw(10) << size
552 << setw(12) << arena.size()
553 << setw(12) << arena.capacity()
554 << setw(14) << fixed << setprecision(1) << utilization << "%" << endl;
555 }
556 }
557
558 print_subheader("Debug output");
559 cout << arena << endl;
560
561 fs::remove(arena_file);
562}
563
564// ============================================================================
565// Main
566// ============================================================================
567
568int main()
569{
570 cout << "\n";
571 cout << "========================================================================" << endl;
572 cout << " ALEPH-W MAP ARENA EXAMPLE" << endl;
573 cout << " Memory-Mapped File Arena Allocator" << endl;
574 cout << "========================================================================" << endl;
575
582
583 cout << "\n";
584 cout << "========================================================================" << endl;
585 cout << " Example completed successfully!" << endl;
586 cout << "========================================================================" << endl;
587 cout << endl;
588
589 return 0;
590}
Memory-mapped file arena allocator.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Memory-mapped file arena allocator.
size_type size() const noexcept
Get the total committed (allocated) size.
size_type capacity() const noexcept
Get the current capacity (mapped region size).
void commit(const size_type sz) noexcept
Commit a previous reservation.
char * reserve(const size_type sz)
Reserve memory for allocation.
bool empty() const noexcept
Check if the arena is empty.
iterator end() noexcept
Get iterator past the last allocated byte.
static constexpr size_t initial_rgn_size
Initial region size in bytes (4 KB).
size_type avail() const noexcept
Get the available memory in the current mapping.
iterator begin() noexcept
Get iterator to the beginning of allocated memory.
void sync() noexcept
Ensure data is persisted to disk.
size_t length() const noexcept
Count the number of elements of a container.
Definition ah-dry.H:1385
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
void print_arena_status(const MapArena &arena, const string &label)
void demo_basic_operations()
void demo_structured_data()
void demo_arena_growth()
void print_subheader(const string &subtitle)
void demo_move_semantics()
void demo_memory_stats()
void demo_log_buffer()
int main()
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
void message(const char *file, int line, const char *format,...)
Print an informational message with file and line info.
Definition ahDefs.C:100
size_t size(Node *root) noexcept
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
STL namespace.
void print_header()