1
1
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2
2
3
3
use crate :: { BoundRange , Key , KvPair , Result , Value } ;
4
+ use derive_new:: new;
4
5
use std:: {
5
- collections:: { BTreeMap , HashMap } ,
6
+ collections:: { btree_map :: Entry , BTreeMap , HashMap } ,
6
7
future:: Future ,
7
8
} ;
8
9
use tikv_client_proto:: kvrpcpb;
9
10
use tokio:: sync:: { Mutex , MutexGuard } ;
10
11
11
- #[ derive( Default ) ]
12
+ #[ derive( new ) ]
12
13
struct InnerBuffer {
14
+ #[ new( default ) ]
13
15
primary_key : Option < Key > ,
16
+ #[ new( default ) ]
14
17
entry_map : BTreeMap < Key , BufferEntry > ,
18
+ is_pessimistic : bool ,
15
19
}
16
20
17
21
impl InnerBuffer {
@@ -29,16 +33,22 @@ impl InnerBuffer {
29
33
}
30
34
31
35
/// A caching layer which buffers reads and writes in a transaction.
32
- #[ derive( Default ) ]
33
36
pub struct Buffer {
34
37
mutations : Mutex < InnerBuffer > ,
35
38
}
36
39
37
40
impl Buffer {
41
+ pub fn new ( is_pessimistic : bool ) -> Buffer {
42
+ Buffer {
43
+ mutations : Mutex :: new ( InnerBuffer :: new ( is_pessimistic) ) ,
44
+ }
45
+ }
46
+
38
47
/// Get the primary key of the buffer.
39
48
pub async fn get_primary_key ( & self ) -> Option < Key > {
40
49
self . mutations . lock ( ) . await . primary_key . clone ( )
41
50
}
51
+
42
52
/// Get the primary key of the buffer, if not exists, use `key` as the primary key.
43
53
pub async fn get_primary_key_or ( & self , key : & Key ) -> Key {
44
54
self . mutations . lock ( ) . await . get_primary_key_or ( key) . clone ( )
@@ -203,28 +213,30 @@ impl Buffer {
203
213
204
214
/// Mark a value as Insert mutation into the buffer (does not write through).
205
215
pub async fn insert ( & self , key : Key , value : Value ) {
206
- self . mutations
207
- . lock ( )
208
- . await
209
- . insert ( key, BufferEntry :: Insert ( value) ) ;
216
+ let mut mutations = self . mutations . lock ( ) . await ;
217
+ let mut entry = mutations. entry_map . entry ( key. clone ( ) ) ;
218
+ match entry {
219
+ Entry :: Occupied ( ref mut o) if matches ! ( o. get( ) , BufferEntry :: Del ) => {
220
+ o. insert ( BufferEntry :: Put ( value) ) ;
221
+ }
222
+ _ => mutations. insert ( key, BufferEntry :: Insert ( value) ) ,
223
+ }
210
224
}
211
225
212
226
/// Mark a value as deleted.
213
227
pub async fn delete ( & self , key : Key ) {
214
228
let mut mutations = self . mutations . lock ( ) . await ;
215
- let value = mutations
216
- . entry_map
217
- . entry ( key . clone ( ) )
218
- . or_insert ( BufferEntry :: Del ) ;
219
-
220
- let new_value : BufferEntry ;
221
- if let BufferEntry :: Insert ( _ ) = value {
222
- new_value = BufferEntry :: CheckNotExist
223
- } else {
224
- new_value = BufferEntry :: Del
229
+ let is_pessimistic = mutations. is_pessimistic ;
230
+ let mut entry = mutations . entry_map . entry ( key . clone ( ) ) ;
231
+
232
+ match entry {
233
+ Entry :: Occupied ( ref mut o )
234
+ if matches ! ( o . get ( ) , BufferEntry :: Insert ( _ ) ) && !is_pessimistic =>
235
+ {
236
+ o . insert ( BufferEntry :: CheckNotExist ) ;
237
+ }
238
+ _ => mutations . insert ( key , BufferEntry :: Del ) ,
225
239
}
226
-
227
- mutations. insert ( key, new_value) ;
228
240
}
229
241
230
242
/// Converts the buffered mutations to the proto buffer version
@@ -378,7 +390,7 @@ mod tests {
378
390
#[ tokio:: test]
379
391
#[ allow( unreachable_code) ]
380
392
async fn set_and_get_from_buffer ( ) {
381
- let buffer = Buffer :: default ( ) ;
393
+ let buffer = Buffer :: new ( false ) ;
382
394
buffer
383
395
. put ( b"key1" . to_vec ( ) . into ( ) , b"value1" . to_vec ( ) )
384
396
. await ;
@@ -411,7 +423,7 @@ mod tests {
411
423
#[ tokio:: test]
412
424
#[ allow( unreachable_code) ]
413
425
async fn insert_and_get_from_buffer ( ) {
414
- let buffer = Buffer :: default ( ) ;
426
+ let buffer = Buffer :: new ( false ) ;
415
427
buffer
416
428
. insert ( b"key1" . to_vec ( ) . into ( ) , b"value1" . to_vec ( ) )
417
429
. await ;
@@ -453,13 +465,13 @@ mod tests {
453
465
let v2: Value = b"value2" . to_vec ( ) ;
454
466
let v2_ = v2. clone ( ) ;
455
467
456
- let buffer = Buffer :: default ( ) ;
468
+ let buffer = Buffer :: new ( false ) ;
457
469
let r1 = block_on ( buffer. get_or_else ( k1. clone ( ) , move |_| ready ( Ok ( Some ( v1_) ) ) ) ) ;
458
470
let r2 = block_on ( buffer. get_or_else ( k1. clone ( ) , move |_| ready ( panic ! ( ) ) ) ) ;
459
471
assert_eq ! ( r1. unwrap( ) . unwrap( ) , v1) ;
460
472
assert_eq ! ( r2. unwrap( ) . unwrap( ) , v1) ;
461
473
462
- let buffer = Buffer :: default ( ) ;
474
+ let buffer = Buffer :: new ( false ) ;
463
475
let r1 = block_on (
464
476
buffer. batch_get_or_else ( vec ! [ k1. clone( ) , k2. clone( ) ] . into_iter ( ) , move |_| {
465
477
ready ( Ok ( vec ! [ ( k1_, v1__) . into( ) , ( k2_, v2_) . into( ) ] ) )
0 commit comments