Skip to content

Nothrow: Substitutes for standard C++ containers and memory resources, with pluggable pointer storage policies#272

Open
MichaelSteffens17 wants to merge 41 commits into
eclipse-score:mainfrom
MichaelSteffens17:main
Open

Nothrow: Substitutes for standard C++ containers and memory resources, with pluggable pointer storage policies#272
MichaelSteffens17 wants to merge 41 commits into
eclipse-score:mainfrom
MichaelSteffens17:main

Conversation

@MichaelSteffens17

@MichaelSteffens17 MichaelSteffens17 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Part of #167

MichaelSteffens17 and others added 30 commits June 1, 2026 10:47
…r comparisons.

  1. Emplace — true in-place construction

   - Added a Node(parent, std::in_place_t, Args&&...) constructor and AllocateNode. Emplace to construct the value_type directly in allocated node memory
   - Emplace now allocates the node first, constructs in-place, then searches the tree; destroys the node if a duplicate key is found
   - Eliminates the intermediate stack temporary + move that the old implementation used

  2. clear() — no freed-pointer comparisons

   - Replaced the previous-tracking traversal (which compared freed addresses — UB per [basic.stc]/4) with a descend-to-leaf approach
   - Each iteration descends left/right until hitting a leaf, nulls the parent's link, then destroys the leaf and backs up to the parent
   - All pointer comparisons are against live objects only
…o container algorithm without UB. Add combined benchmark.
- Shared insert-position search (FindInsertPosition)
- Consolidated key comparison (CompareKey) used in insert/find
- Added specialized 2-arg Emplace(...) overloads to avoid pre-construct-and-destroy on duplicates
- RebalanceFrom(..., stop_on_stable_height) early-exit for insert flows
… final equality check, and reused that for insert-position search (removing extra compare/branch work). I also added a std::greater<int> regression test in score/shm/map_test.cpp.
…plus OrAbort variants), with std-like neighbor checks and fallback.

Sorted fast path via maintained leftmost_/rightmost_ and boundary-aware insertion checks, used in Create(range) and Clone() with rolling hint.
Udated score/shm/BENCHMARK.md with the full latest suite results from the current codebase.
…hrow with pointer box renames.

Move score/shm/ to score/nothrow/ to reflect that these containers and
memory resources are nothrow std-container substitutes, not
shared-memory-specific.

Rename pointer storage types to reflect their role as encoding boxes:
- OffsetPtr -> OffsetBox
- NullableOffsetPtr -> NullableOffsetBox
- DirectPtr -> RawBox (serves as both Ptr and NullablePtr)
- ShmPointerPolicy -> OffsetBoxPolicy
- ShmDirectPointerPolicy -> RawBoxPolicy
- offset_ptr.h -> pointer_box.h

Update all include paths, header guards, namespaces, BUILD targets,
documentation, and example code.

Add reverse iterators (rbegin/rend/crbegin/crend), ordered lookup
methods (count, lower_bound, upper_bound, equal_range), iterator-based
erase overloads (const_iterator and range), and equality operators.

Fix GetOrInsertDefault to use Emplace instead of constructing an
intermediate value_type, avoiding an unnecessary key copy.

All new members follow the naming conventions from score/shm/README.md:
non-allocating operations use standard snake_case spelling.
Updated the benchmark analysis section to clarify the overhead cause and corrected terminology from 'OffsetBox' to 'OffsetPtr'.

Signed-off-by: MichaelSteffens17 <michael.steffens@vector.com>
…ffsetBox.

Signed-off-by: MichaelSteffens17 <michael.steffens@vector.com>
Signed-off-by: MichaelSteffens17 <michael.steffens@vector.com>
Signed-off-by: MichaelSteffens17 <michael.steffens@vector.com>
Signed-off-by: MichaelSteffens17 <michael.steffens@vector.com>
…irly to NoBoundsCheck timings. Add boost::interprocess container and completed score::memory::shared::Map benchmarks.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

Comment thread map.tar.gz Outdated
@MichaelSteffens17

MichaelSteffens17 commented Jun 17, 2026 via email

Copy link
Copy Markdown
Contributor Author

Provision a Map's node storage directly from an external buffer, bypassing
the templated allocator the same way Vector::CreateWithBuffer does. The map
manages an internal free-list pool over the buffer: nodes are carved on
insert and recycled on erase, bounding the map to a fixed node count.

All pool state is position-independent -- the cell base is stored through the
pointer policy (offset-encoded by default) and the free-list head/capacity are
indices -- so a buffer-backed map with OffsetSlotPolicy is relocatable and can
be both read and mutated across processes mapping the same segment, without the
vtable, raw buffer pointer, and process-local upstream singleton that a
polymorphic MemoryResource would drag along.

- map.h: PoolCell union + CreateWithBuffer(), uses_buffer(), cell_size(),
  cell_alignment(), required_bytes(); pool-routed AllocateNode/DestroyNode;
  move ctor/assignment extended to carry pool state.
- map_test.cpp: tests for empty/insert/find, capacity bound, freed-cell reuse,
  move, and OrAbort-on-exhaustion death test.
- bounded_containers.h: convert the shared-memory example bundle to the
  allocator-free buffer API.
- README.md: document the cross-process map mutation capability.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MichaelSteffens17 and others added 3 commits June 25, 2026 17:30
The child now inserts new keys into the parent's map, exercising node
allocation from the shared free-list pool across processes (not just in-place
value updates). The parent observes the grown map (size 3 -> 5) after remapping
the segment, confirming pooled allocation is position-independent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A buffer not aligned to cell_alignment() would misalign the pooled nodes.
That is a caller precondition violation, so trap it with std::abort() like the
map's other contract checks rather than returning an error. Add a death test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reflect the child's new insertion step: the README now describes node
allocation from the shared free-list pool across processes (map grows 3 -> 5),
not just in-place value updates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants