add meta_slot, xpop_slot

This commit is contained in:
tequ
2025-09-29 12:25:41 +09:00
parent 27e4e4b510
commit a62bac3fcd
3 changed files with 110 additions and 86 deletions

View File

@@ -4586,30 +4586,12 @@ DEFINE_HOOK_FUNCTION(int64_t, meta_slot, uint32_t slot_into)
{
HOOK_SETUP();
if (!hookCtx.result.provisionalMeta)
return PREREQUISITE_NOT_MET;
hook::HookAPI api(hookCtx);
auto const result = api.meta_slot(slot_into);
if (!result)
return result.error();
if (slot_into > hook_api::max_slots)
return INVALID_ARGUMENT;
// check if we can emplace the object to a slot
if (slot_into == 0 && no_free_slots(hookCtx))
return NO_FREE_SLOTS;
if (slot_into == 0)
{
if (auto found = get_free_slot(hookCtx); found)
slot_into = *found;
else
return NO_FREE_SLOTS;
}
hookCtx.slot[slot_into] =
hook::SlotEntry{.storage = hookCtx.result.provisionalMeta, .entry = 0};
hookCtx.slot[slot_into].entry = &(*hookCtx.slot[slot_into].storage);
return slot_into;
return result.value();
HOOK_TEARDOWN();
}
@@ -4622,66 +4604,12 @@ DEFINE_HOOK_FUNCTION(
{
HOOK_SETUP();
if (applyCtx.tx.getFieldU16(sfTransactionType) != ttIMPORT)
return PREREQUISITE_NOT_MET;
hook::HookAPI api(hookCtx);
auto const result = api.xpop_slot(slot_into_tx, slot_into_meta);
if (!result)
return result.error();
if (slot_into_tx > hook_api::max_slots ||
slot_into_meta > hook_api::max_slots)
return INVALID_ARGUMENT;
size_t free_count = hook_api::max_slots - hookCtx.slot.size();
size_t needed_count = slot_into_tx == 0 && slot_into_meta == 0
? 2
: slot_into_tx != 0 && slot_into_meta != 0 ? 0 : 1;
if (free_count < needed_count)
return NO_FREE_SLOTS;
// if they supply the same slot number for both (other than 0)
// they will produce a collision
if (needed_count == 0 && slot_into_tx == slot_into_meta)
return INVALID_ARGUMENT;
if (slot_into_tx == 0)
{
if (no_free_slots(hookCtx))
return NO_FREE_SLOTS;
if (auto found = get_free_slot(hookCtx); found)
slot_into_tx = *found;
else
return NO_FREE_SLOTS;
}
if (slot_into_meta == 0)
{
if (no_free_slots(hookCtx))
return NO_FREE_SLOTS;
if (auto found = get_free_slot(hookCtx); found)
slot_into_meta = *found;
else
return NO_FREE_SLOTS;
}
auto [tx, meta] = Import::getInnerTxn(applyCtx.tx, j);
if (!tx || !meta)
return INVALID_TXN;
hookCtx.slot[slot_into_tx] =
hook::SlotEntry{.storage = std::move(tx), .entry = 0};
hookCtx.slot[slot_into_tx].entry = &(*hookCtx.slot[slot_into_tx].storage);
hookCtx.slot[slot_into_meta] =
hook::SlotEntry{.storage = std::move(meta), .entry = 0};
hookCtx.slot[slot_into_meta].entry =
&(*hookCtx.slot[slot_into_meta].storage);
return (slot_into_tx << 16U) + slot_into_meta;
return std::get<0>(result.value()) << 16U | std::get<1>(result.value());
HOOK_TEARDOWN();
}