Fix remove len impl, use relaxed and add tests

next
Sayan Nandan 2 years ago
parent 1920664273
commit 932bb4f58b
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -503,6 +503,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
Self::read_data(node) Self::read_data(node)
}; };
let mut ret = W::nx(); let mut ret = W::nx();
let mut rem = false;
// this node shouldn't be empty // this node shouldn't be empty
debug_assert!(!data.is_empty(), "logic,empty node not collected"); debug_assert!(!data.is_empty(), "logic,empty node not collected");
// build new lnode // build new lnode
@ -511,6 +512,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
.filter_map(|this_elem| { .filter_map(|this_elem| {
if this_elem.key().borrow() == k { if this_elem.key().borrow() == k {
ret = W::ex(this_elem); ret = W::ex(this_elem);
rem = true;
None None
} else { } else {
Some(this_elem.clone()) Some(this_elem.clone())
@ -567,6 +569,7 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
break; break;
} }
} }
self.decr_len_by(rem as _);
gc(g); gc(g);
return ret; return ret;
} }
@ -586,10 +589,13 @@ impl<T: TreeElement, C: Config> Tree<T, C> {
impl<T, C: Config> Tree<T, C> { impl<T, C: Config> Tree<T, C> {
// hilarious enough but true, l doesn't affect safety but only creates an incorrect state // hilarious enough but true, l doesn't affect safety but only creates an incorrect state
fn decr_len(&self) { fn decr_len(&self) {
self.l.fetch_sub(1, ORD_ACQ); self.decr_len_by(1)
}
fn decr_len_by(&self, by: usize) {
self.l.fetch_sub(by, ORD_RLX);
} }
fn incr_len(&self) { fn incr_len(&self) {
self.l.fetch_add(1, ORD_ACQ); self.l.fetch_add(1, ORD_RLX);
} }
#[inline(always)] #[inline(always)]
fn new_lnode(node: LNode<T>) -> Owned<Node<C>> { fn new_lnode(node: LNode<T>) -> Owned<Node<C>> {

@ -201,7 +201,7 @@ fn tjoin_all<T>(handles: Vec<JoinHandle<T>>) -> Box<[T]> {
.collect() .collect()
} }
fn store_and_verify_integrity<K, V>( fn modify_and_verify_integrity<K, V>(
token: &ControlToken, token: &ControlToken,
tree: &Arc<ChmCopy<K, V>>, tree: &Arc<ChmCopy<K, V>>,
source_buf: &[StringTup], source_buf: &[StringTup],
@ -230,7 +230,7 @@ fn _action_put(
let _token = token.acquire_permit(); let _token = token.acquire_permit();
let g = cpin(); let g = cpin();
data.into_iter().for_each(|(k, v)| { data.into_iter().for_each(|(k, v)| {
assert!(idx.insert((k, v), &g)); assert!(idx.mt_insert(k, v, &g));
}); });
} }
fn _verify_eq( fn _verify_eq(
@ -255,7 +255,7 @@ fn multispam_insert() {
let token = ControlToken::new(); let token = ControlToken::new();
let mut data = Vec::new(); let mut data = Vec::new();
prepare_data(&mut data, TUP_INCR); prepare_data(&mut data, TUP_INCR);
store_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq); modify_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq);
} }
#[test] #[test]
@ -264,21 +264,13 @@ fn multispam_update() {
let token = ControlToken::new(); let token = ControlToken::new();
let mut data = Vec::new(); let mut data = Vec::new();
prepare_data(&mut data, TUP_INCR); prepare_data(&mut data, TUP_INCR);
assert!(data modify_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq);
.iter()
.enumerate()
.all(|(i, (k, v))| { i == k.parse().unwrap() && i + 1 == v.parse().unwrap() }));
store_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq);
// update our data set // update our data set
data.iter_mut().enumerate().for_each(|(i, (_, v))| { data.iter_mut().enumerate().for_each(|(i, (_, v))| {
*v = Arc::new((i + 2).to_string()); *v = Arc::new((i + 2).to_string());
}); });
assert!(data
.iter()
.enumerate()
.all(|(i, (k, v))| { i == k.parse().unwrap() && i + 2 == v.parse().unwrap() }));
// store and verify integrity // store and verify integrity
store_and_verify_integrity( modify_and_verify_integrity(
&token, &token,
&idx, &idx,
&data, &data,
@ -307,3 +299,29 @@ fn multispam_update() {
}, },
); );
} }
#[test]
fn multispam_delete() {
let idx = Arc::default();
let token = ControlToken::new();
let mut data = Vec::new();
prepare_data(&mut data, TUP_INCR);
modify_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq);
// now expunge
modify_and_verify_integrity(
&token,
&idx,
&data,
|tok, idx, chunk| {
let g = cpin();
let _permit = tok.acquire_permit();
chunk.into_iter().for_each(|(k, v)| {
assert_eq!(idx.mt_delete_return(&k, &g).unwrap().as_str(), v.as_str());
});
},
|g, idx, orig| {
assert!(orig.into_iter().all(|(k, _)| idx.mt_get(k, &g).is_none()));
assert!(idx.is_empty(), "expected empty, found {} elements instead", idx.len());
},
);
}

Loading…
Cancel
Save