-
Notifications
You must be signed in to change notification settings - Fork 1.1k
WIP: Auto PostUpdate()
#2268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Auto PostUpdate()
#2268
Changes from 8 commits
1756663
0aa37fe
6cf66fb
fe6fbda
2a1f9e6
baef349
6a98bb3
9b969b9
510efe9
1c63e6e
c586960
175d5b0
d6dff27
28844dd
4c78f77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -278,17 +278,18 @@ OpResult<StringVec> OpScan(const OpArgs& op_args, std::string_view key, uint64_t | |
* of returning no or very few elements. (taken from redis code at db.c line 904 */ | ||
constexpr size_t INTERATION_FACTOR = 10; | ||
|
||
OpResult<PrimeIterator> find_res = op_args.shard->db_slice().Find(op_args.db_cntx, key, OBJ_HASH); | ||
OpResult<PrimeConstIterator> find_res = | ||
op_args.shard->db_slice().FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (!find_res) { | ||
DVLOG(1) << "ScanOp: find failed: " << find_res << ", baling out"; | ||
return find_res.status(); | ||
} | ||
|
||
PrimeIterator it = find_res.value(); | ||
PrimeConstIterator it = find_res.value(); | ||
StringVec res; | ||
uint32_t count = scan_op.limit * HASH_TABLE_ENTRIES_FACTOR; | ||
PrimeValue& pv = it->second; | ||
const PrimeValue& pv = it->second; | ||
|
||
if (pv.Encoding() == kEncodingListPack) { | ||
uint8_t* lp = (uint8_t*)pv.RObjPtr(); | ||
|
@@ -342,15 +343,14 @@ OpResult<uint32_t> OpDel(const OpArgs& op_args, string_view key, CmdArgList valu | |
DCHECK(!values.empty()); | ||
|
||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindMutable(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (!it_res) | ||
return it_res.status(); | ||
|
||
op_args.shard->search_indices()->RemoveDoc(key, op_args.db_cntx, (*it_res)->second); | ||
db_slice.PreUpdate(op_args.db_cntx.db_index, *it_res); | ||
PrimeValue& pv = it_res->it->second; | ||
op_args.shard->search_indices()->RemoveDoc(key, op_args.db_cntx, pv); | ||
|
||
PrimeValue& pv = (*it_res)->second; | ||
unsigned deleted = 0; | ||
bool key_remove = false; | ||
DbTableStats* stats = db_slice.MutableStats(op_args.db_cntx.db_index); | ||
|
@@ -387,7 +387,7 @@ OpResult<uint32_t> OpDel(const OpArgs& op_args, string_view key, CmdArgList valu | |
} | ||
} | ||
|
||
db_slice.PostUpdate(op_args.db_cntx.db_index, *it_res, key); | ||
it_res->post_updater.Run(); | ||
|
||
if (!key_remove) | ||
op_args.shard->search_indices()->AddDoc(key, op_args.db_cntx, pv); | ||
|
@@ -396,7 +396,7 @@ OpResult<uint32_t> OpDel(const OpArgs& op_args, string_view key, CmdArgList valu | |
if (enc == kEncodingListPack) { | ||
stats->listpack_blob_cnt--; | ||
} | ||
db_slice.Del(op_args.db_cntx.db_index, *it_res); | ||
db_slice.Del(op_args.db_cntx.db_index, it_res->it); | ||
} else if (enc == kEncodingListPack) { | ||
stats->listpack_bytes += lpBytes((uint8_t*)pv.RObjPtr()); | ||
} | ||
|
@@ -408,12 +408,12 @@ OpResult<vector<OptStr>> OpHMGet(const OpArgs& op_args, std::string_view key, Cm | |
DCHECK(!fields.empty()); | ||
|
||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (!it_res) | ||
return it_res.status(); | ||
|
||
PrimeValue& pv = (*it_res)->second; | ||
const PrimeValue& pv = (*it_res)->second; | ||
|
||
std::vector<OptStr> result(fields.size()); | ||
|
||
|
@@ -466,7 +466,7 @@ OpResult<vector<OptStr>> OpHMGet(const OpArgs& op_args, std::string_view key, Cm | |
|
||
OpResult<uint32_t> OpLen(const OpArgs& op_args, string_view key) { | ||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (it_res) { | ||
return HMapLength(op_args.db_cntx, (*it_res)->second); | ||
|
@@ -479,7 +479,7 @@ OpResult<uint32_t> OpLen(const OpArgs& op_args, string_view key) { | |
|
||
OpResult<int> OpExist(const OpArgs& op_args, string_view key, string_view field) { | ||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (!it_res) { | ||
if (it_res.status() == OpStatus::KEY_NOTFOUND) | ||
|
@@ -503,7 +503,7 @@ OpResult<int> OpExist(const OpArgs& op_args, string_view key, string_view field) | |
|
||
OpResult<string> OpGet(const OpArgs& op_args, string_view key, string_view field) { | ||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
if (!it_res) | ||
return it_res.status(); | ||
|
||
|
@@ -531,7 +531,7 @@ OpResult<string> OpGet(const OpArgs& op_args, string_view key, string_view field | |
|
||
OpResult<vector<string>> OpGetAll(const OpArgs& op_args, string_view key, uint8_t mask) { | ||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
if (!it_res) { | ||
if (it_res.status() == OpStatus::KEY_NOTFOUND) | ||
return vector<string>{}; | ||
|
@@ -582,7 +582,7 @@ OpResult<vector<string>> OpGetAll(const OpArgs& op_args, string_view key, uint8_ | |
|
||
OpResult<size_t> OpStrLen(const OpArgs& op_args, string_view key, string_view field) { | ||
auto& db_slice = op_args.shard->db_slice(); | ||
auto it_res = db_slice.Find(op_args.db_cntx, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(op_args.db_cntx, key, OBJ_HASH); | ||
|
||
if (!it_res) { | ||
if (it_res.status() == OpStatus::KEY_NOTFOUND) | ||
|
@@ -1062,7 +1062,7 @@ void HSetFamily::HRandField(CmdArgList args, ConnectionContext* cntx) { | |
auto cb = [&](Transaction* t, EngineShard* shard) -> OpResult<StringVec> { | ||
auto& db_slice = shard->db_slice(); | ||
DbContext db_context = t->GetDbContext(); | ||
auto it_res = db_slice.Find(db_context, key, OBJ_HASH); | ||
auto it_res = db_slice.FindReadOnly(db_context, key, OBJ_HASH); | ||
|
||
if (!it_res) | ||
return it_res.status(); | ||
|
@@ -1097,7 +1097,9 @@ void HSetFamily::HRandField(CmdArgList args, ConnectionContext* cntx) { | |
} | ||
|
||
if (string_map->Empty()) { | ||
db_slice.Del(db_context.db_index, *it_res); | ||
auto it_mutable = db_slice.FindMutable(db_context, key, OBJ_HASH); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its a change in this PR bu I am confused here. This is readonly command, and it can remove key from db.. does this makes sense? we should replicate a del command here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's the weirdness of our field expiration feature.. We should do it in all commands I guess, or better yet, implement it as a similar mechanism to expiration. Otherwise, an attempt to, say, set a string to what was previously a hash key will fail, despite it being empty. I'd say this is of low priority though (and also outside the scope here) |
||
it_mutable->post_updater.Run(); | ||
db_slice.Del(db_context.db_index, it_mutable->it); | ||
return facade::OpStatus::KEY_NOTFOUND; | ||
} | ||
} else if (pv.Encoding() == kEncodingListPack) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason you actually need this field is to clear it in the move constructor instead of dropping in an undefined state 🤔 Not handy, but I don't know any other solution instead of having a move-clearable flag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by a move-clearable flag?
(I don't see any issue with this implementation though..)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an interesting thought I had... So this example
will print
because moving an int is just copying it.... A move-clearable flag would behave like unique_ptr (but without the heap allocation). This way to don't need the nested struct, but can rely on default move constructor / operator to store "default" values in the moved-from object that can then be checked inside the destructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. Well, it's simpler currently :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not arguing, just if we or absl had this type, it'd be one line