Add tests for erase_batch.

This commit is contained in:
levlam 2023-02-12 03:36:52 +03:00
parent 2543d00314
commit b9f7cc4150

View File

@ -264,13 +264,32 @@ TEST(DB, sqlite_encryption_migrate_v4) {
using SeqNo = td::uint64; using SeqNo = td::uint64;
struct DbQuery { struct DbQuery {
enum class Type { Get, Set, Erase } type = Type::Get; enum class Type { Get, Set, Erase, EraseBatch } type = Type::Get;
SeqNo tid = 0; SeqNo tid = 0;
td::int32 id = 0;
td::string key; td::string key;
td::string value; td::string value;
// for EraseBatch
td::vector<td::string> erased_keys;
}; };
static td::StringBuilder &operator<<(td::StringBuilder &string_builder, const DbQuery &query) {
string_builder << "seq_no = " << query.tid << ": ";
switch (query.type) {
case DbQuery::Type::Get:
return string_builder << "Get " << query.key << " = " << query.value;
case DbQuery::Type::Set:
return string_builder << "Set " << query.key << " = " << query.value;
case DbQuery::Type::Erase:
return string_builder << "Del " << query.key;
case DbQuery::Type::EraseBatch:
return string_builder << "Del " << query.erased_keys;
default:
UNREACHABLE();
return string_builder;
}
}
template <class ImplT> template <class ImplT>
class QueryHandler { class QueryHandler {
public: public:
@ -290,6 +309,10 @@ class QueryHandler {
impl_.erase(query.key); impl_.erase(query.key);
query.tid = 1; query.tid = 1;
return; return;
case DbQuery::Type::EraseBatch:
impl_.erase_batch(query.erased_keys);
query.tid = 1;
return;
} }
} }
@ -314,6 +337,9 @@ class SeqQueryHandler {
case DbQuery::Type::Erase: case DbQuery::Type::Erase:
query.tid = impl_.erase(query.key); query.tid = impl_.erase(query.key);
return; return;
case DbQuery::Type::EraseBatch:
query.tid = impl_.erase_batch(query.erased_keys);
return;
} }
} }
@ -334,6 +360,12 @@ class SqliteKV {
kv_->get().erase(key); kv_->get().erase(key);
return 0; return 0;
} }
SeqNo erase_batch(td::vector<td::string> keys) {
for (auto &key : keys) {
kv_->get().erase(key);
}
return 0;
}
td::Status init(const td::string &name) { td::Status init(const td::string &name) {
auto sql_connection = std::make_shared<td::SqliteConnectionSafe>(name, td::DbKey::empty()); auto sql_connection = std::make_shared<td::SqliteConnectionSafe>(name, td::DbKey::empty());
kv_ = std::make_shared<td::SqliteKeyValueSafe>("kv", sql_connection); kv_ = std::make_shared<td::SqliteKeyValueSafe>("kv", sql_connection);
@ -360,6 +392,14 @@ class BaselineKV {
map_.erase(key); map_.erase(key);
return ++current_tid_; return ++current_tid_;
} }
SeqNo erase_batch(td::vector<td::string> keys) {
for (auto &key : keys) {
map_.erase(key);
}
SeqNo result = current_tid_ + 1;
current_tid_ += map_.size();
return result;
}
private: private:
std::map<td::string, td::string> map_; std::map<td::string, td::string> map_;
@ -380,9 +420,8 @@ TEST(DB, key_value) {
int queries_n = 1000; int queries_n = 1000;
td::vector<DbQuery> queries(queries_n); td::vector<DbQuery> queries(queries_n);
for (auto &q : queries) { for (auto &q : queries) {
int op = td::Random::fast(0, 2); int op = td::Random::fast(0, 3);
const auto &key = rand_elem(keys); const auto &key = rand_elem(keys);
const auto &value = rand_elem(values);
if (op == 0) { if (op == 0) {
q.type = DbQuery::Type::Get; q.type = DbQuery::Type::Get;
q.key = key; q.key = key;
@ -392,7 +431,13 @@ TEST(DB, key_value) {
} else if (op == 2) { } else if (op == 2) {
q.type = DbQuery::Type::Set; q.type = DbQuery::Type::Set;
q.key = key; q.key = key;
q.value = value; q.value = rand_elem(values);
} else if (op == 3) {
q.type = DbQuery::Type::EraseBatch;
q.erased_keys.resize(td::Random::fast(0, 3));
for (auto &erased_key : q.erased_keys) {
erased_key = rand_elem(keys);
}
} }
} }
@ -494,17 +539,22 @@ TEST(DB, thread_key_value) {
for (auto &q : qs) { for (auto &q : qs) {
int op = td::Random::fast(0, 10); int op = td::Random::fast(0, 10);
const auto &key = rand_elem(keys); const auto &key = rand_elem(keys);
const auto &value = rand_elem(values); if (op == 0) {
if (op > 1) {
q.type = DbQuery::Type::Get;
q.key = key;
} else if (op == 0) {
q.type = DbQuery::Type::Erase; q.type = DbQuery::Type::Erase;
q.key = key; q.key = key;
} else if (op == 1) { } else if (op == 1) {
q.type = DbQuery::Type::EraseBatch;
q.erased_keys.resize(td::Random::fast(0, 3));
for (auto &erased_key : q.erased_keys) {
erased_key = rand_elem(keys);
}
} else if (op <= 6) {
q.type = DbQuery::Type::Set; q.type = DbQuery::Type::Set;
q.key = key; q.key = key;
q.value = value; q.value = rand_elem(values);
} else {
q.type = DbQuery::Type::Get;
q.key = key;
} }
} }
} }
@ -606,17 +656,22 @@ TEST(DB, persistent_key_value) {
for (auto &q : qs) { for (auto &q : qs) {
int op = td::Random::fast(0, 10); int op = td::Random::fast(0, 10);
const auto &key = rand_elem(keys); const auto &key = rand_elem(keys);
const auto &value = rand_elem(values); if (op == 0) {
if (op > 1) {
q.type = DbQuery::Type::Get;
q.key = key;
} else if (op == 0) {
q.type = DbQuery::Type::Erase; q.type = DbQuery::Type::Erase;
q.key = key; q.key = key;
} else if (op == 1) { } else if (op == 1) {
q.type = DbQuery::Type::EraseBatch;
q.erased_keys.resize(td::Random::fast(0, 3));
for (auto &erased_key : q.erased_keys) {
erased_key = rand_elem(keys);
}
} else if (op <= 6) {
q.type = DbQuery::Type::Set; q.type = DbQuery::Type::Set;
q.key = key; q.key = key;
q.value = value; q.value = rand_elem(values);
} else {
q.type = DbQuery::Type::Get;
q.key = key;
} }
} }
} }
@ -718,6 +773,7 @@ TEST(DB, persistent_key_value) {
if (was) { if (was) {
continue; continue;
} }
LOG(DEBUG) << pos;
int best = -1; int best = -1;
SeqNo best_tid = 0; SeqNo best_tid = 0;
@ -728,6 +784,7 @@ TEST(DB, persistent_key_value) {
} }
was = true; was = true;
auto &q = res[i][p]; auto &q = res[i][p];
LOG(DEBUG) << i << ' ' << p << ' ' << q;
if (q.tid != 0) { if (q.tid != 0) {
if (best == -1 || q.tid < best_tid) { if (best == -1 || q.tid < best_tid) {
best = i; best = i;