Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
pointer_table.H
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
80# ifndef POINTER_TABLE_H
81# define POINTER_TABLE_H
82
83# include <tpl_dynArray.H>
84# include <ah-errors.H>
85# include <iostream>
86
111{
112public:
118 static constexpr long Null_Index = -1;
119
120private:
126
138 {
139 if (free_table.size() == 0)
140 return Null_Index;
141
142 long ret_val = free_table[free_table.size() - 1];
143
145 assert(pointer_table[ret_val] == nullptr);
146
148
149 return ret_val;
150 }
151
166 {
167 assert(i >= 0 and i < heap_index);
168
169 pointer_table[i] = nullptr;
171 }
172
185 {
186 if (free_table.size() == 0)
187 return;
188
189 // Remove all indices >= new_heap_index from free_table
190 // We need to compact the free_table, keeping only valid indices
191 long write_pos = 0;
193 {
195 {
196 if (write_pos != read_pos)
198 ++write_pos;
199 }
200 }
201
202 if (write_pos < static_cast<long>(free_table.size()))
204 }
205
217 bool is_valid_index(long i) const noexcept
218 {
219 return i >= 0 and i < heap_index;
220 }
221
233 bool pointer_matches_with_index(long i, const void *ptr) const noexcept
234 {
236 return pointer_table(i) == ptr;
237 }
238
252 bool invariant() const
253 {
254 // Basic count check
255 if (num_pointers < 0)
256 return false;
257
258 // When empty
259 if (num_pointers == 0)
260 return heap_index == 0 and free_table.size() == 0;
261
262 // Non-empty: top of heap must be non-null
263 if (heap_index <= 0 or pointer_table(heap_index - 1) == nullptr)
264 return false;
265
266 // Verify count consistency
267 if (num_pointers != heap_index - static_cast<long>(free_table.size()))
268 return false;
269
270 // Verify all free_table indices are valid and point to nullptr
271 for (size_t j = 0; j < free_table.size(); ++j)
272 {
273 long idx = free_table(j);
275 return false;
276 if (pointer_table(idx) != nullptr)
277 return false;
278 }
279
280 return true;
281 }
282
283public:
306 {
307 // DynArray initializes to default (nullptr for pointers)
308 // No explicit initialization loop needed
309 }
310
323 long size() const noexcept { return pointer_table.size(); }
324
333
344 long frees() const noexcept { return free_table.size(); }
345
357
369
377 bool is_empty() const noexcept { return num_pointers == 0; }
378
405 long insert_pointer(void *ptr)
406 {
407 assert(invariant());
408
410
411 if (ret_val == Null_Index)
413
414 pointer_table[ret_val] = ptr;
415 ++num_pointers;
416
417 assert(invariant());
418
419 return ret_val;
420 }
421
449 void remove_pointer(long i)
450 {
451 assert(invariant());
452
453 if (not is_valid_index(i))
454 ah_range_error_if(true) << "index " << i << " out of range [0, "
455 << heap_index << ")";
456
457 if (pointer_table[i] == nullptr)
458 ah_domain_error_if(true) << "index " << i << " is not busy (already free)";
459
460 if (i == heap_index - 1)
461 {
462 // Removing from top of heap - contract the heap
463 pointer_table[heap_index - 1] = nullptr;
464
465 // Find new heap top (first non-null from the top)
466 while (heap_index > 0 and pointer_table[heap_index - 1] == nullptr)
467 --heap_index;
468
469 // CRITICAL FIX: Remove invalid indices from free_table
471 }
472 else
474
475 // Shrink pointer_table if below threshold
476 if (heap_index <= threshold_size and pointer_table.size() > static_cast<size_t>(threshold_size))
478
479 --num_pointers;
480
481 assert(invariant());
482 }
483
499 void * get_pointer(long i) const
500 {
501 if (not is_valid_index(i))
502 ah_range_error_if(true) << "index " << i << " out of range [0, "
503 << heap_index << ")";
504 return pointer_table(i);
505 }
506
539 void * verify_pointer(long i, void *ptr) const
540 {
541 if (not is_valid_index(i))
542 ah_range_error_if(true) << "index " << i << " out of range [0, "
543 << heap_index << ")";
544
546 ah_domain_error_if(true) << "pointer at index " << i
547 << " does not match expected value";
548
549 return ptr;
550 }
551
572 void clear()
573 {
575 free_table.cut(0);
576 num_pointers = 0;
577 heap_index = 0;
578
579 assert(invariant());
580 }
581
582# ifdef DEBUG
598 void print_parameters() const
599 {
600 std::cout << "Number of pointers = " << num_pointers << '\n'
601 << "Pointer table size = " << pointer_table.size() << '\n'
602 << "Free table size = " << free_table.size() << '\n'
603 << "Threshold = " << threshold_size << '\n'
604 << "Heap index = " << heap_index << '\n';
605 if (heap_index > 0)
606 std::cout << "pointer_table[" << heap_index - 1 << "]= "
607 << pointer_table(heap_index - 1) << '\n';
608 }
609
614 bool check_invariant() const { return invariant(); }
615# endif
616};
617
618
619# endif // POINTER_TABLE_H
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:522
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
void print_parameters()
Definition btreepic.C:2198
void cut(const size_t new_dim=0)
Cut the array to a new dimension; that is, it reduces the dimension of array and frees the remaining ...
size_t size() const noexcept
Return the current dimension of array.
A dynamic table for managing void pointers with index recycling.
void * verify_pointer(long i, void *ptr) const
Verifies that a pointer matches the one stored at an index.
long frees() const noexcept
Returns the number of recyclable indices.
void remove_pointer(long i)
Removes the pointer at the given index.
long num_pointers
Count of currently stored pointers.
bool invariant() const
Validates the internal consistency of the data structure.
long get_threshold() const noexcept
Returns the threshold size.
long busies() const noexcept
Returns the number of pointers currently stored.
bool is_valid_index(long i) const noexcept
Checks if an index is within valid bounds.
long threshold_size
Minimum size to maintain (prevents excessive shrinking)
long allocate_above_heap()
Allocates an index from the free table.
bool is_empty() const noexcept
Checks if the table is empty.
long get_heap_index() const noexcept
Returns the current heap index (high water mark).
long size() const noexcept
Returns the current capacity of the pointer table.
static constexpr long Null_Index
Sentinel value indicating an invalid or null index.
DynArray< void * > pointer_table
Array mapping indices to pointers.
long insert_pointer(void *ptr)
Inserts a pointer and returns its assigned index.
DynArray< long > free_table
Stack of available indices for reuse.
bool pointer_matches_with_index(long i, const void *ptr) const noexcept
Checks if a pointer matches the one stored at an index.
void insert_in_free_table(long i)
Adds an index to the free table for future reuse.
Pointer_Table(size_t initial_size=0)
Constructs a Pointer_Table with optional initial capacity.
long heap_index
Next available index at the heap top.
void clear()
Clears all pointers from the table.
void * get_pointer(long i) const
Retrieves the pointer at the given index.
void cleanup_free_table(long new_heap_index)
Removes indices from free_table that are >= new_heap_index.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Lazy and scalable dynamic array implementation.