Skip to content

fix: use conservative bucket reuse that survives reload#394

Merged
maksymar merged 18 commits intomainfrom
maksym/buckets-fix
Aug 21, 2025
Merged

fix: use conservative bucket reuse that survives reload#394
maksymar merged 18 commits intomainfrom
maksym/buckets-fix

Conversation

@maksymar
Copy link
Copy Markdown
Contributor

@maksymar maksymar commented Aug 20, 2025

This PR uses conservative bucket reuse to preserve ordering across reloads.

Problem

Previously, a memory with buckets [5, 6, 7] could reuse free buckets [0, 1, 2], producing [5, 6, 7, 0, 1, 2]. On reload, the manager reads buckets in ascending order — [0, 1, 2, 5, 6, 7] — corrupting the structure.

Fix

When growing a memory, reuse only free buckets with IDs greater than the memory’s current max; otherwise allocate a new bucket. This keeps per-memory bucket IDs strictly ascending across lifetimes.

Guarantees

  • Newly created structures will reliably reuse available free buckets.
  • Existing structures may reuse buckets when higher-ID free buckets exist — this is not guaranteed and not user-controllable.

Result

A conservative reuse algorithm that maintains stable-structure consistency after reloads.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/btreeset) 126972f 2025-08-21 08:24:38 UTC

./benchmarks/btreeset/canbench_results.yml is up to date
📦 canbench_results_btreeset.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 100 | regressed 0 | improved 0 | new 0 | unchanged 100]
    change:   [max +1.61M | p75 +2.66K | median +92 | p25 0 | min -160.01K]
    change %: [max +0.62% | p75 +0.02% | median 0.00% | p25 0.00% | min -1.50%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 100 | regressed 0 | improved 0 | new 0 | unchanged 100]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 100 | regressed 0 | improved 0 | new 0 | unchanged 100]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/nns) 126972f 2025-08-21 08:24:18 UTC

./benchmarks/nns/canbench_results.yml is up to date
📦 canbench_results_nns.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max +1.03M | p75 +32.74K | median +19 | p25 -257.92K | min -4.43M]
    change %: [max +0.55% | p75 +0.12% | median +0.02% | p25 -0.05% | min -0.08%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/io_chunks) 126972f 2025-08-21 08:25:14 UTC

./benchmarks/io_chunks/canbench_results.yml is up to date
📦 canbench_results_io_chunks.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 18 | regressed 0 | improved 0 | new 0 | unchanged 18]
    change:   [max +112 | p75 +97 | median -14 | p25 -30.76K | min -10.63M]
    change %: [max 0.00% | p75 0.00% | median -0.00% | p25 -0.00% | min -0.36%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 18 | regressed 0 | improved 0 | new 0 | unchanged 18]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 18 | regressed 0 | improved 0 | new 0 | unchanged 18]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/vec) 126972f 2025-08-21 08:24:06 UTC

./benchmarks/vec/canbench_results.yml is up to date
📦 canbench_results_vec.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 16 | regressed 0 | improved 0 | new 0 | unchanged 16]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/btreemap) 126972f 2025-08-21 08:25:48 UTC

./benchmarks/btreemap/canbench_results.yml is up to date
📦 canbench_results_btreemap.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 303 | regressed 0 | improved 0 | new 0 | unchanged 303]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 303 | regressed 0 | improved 0 | new 0 | unchanged 303]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 303 | regressed 0 | improved 0 | new 0 | unchanged 303]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 20, 2025

canbench 🏋 (dir: ./benchmarks/memory_manager) 126972f 2025-08-21 08:24:12 UTC

./benchmarks/memory_manager/canbench_results.yml is up to date
📦 canbench_results_memory-manager.csv available in artifacts

---------------------------------------------------

Summary:
  instructions:
    status:   No significant changes 👍
    counts:   [total 3 | regressed 0 | improved 0 | new 0 | unchanged 3]
    change:   [max +1.18M | p75 +595.51K | median +6.97K | p25 +3.48K | min 0]
    change %: [max +0.34% | p75 +0.17% | median 0.00% | p25 0.00% | min 0.00%]

  heap_increase:
    status:   No significant changes 👍
    counts:   [total 3 | regressed 0 | improved 0 | new 0 | unchanged 3]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

  stable_memory_increase:
    status:   No significant changes 👍
    counts:   [total 3 | regressed 0 | improved 0 | new 0 | unchanged 3]
    change:   [max 0 | p75 0 | median 0 | p25 0 | min 0]
    change %: [max 0.00% | p75 0.00% | median 0.00% | p25 0.00% | min 0.00%]

---------------------------------------------------
CSV results saved to canbench_results.csv

@maksymar maksymar changed the title test: add test showing broken buckets order fix: use conservative bucket reuse that survives reload Aug 20, 2025
@maksymar maksymar marked this pull request as ready for review August 21, 2025 08:11
@maksymar maksymar requested a review from a team as a code owner August 21, 2025 08:11
Comment thread src/memory_manager.rs
@maksymar maksymar merged commit 6e397bd into main Aug 21, 2025
17 checks passed
@maksymar maksymar deleted the maksym/buckets-fix branch August 21, 2025 13:05
maksymar added a commit that referenced this pull request Aug 25, 2025
This PR reverts adding `reclaim_memory` method.

Reverts several recent commits in a single change:

- `6e397bd` fix: use conservative bucket reuse that survives reload #394
- `00468e1` docs: update memory reclamation examples in the docs  #392 
- `b911479` docs: cleanup documentation  #391 
- `d1fde89` docs: use reclaim_memory() name and update docs accordingly
#388
- `a18917b` docs: add safety documentation and tests for manual bucket
release #387
- `73e96e8` feat: add manual bucket release to prevent memory waste #386

This PR restores the codebase to the state before these commits.

Done with `git revert -n 6e397bd 00468e1 b911479 d1fde89 a18917b
73e96e8`

The reason for reverting this approach was that it can reclaim unused
memory in theory but provides little benefit in real-world migrations.
All due to the requirement to keep buckets in ascending order in each
VM.

Example 1: Reuse works
```
A allocates: [0, 4, 5]
B allocates: [1, 2, 3]
A frees: [0, 4, 5]
B grows: can reuse bucket 4 (since 4 > max(B) = 3)
B after grow: [1, 2, 3, 4]
```
Example 2: Reuse fails
```
A allocates: [0, 1, 2]
B allocates: [4, 5, 6]
A frees: [0, 1, 2]
B grows: cannot reuse any freed bucket (all < max(B) = 6), so allocates new bucket 7
B after grow: [4, 5, 6, 7]
```

In real life when migrating state A to state B, state B created after
state A grown, so it's first bucket ID is already higher than any free
bucket in state A virtual memory, therefore can not be reused.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants