Skip to content

Commit

Permalink
use AtomicUsize
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Jan 17, 2024
1 parent a596dbf commit d9e31e8
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions src/lazy_index_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@ use std::cmp::{Eq, PartialEq};
use std::fmt;
use std::hash::Hash;
use std::slice::Iter as SliceIter;
use std::sync::{Arc, Mutex, OnceLock};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::OnceLock;

use ahash::AHashMap;
use smallvec::SmallVec;

/// Like [IndexMap](https://docs.rs/indexmap/latest/indexmap/) but only builds the lookup map when it's needed.
#[derive(Clone, Default)]
#[derive(Default)]

Check warning on line 13 in src/lazy_index_map.rs

View check run for this annotation

Codecov / codecov/patch

src/lazy_index_map.rs#L13

Added line #L13 was not covered by tests
pub struct LazyIndexMap<K, V> {
vec: SmallVec<[(K, V); 8]>,
map: OnceLock<AHashMap<K, usize>>,
last_find: Arc<Mutex<usize>>,
last_find: AtomicUsize,
}

impl<K: Clone, V: Clone> Clone for LazyIndexMap<K, V> {
fn clone(&self) -> Self {
Self {
vec: self.vec.clone(),
map: OnceLock::new(),
last_find: AtomicUsize::new(0),
}
}

Check warning on line 27 in src/lazy_index_map.rs

View check run for this annotation

Codecov / codecov/patch

src/lazy_index_map.rs#L21-L27

Added lines #L21 - L27 were not covered by tests
}

impl<K, V> fmt::Debug for LazyIndexMap<K, V>
Expand All @@ -39,7 +50,7 @@ where
Self {
vec: SmallVec::new(),
map: OnceLock::new(),
last_find: Arc::new(Mutex::new(0)),
last_find: AtomicUsize::new(0),
}
}

Expand Down Expand Up @@ -70,21 +81,16 @@ where
} else {
// otherwise we find the value in the vec
// we assume the most likely position for the match is at `last_find + 1`
match self.last_find.lock() {
Ok(mut last_find) => {
let first_try = *last_find + 1;
for i in first_try..first_try + vec_len {
let index = i % vec_len;
let (k, v) = &self.vec[index];
if k == key {
*last_find = index;
return Some(v);
}
}
None
let first_try = self.last_find.load(Ordering::Relaxed) + 1;
for i in first_try..first_try + vec_len {
let index = i % vec_len;
let (k, v) = &self.vec[index];
if k == key {
self.last_find.store(index, Ordering::Relaxed);
return Some(v);
}
Err(_) => None,
}
None

Check warning on line 93 in src/lazy_index_map.rs

View check run for this annotation

Codecov / codecov/patch

src/lazy_index_map.rs#L93

Added line #L93 was not covered by tests
}
}

Expand Down

0 comments on commit d9e31e8

Please sign in to comment.