Skip to content

Commit b2ac690

Browse files
committed
Handle more combinations of operations in the buffer
Closes #257, #270 Signed-off-by: Nick Cameron <nrc@ncameron.org>
1 parent da26bb4 commit b2ac690

File tree

1 file changed

+69
-14
lines changed

1 file changed

+69
-14
lines changed

src/transaction/buffer.rs

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,18 @@ impl Buffer {
174174
}
175175
}
176176

177-
/// Insert a value into the buffer (does not write through).
177+
/// Put a value into the buffer (does not write through).
178178
pub async fn put(&mut self, key: Key, value: Value) {
179-
self.insert_entry(key, BufferEntry::Put(value));
179+
let mut entry = self.entry_map.entry(key.clone());
180+
match entry {
181+
Entry::Occupied(ref mut o)
182+
if matches!(o.get(), BufferEntry::Insert(_))
183+
|| matches!(o.get(), BufferEntry::CheckNotExist) =>
184+
{
185+
o.insert(BufferEntry::Insert(value));
186+
}
187+
_ => self.insert_entry(key, BufferEntry::Put(value)),
188+
}
180189
}
181190

182191
/// Mark a value as Insert mutation into the buffer (does not write through).
@@ -197,7 +206,9 @@ impl Buffer {
197206

198207
match entry {
199208
Entry::Occupied(ref mut o)
200-
if matches!(o.get(), BufferEntry::Insert(_)) && !is_pessimistic =>
209+
if !is_pessimistic
210+
&& (matches!(o.get(), BufferEntry::Insert(_))
211+
|| matches!(o.get(), BufferEntry::CheckNotExist)) =>
201212
{
202213
o.insert(BufferEntry::CheckNotExist);
203214
}
@@ -352,9 +363,9 @@ impl MutationValue {
352363
mod tests {
353364
use super::*;
354365
use futures::{executor::block_on, future::ready};
366+
use tikv_client_common::internal_err;
355367

356368
#[tokio::test]
357-
#[allow(unreachable_code)]
358369
async fn set_and_get_from_buffer() {
359370
let mut buffer = Buffer::new(false);
360371
buffer
@@ -364,9 +375,13 @@ mod tests {
364375
.put(b"key2".to_vec().into(), b"value2".to_vec())
365376
.await;
366377
assert_eq!(
367-
block_on(buffer.get_or_else(b"key1".to_vec().into(), move |_| ready(panic!())))
368-
.unwrap()
369-
.unwrap(),
378+
block_on(
379+
buffer.get_or_else(b"key1".to_vec().into(), move |_| ready(Err(internal_err!(
380+
""
381+
))))
382+
)
383+
.unwrap()
384+
.unwrap(),
370385
b"value1".to_vec()
371386
);
372387

@@ -387,7 +402,6 @@ mod tests {
387402
}
388403

389404
#[tokio::test]
390-
#[allow(unreachable_code)]
391405
async fn insert_and_get_from_buffer() {
392406
let mut buffer = Buffer::new(false);
393407
buffer
@@ -397,9 +411,13 @@ mod tests {
397411
.insert(b"key2".to_vec().into(), b"value2".to_vec())
398412
.await;
399413
assert_eq!(
400-
block_on(buffer.get_or_else(b"key1".to_vec().into(), move |_| ready(panic!())))
401-
.unwrap()
402-
.unwrap(),
414+
block_on(
415+
buffer.get_or_else(b"key1".to_vec().into(), move |_| ready(Err(internal_err!(
416+
""
417+
))))
418+
)
419+
.unwrap()
420+
.unwrap(),
403421
b"value1".to_vec()
404422
);
405423

@@ -419,7 +437,6 @@ mod tests {
419437
}
420438

421439
#[test]
422-
#[allow(unreachable_code)]
423440
fn repeat_reads_are_cached() {
424441
let k1: Key = b"key1".to_vec().into();
425442
let k1_ = k1.clone();
@@ -433,7 +450,7 @@ mod tests {
433450

434451
let mut buffer = Buffer::new(false);
435452
let r1 = block_on(buffer.get_or_else(k1.clone(), move |_| ready(Ok(Some(v1_)))));
436-
let r2 = block_on(buffer.get_or_else(k1.clone(), move |_| ready(panic!())));
453+
let r2 = block_on(buffer.get_or_else(k1.clone(), move |_| ready(Err(internal_err!("")))));
437454
assert_eq!(r1.unwrap().unwrap(), v1);
438455
assert_eq!(r2.unwrap().unwrap(), v1);
439456

@@ -443,7 +460,7 @@ mod tests {
443460
ready(Ok(vec![(k1_, v1__).into(), (k2_, v2_).into()]))
444461
}),
445462
);
446-
let r2 = block_on(buffer.get_or_else(k2.clone(), move |_| ready(panic!())));
463+
let r2 = block_on(buffer.get_or_else(k2.clone(), move |_| ready(Err(internal_err!("")))));
447464
let r3 = block_on(
448465
buffer.batch_get_or_else(vec![k1.clone(), k2.clone()].into_iter(), move |_| {
449466
ready(Ok(vec![]))
@@ -462,4 +479,42 @@ mod tests {
462479
vec![KvPair(k1, v1), KvPair(k2, v2)]
463480
);
464481
}
482+
483+
// Check that multiple writes to the same key combine in the correct way.
484+
#[tokio::test]
485+
async fn state_machine() {
486+
let mut buffer = Buffer::new(false);
487+
488+
macro_rules! assert_entry {
489+
($key: ident, $p: pat) => {
490+
assert!(matches!(buffer.entry_map.get(&$key), Some(&$p),))
491+
};
492+
}
493+
494+
// Insert + Delete = CheckNotExists
495+
let key: Key = b"key1".to_vec().into();
496+
buffer.insert(key.clone(), b"value1".to_vec()).await;
497+
buffer.delete(key.clone()).await;
498+
assert_entry!(key, BufferEntry::CheckNotExist);
499+
500+
// CheckNotExists + Delete = CheckNotExists
501+
buffer.delete(key.clone()).await;
502+
assert_entry!(key, BufferEntry::CheckNotExist);
503+
504+
// CheckNotExists + Put = Insert
505+
buffer.put(key.clone(), b"value2".to_vec()).await;
506+
assert_entry!(key, BufferEntry::Insert(_));
507+
508+
// Insert + Put = Insert
509+
let key: Key = b"key2".to_vec().into();
510+
buffer.insert(key.clone(), b"value1".to_vec()).await;
511+
buffer.put(key.clone(), b"value2".to_vec()).await;
512+
assert_entry!(key, BufferEntry::Insert(_));
513+
514+
// Delete + Insert = Put
515+
let key: Key = b"key3".to_vec().into();
516+
buffer.delete(key.clone()).await;
517+
buffer.insert(key.clone(), b"value1".to_vec()).await;
518+
assert_entry!(key, BufferEntry::Put(_));
519+
}
465520
}

0 commit comments

Comments
 (0)