@@ -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 {
352363mod 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