From 932bb4f58b1235707db90e40f8903f0e4dc9e34a Mon Sep 17 00:00:00 2001 From: Sayan Nandan Date: Wed, 1 Feb 2023 09:00:54 -0800 Subject: [PATCH] Fix remove len impl, use relaxed and add tests --- server/src/engine/idx/mtchm/mod.rs | 10 +++++-- server/src/engine/idx/mtchm/tests.rs | 44 ++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/server/src/engine/idx/mtchm/mod.rs b/server/src/engine/idx/mtchm/mod.rs index 7c20a729..4603189d 100644 --- a/server/src/engine/idx/mtchm/mod.rs +++ b/server/src/engine/idx/mtchm/mod.rs @@ -503,6 +503,7 @@ impl Tree { Self::read_data(node) }; let mut ret = W::nx(); + let mut rem = false; // this node shouldn't be empty debug_assert!(!data.is_empty(), "logic,empty node not collected"); // build new lnode @@ -511,6 +512,7 @@ impl Tree { .filter_map(|this_elem| { if this_elem.key().borrow() == k { ret = W::ex(this_elem); + rem = true; None } else { Some(this_elem.clone()) @@ -567,6 +569,7 @@ impl Tree { break; } } + self.decr_len_by(rem as _); gc(g); return ret; } @@ -586,10 +589,13 @@ impl Tree { impl Tree { // hilarious enough but true, l doesn't affect safety but only creates an incorrect state 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) { - self.l.fetch_add(1, ORD_ACQ); + self.l.fetch_add(1, ORD_RLX); } #[inline(always)] fn new_lnode(node: LNode) -> Owned> { diff --git a/server/src/engine/idx/mtchm/tests.rs b/server/src/engine/idx/mtchm/tests.rs index fe4e5778..43ec8be3 100644 --- a/server/src/engine/idx/mtchm/tests.rs +++ b/server/src/engine/idx/mtchm/tests.rs @@ -201,7 +201,7 @@ fn tjoin_all(handles: Vec>) -> Box<[T]> { .collect() } -fn store_and_verify_integrity( +fn modify_and_verify_integrity( token: &ControlToken, tree: &Arc>, source_buf: &[StringTup], @@ -230,7 +230,7 @@ fn _action_put( let _token = token.acquire_permit(); let g = cpin(); data.into_iter().for_each(|(k, v)| { - assert!(idx.insert((k, v), &g)); + assert!(idx.mt_insert(k, v, &g)); }); } fn _verify_eq( @@ -255,7 +255,7 @@ fn multispam_insert() { let token = ControlToken::new(); let mut data = Vec::new(); 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] @@ -264,21 +264,13 @@ fn multispam_update() { let token = ControlToken::new(); let mut data = Vec::new(); prepare_data(&mut data, TUP_INCR); - assert!(data - .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); + modify_and_verify_integrity(&token, &idx, &data, _action_put, _verify_eq); // update our data set data.iter_mut().enumerate().for_each(|(i, (_, v))| { *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( + modify_and_verify_integrity( &token, &idx, &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()); + }, + ); +}