Skip to content

Add shift_remove family to IndexMap/IndexSet - #685

Open
HarnageaGabriel wants to merge 2 commits into
rust-embedded:mainfrom
HarnageaGabriel:feat/shift-remove-indexmap
Open

Add shift_remove family to IndexMap/IndexSet#685
HarnageaGabriel wants to merge 2 commits into
rust-embedded:mainfrom
HarnageaGabriel:feat/shift-remove-indexmap

Conversation

@HarnageaGabriel

Copy link
Copy Markdown

Summary

swap_remove is O(1) but perturbs map/set order by moving the last element into the removed slot. This adds order-preserving removal, mirroring the indexmap crate's shift_remove API:

  • IndexMap::shift_remove / shift_remove_entry / shift_remove_index
  • OccupiedEntry::shift_remove / shift_remove_entry
  • IndexSet::shift_remove

Implementation: CoreMap::shift_remove_found removes the entry with Vec::remove (order-preserving shift) instead of swap_remove_unchecked, then walks the indices robin-hood table decrementing every Pos whose index pointed past the removed slot, then runs the existing backward_shift_after_removal to restore the probe-distance invariant. O(n) instead of swap_remove's O(1), same as upstream indexmap.

remove/swap_remove/remove_entry/swap_remove_entry are untouched.

Fixes #678

Test plan

  • cargo build
  • cargo test --lib (251 passed, including 5 new shift_remove tests covering order preservation on IndexMap, OccupiedEntry, shift_remove_index, and IndexSet)
  • cargo test --doc index_map (31 passed, including new doctests)
  • cargo clippy --lib clean (repo denies clippy::undocumented_unsafe_blocks)
  • cargo fmt --check clean

swap_remove is O(1) but perturbs the position of the last element,
which isn't acceptable when callers need remaining entries to keep
their relative insertion order after a removal. This mirrors the
upstream indexmap crate's shift_remove/shift_remove_entry API
(O(n), shifts entries down via Vec::remove and fixes up the hash
table's index pointers) adapted to heapless's fixed-capacity,
no_std CoreMap/Pos representation.

Fixes rust-embedded#678
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.

IndexMap/IndexSet: implement shift_remove and variants

1 participant