Skip to content

Commit 293b85f

Browse files
committed
Port get_disjoint_mut to ringmap
1 parent a8fc73e commit 293b85f

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

src/map.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,8 @@ where
838838
Q: ?Sized + Hash + Equivalent<K>,
839839
{
840840
let indices = keys.map(|key| self.get_index_of(key));
841-
match self.as_mut_slice().get_disjoint_opt_mut(indices) {
841+
let (head, tail) = self.as_mut_slices();
842+
match Slice::get_disjoint_opt_mut(head, tail, indices) {
842843
Err(GetDisjointMutError::IndexOutOfBounds) => {
843844
unreachable!(
844845
"Internal error: indices should never be OOB as we got them from get_index_of"
@@ -1326,7 +1327,10 @@ impl<K, V, S> RingMap<K, V, S> {
13261327
&mut self,
13271328
indices: [usize; N],
13281329
) -> Result<[(&K, &mut V); N], GetDisjointMutError> {
1329-
self.as_mut_slice().get_disjoint_mut(indices)
1330+
let indices = indices.map(Some);
1331+
let (head, tail) = self.as_mut_slices();
1332+
let key_values = Slice::get_disjoint_opt_mut(head, tail, indices)?;
1333+
Ok(key_values.map(Option::unwrap))
13301334
}
13311335

13321336
/// Get the first key-value pair

src/map/slice.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,21 @@ impl<K, V> Slice<K, V> {
274274
indices: [usize; N],
275275
) -> Result<[(&K, &mut V); N], GetDisjointMutError> {
276276
let indices = indices.map(Some);
277-
let key_values = self.get_disjoint_opt_mut(indices)?;
277+
let empty_tail = Self::new_mut();
278+
let key_values = Self::get_disjoint_opt_mut(self, empty_tail, indices)?;
278279
Ok(key_values.map(Option::unwrap))
279280
}
280281

281282
#[allow(unsafe_code)]
282-
pub(crate) fn get_disjoint_opt_mut<const N: usize>(
283-
&mut self,
283+
pub(crate) fn get_disjoint_opt_mut<'a, const N: usize>(
284+
head: &mut Self,
285+
tail: &mut Self,
284286
indices: [Option<usize>; N],
285-
) -> Result<[Option<(&K, &mut V)>; N], GetDisjointMutError> {
287+
) -> Result<[Option<(&'a K, &'a mut V)>; N], GetDisjointMutError> {
288+
let mid = head.len();
289+
let len = mid + tail.len();
290+
286291
// SAFETY: Can't allow duplicate indices as we would return several mutable refs to the same data.
287-
let len = self.len();
288292
for i in 0..N {
289293
if let Some(idx) = indices[i] {
290294
if idx >= len {
@@ -295,14 +299,20 @@ impl<K, V> Slice<K, V> {
295299
}
296300
}
297301

298-
let entries_ptr = self.entries.as_mut_ptr();
302+
let head_ptr = head.entries.as_mut_ptr();
303+
let tail_ptr = tail.entries.as_mut_ptr();
299304
let out = indices.map(|idx_opt| {
300305
match idx_opt {
301306
Some(idx) => {
302-
// SAFETY: The base pointer is valid as it comes from a slice and the reference is always
307+
// SAFETY: The base pointers are valid as they come from slices and the reference is always
303308
// in-bounds & unique as we've already checked the indices above.
304-
let kv = unsafe { (*(entries_ptr.add(idx))).ref_mut() };
305-
Some(kv)
309+
unsafe {
310+
let ptr = match idx.checked_sub(mid) {
311+
None => head_ptr.add(idx),
312+
Some(tidx) => tail_ptr.add(tidx),
313+
};
314+
Some((*ptr).ref_mut())
315+
}
306316
}
307317
None => None,
308318
}

0 commit comments

Comments
 (0)