@@ -264,13 +264,32 @@ TEST(DB, sqlite_encryption_migrate_v4) {
264264
265265using SeqNo = td::uint64;
266266struct DbQuery {
267- enum class Type { Get, Set, Erase } type = Type::Get;
267+ enum class Type { Get, Set, Erase, EraseBatch } type = Type::Get;
268268 SeqNo tid = 0 ;
269- td::int32 id = 0 ;
270269 td::string key;
271270 td::string value;
271+
272+ // for EraseBatch
273+ td::vector<td::string> erased_keys;
272274};
273275
276+ static td::StringBuilder &operator <<(td::StringBuilder &string_builder, const DbQuery &query) {
277+ string_builder << " seq_no = " << query.tid << " : " ;
278+ switch (query.type ) {
279+ case DbQuery::Type::Get:
280+ return string_builder << " Get " << query.key << " = " << query.value ;
281+ case DbQuery::Type::Set:
282+ return string_builder << " Set " << query.key << " = " << query.value ;
283+ case DbQuery::Type::Erase:
284+ return string_builder << " Del " << query.key ;
285+ case DbQuery::Type::EraseBatch:
286+ return string_builder << " Del " << query.erased_keys ;
287+ default :
288+ UNREACHABLE ();
289+ return string_builder;
290+ }
291+ }
292+
274293template <class ImplT >
275294class QueryHandler {
276295 public:
@@ -290,6 +309,10 @@ class QueryHandler {
290309 impl_.erase (query.key );
291310 query.tid = 1 ;
292311 return ;
312+ case DbQuery::Type::EraseBatch:
313+ impl_.erase_batch (query.erased_keys );
314+ query.tid = 1 ;
315+ return ;
293316 }
294317 }
295318
@@ -314,6 +337,9 @@ class SeqQueryHandler {
314337 case DbQuery::Type::Erase:
315338 query.tid = impl_.erase (query.key );
316339 return ;
340+ case DbQuery::Type::EraseBatch:
341+ query.tid = impl_.erase_batch (query.erased_keys );
342+ return ;
317343 }
318344 }
319345
@@ -334,6 +360,12 @@ class SqliteKV {
334360 kv_->get ().erase (key);
335361 return 0 ;
336362 }
363+ SeqNo erase_batch (td::vector<td::string> keys) {
364+ for (auto &key : keys) {
365+ kv_->get ().erase (key);
366+ }
367+ return 0 ;
368+ }
337369 td::Status init (const td::string &name) {
338370 auto sql_connection = std::make_shared<td::SqliteConnectionSafe>(name, td::DbKey::empty ());
339371 kv_ = std::make_shared<td::SqliteKeyValueSafe>(" kv" , sql_connection);
@@ -360,6 +392,14 @@ class BaselineKV {
360392 map_.erase (key);
361393 return ++current_tid_;
362394 }
395+ SeqNo erase_batch (td::vector<td::string> keys) {
396+ for (auto &key : keys) {
397+ map_.erase (key);
398+ }
399+ SeqNo result = current_tid_ + 1 ;
400+ current_tid_ += map_.size ();
401+ return result;
402+ }
363403
364404 private:
365405 std::map<td::string, td::string> map_;
@@ -380,9 +420,8 @@ TEST(DB, key_value) {
380420 int queries_n = 1000 ;
381421 td::vector<DbQuery> queries (queries_n);
382422 for (auto &q : queries) {
383- int op = td::Random::fast (0 , 2 );
423+ int op = td::Random::fast (0 , 3 );
384424 const auto &key = rand_elem (keys);
385- const auto &value = rand_elem (values);
386425 if (op == 0 ) {
387426 q.type = DbQuery::Type::Get;
388427 q.key = key;
@@ -392,7 +431,13 @@ TEST(DB, key_value) {
392431 } else if (op == 2 ) {
393432 q.type = DbQuery::Type::Set;
394433 q.key = key;
395- q.value = value;
434+ q.value = rand_elem (values);
435+ } else if (op == 3 ) {
436+ q.type = DbQuery::Type::EraseBatch;
437+ q.erased_keys .resize (td::Random::fast (0 , 3 ));
438+ for (auto &erased_key : q.erased_keys ) {
439+ erased_key = rand_elem (keys);
440+ }
396441 }
397442 }
398443
@@ -494,17 +539,22 @@ TEST(DB, thread_key_value) {
494539 for (auto &q : qs) {
495540 int op = td::Random::fast (0 , 10 );
496541 const auto &key = rand_elem (keys);
497- const auto &value = rand_elem (values);
498- if (op > 1 ) {
499- q.type = DbQuery::Type::Get;
500- q.key = key;
501- } else if (op == 0 ) {
542+ if (op == 0 ) {
502543 q.type = DbQuery::Type::Erase;
503544 q.key = key;
504545 } else if (op == 1 ) {
546+ q.type = DbQuery::Type::EraseBatch;
547+ q.erased_keys .resize (td::Random::fast (0 , 3 ));
548+ for (auto &erased_key : q.erased_keys ) {
549+ erased_key = rand_elem (keys);
550+ }
551+ } else if (op <= 6 ) {
505552 q.type = DbQuery::Type::Set;
506553 q.key = key;
507- q.value = value;
554+ q.value = rand_elem (values);
555+ } else {
556+ q.type = DbQuery::Type::Get;
557+ q.key = key;
508558 }
509559 }
510560 }
@@ -606,17 +656,22 @@ TEST(DB, persistent_key_value) {
606656 for (auto &q : qs) {
607657 int op = td::Random::fast (0 , 10 );
608658 const auto &key = rand_elem (keys);
609- const auto &value = rand_elem (values);
610- if (op > 1 ) {
611- q.type = DbQuery::Type::Get;
612- q.key = key;
613- } else if (op == 0 ) {
659+ if (op == 0 ) {
614660 q.type = DbQuery::Type::Erase;
615661 q.key = key;
616662 } else if (op == 1 ) {
663+ q.type = DbQuery::Type::EraseBatch;
664+ q.erased_keys .resize (td::Random::fast (0 , 3 ));
665+ for (auto &erased_key : q.erased_keys ) {
666+ erased_key = rand_elem (keys);
667+ }
668+ } else if (op <= 6 ) {
617669 q.type = DbQuery::Type::Set;
618670 q.key = key;
619- q.value = value;
671+ q.value = rand_elem (values);
672+ } else {
673+ q.type = DbQuery::Type::Get;
674+ q.key = key;
620675 }
621676 }
622677 }
@@ -718,6 +773,7 @@ TEST(DB, persistent_key_value) {
718773 if (was) {
719774 continue ;
720775 }
776+ LOG (DEBUG ) << pos;
721777
722778 int best = -1 ;
723779 SeqNo best_tid = 0 ;
@@ -728,6 +784,7 @@ TEST(DB, persistent_key_value) {
728784 }
729785 was = true ;
730786 auto &q = res[i][p];
787+ LOG (DEBUG ) << i << ' ' << p << ' ' << q;
731788 if (q.tid != 0 ) {
732789 if (best == -1 || q.tid < best_tid) {
733790 best = i;
0 commit comments