mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
refactor: return OpResult in DbSlice::AddOrFind instead of throwing std::bad_alloc (#2427)
* return OpResult in AddOrFind instead of throwing bad_alloc * small refactor
This commit is contained in:
parent
1074bcb30b
commit
517be2005e
16 changed files with 209 additions and 213 deletions
|
@ -14,6 +14,7 @@ extern "C" {
|
|||
#include "base/logging.h"
|
||||
#include "generic_family.h"
|
||||
#include "server/engine_shard_set.h"
|
||||
#include "server/error.h"
|
||||
#include "server/journal/journal.h"
|
||||
#include "server/server_state.h"
|
||||
#include "server/tiered_storage.h"
|
||||
|
@ -536,16 +537,17 @@ OpResult<pair<PrimeConstIterator, unsigned>> DbSlice::FindFirstReadOnly(const Co
|
|||
return OpStatus::KEY_NOTFOUND;
|
||||
}
|
||||
|
||||
DbSlice::AddOrFindResult DbSlice::AddOrFind(const Context& cntx, string_view key) {
|
||||
OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrFind(const Context& cntx, string_view key) {
|
||||
return AddOrFindInternal(cntx, key, LoadExternalMode::kDontLoad);
|
||||
}
|
||||
|
||||
DbSlice::AddOrFindResult DbSlice::AddOrFindAndFetch(const Context& cntx, string_view key) {
|
||||
OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrFindAndFetch(const Context& cntx,
|
||||
string_view key) {
|
||||
return AddOrFindInternal(cntx, key, LoadExternalMode::kLoad);
|
||||
}
|
||||
|
||||
DbSlice::AddOrFindResult DbSlice::AddOrFindInternal(const Context& cntx, string_view key,
|
||||
LoadExternalMode load_mode) noexcept(false) {
|
||||
OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrFindInternal(const Context& cntx, string_view key,
|
||||
LoadExternalMode load_mode) {
|
||||
DCHECK(IsDbValid(cntx.db_index));
|
||||
|
||||
DbTable& db = *db_arr_[cntx.db_index];
|
||||
|
@ -553,16 +555,18 @@ DbSlice::AddOrFindResult DbSlice::AddOrFindInternal(const Context& cntx, string_
|
|||
|
||||
if (res.ok()) {
|
||||
PreUpdate(cntx.db_index, res->it);
|
||||
return {.it = res->it,
|
||||
.exp_it = res->exp_it,
|
||||
.is_new = false,
|
||||
.post_updater = AutoUpdater({.action = AutoUpdater::DestructorAction::kRun,
|
||||
.db_slice = this,
|
||||
.db_ind = cntx.db_index,
|
||||
.it = res->it,
|
||||
.key = key})};
|
||||
return DbSlice::AddOrFindResult{
|
||||
.it = res->it,
|
||||
.exp_it = res->exp_it,
|
||||
.is_new = false,
|
||||
.post_updater = AutoUpdater({.action = AutoUpdater::DestructorAction::kRun,
|
||||
.db_slice = this,
|
||||
.db_ind = cntx.db_index,
|
||||
.it = res->it,
|
||||
.key = key})};
|
||||
}
|
||||
CHECK_EQ(res.status(), OpStatus::KEY_NOTFOUND);
|
||||
auto status = res.status();
|
||||
CHECK(status == OpStatus::KEY_NOTFOUND || status == OpStatus::OUT_OF_MEMORY) << status;
|
||||
|
||||
// It's a new entry.
|
||||
DVLOG(2) << "Running callbacks for key " << key << " in dbid " << cntx.db_index;
|
||||
|
@ -592,7 +596,7 @@ DbSlice::AddOrFindResult DbSlice::AddOrFindInternal(const Context& cntx, string_
|
|||
if (apply_memory_limit && !caching_mode_ && evp.mem_budget() < 0) {
|
||||
VLOG(2) << "AddOrFind: over limit, budget: " << evp.mem_budget();
|
||||
events_.insertion_rejections++;
|
||||
throw bad_alloc();
|
||||
return OpStatus::OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Fast-path if change_cb_ is empty so we Find or Add using
|
||||
|
@ -606,8 +610,7 @@ DbSlice::AddOrFindResult DbSlice::AddOrFindInternal(const Context& cntx, string_
|
|||
} catch (bad_alloc& e) {
|
||||
VLOG(2) << "AddOrFind2: bad alloc exception, budget: " << evp.mem_budget();
|
||||
events_.insertion_rejections++;
|
||||
|
||||
throw e;
|
||||
return OpStatus::OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
size_t evicted_obj_bytes = 0;
|
||||
|
@ -639,14 +642,15 @@ DbSlice::AddOrFindResult DbSlice::AddOrFindInternal(const Context& cntx, string_
|
|||
db.slots_stats[sid].key_count += 1;
|
||||
}
|
||||
|
||||
return {.it = it,
|
||||
.exp_it = ExpireIterator{},
|
||||
.is_new = true,
|
||||
.post_updater = AutoUpdater({.action = AutoUpdater::DestructorAction::kRun,
|
||||
.db_slice = this,
|
||||
.db_ind = cntx.db_index,
|
||||
.it = it,
|
||||
.key = key})};
|
||||
return DbSlice::AddOrFindResult{
|
||||
.it = it,
|
||||
.exp_it = ExpireIterator{},
|
||||
.is_new = true,
|
||||
.post_updater = AutoUpdater({.action = AutoUpdater::DestructorAction::kRun,
|
||||
.db_slice = this,
|
||||
.db_ind = cntx.db_index,
|
||||
.it = it,
|
||||
.key = key})};
|
||||
}
|
||||
|
||||
void DbSlice::ActivateDb(DbIndex db_ind) {
|
||||
|
@ -824,12 +828,15 @@ uint32_t DbSlice::GetMCFlag(DbIndex db_ind, const PrimeKey& key) const {
|
|||
return it->second;
|
||||
}
|
||||
|
||||
DbSlice::ItAndUpdater DbSlice::AddNew(const Context& cntx, string_view key, PrimeValue obj,
|
||||
uint64_t expire_at_ms) noexcept(false) {
|
||||
auto res = AddOrUpdateInternal(cntx, key, std::move(obj), expire_at_ms, false);
|
||||
OpResult<DbSlice::ItAndUpdater> DbSlice::AddNew(const Context& cntx, string_view key,
|
||||
PrimeValue obj, uint64_t expire_at_ms) {
|
||||
auto op_result = AddOrUpdateInternal(cntx, key, std::move(obj), expire_at_ms, false);
|
||||
RETURN_ON_BAD_STATUS(op_result);
|
||||
auto& res = *op_result;
|
||||
CHECK(res.is_new);
|
||||
|
||||
return {.it = res.it, .exp_it = res.exp_it, .post_updater = std::move(res.post_updater)};
|
||||
return DbSlice::ItAndUpdater{
|
||||
.it = res.it, .exp_it = res.exp_it, .post_updater = std::move(res.post_updater)};
|
||||
}
|
||||
|
||||
pair<int64_t, int64_t> DbSlice::ExpireParams::Calculate(int64_t now_ms) const {
|
||||
|
@ -882,14 +889,19 @@ OpResult<int64_t> DbSlice::UpdateExpire(const Context& cntx, PrimeIterator prime
|
|||
}
|
||||
}
|
||||
|
||||
DbSlice::AddOrFindResult DbSlice::AddOrUpdateInternal(const Context& cntx, std::string_view key,
|
||||
PrimeValue obj, uint64_t expire_at_ms,
|
||||
bool force_update) noexcept(false) {
|
||||
OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrUpdateInternal(const Context& cntx,
|
||||
std::string_view key,
|
||||
PrimeValue obj,
|
||||
uint64_t expire_at_ms,
|
||||
bool force_update) {
|
||||
DCHECK(!obj.IsRef());
|
||||
|
||||
auto res = AddOrFind(cntx, key);
|
||||
auto op_result = AddOrFind(cntx, key);
|
||||
RETURN_ON_BAD_STATUS(op_result);
|
||||
|
||||
auto& res = *op_result;
|
||||
if (!res.is_new && !force_update) // have not inserted.
|
||||
return res;
|
||||
return op_result;
|
||||
|
||||
auto& db = *db_arr_[cntx.db_index];
|
||||
auto& it = res.it;
|
||||
|
@ -906,11 +918,11 @@ DbSlice::AddOrFindResult DbSlice::AddOrUpdateInternal(const Context& cntx, std::
|
|||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return op_result;
|
||||
}
|
||||
|
||||
DbSlice::AddOrFindResult DbSlice::AddOrUpdate(const Context& cntx, string_view key, PrimeValue obj,
|
||||
uint64_t expire_at_ms) noexcept(false) {
|
||||
OpResult<DbSlice::AddOrFindResult> DbSlice::AddOrUpdate(const Context& cntx, string_view key,
|
||||
PrimeValue obj, uint64_t expire_at_ms) {
|
||||
return AddOrUpdateInternal(cntx, key, std::move(obj), expire_at_ms, true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue