refactor(furvm): use generational indexes for thing

Refs: #10
This commit is contained in:
2026-06-10 15:31:23 +02:00
parent d86f38d166
commit 26d77bdc02
3 changed files with 23 additions and 10 deletions
+6 -4
View File
@@ -5,6 +5,7 @@
#include "furvm/fwd.hpp" #include "furvm/fwd.hpp"
#include "furvm/module.hpp" #include "furvm/module.hpp"
#include <queue>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@@ -21,12 +22,12 @@ public:
/** /**
* @brief Move constructor. * @brief Move constructor.
*/ */
context(context&&) = default; context(context&&) noexcept = default;
/** /**
* @brief Move constructor. * @brief Move constructor.
*/ */
context& operator=(context&&) = default; context& operator=(context&&) noexcept = default;
context(const context&) = delete; context(const context&) = delete;
context& operator=(const context&) = delete; context& operator=(const context&) = delete;
@@ -97,8 +98,9 @@ private:
std::vector<thing_p> m_things; std::vector<thing_p> m_things;
std::vector<executor_p> m_executors; std::vector<executor_p> m_executors;
std::vector<void*> m_deadThings; std::queue<thing_handle> m_deadThings;
furlang::arena m_thingArena; std::vector<void*> m_deadThingData;
furlang::arena m_thingArena;
}; };
} // namespace furvm } // namespace furvm
+3 -1
View File
@@ -50,7 +50,7 @@ public:
const char* what() const noexcept override { return "bad thing access"; } const char* what() const noexcept override { return "bad thing access"; }
}; };
class thing { class thing final {
friend class executor; friend class executor;
private: private:
/** /**
@@ -61,6 +61,8 @@ private:
struct rzecz { struct rzecz {
explicit rzecz() = default; explicit rzecz() = default;
}; };
public:
static constexpr thing_handle GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */
public: public:
/** /**
* @brief Private constructor. * @brief Private constructor.
+14 -5
View File
@@ -21,12 +21,13 @@ thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context)
: m_id(id), m_type(type), m_context(context) { : m_id(id), m_type(type), m_context(context) {
std::size_t size = thing_type_size(type); std::size_t size = thing_type_size(type);
std::byte* data = nullptr; std::byte* data = nullptr;
if (!m_context->m_deadThings.empty()) { if (!m_context->m_deadThingData.empty()) {
thing_t itType{}; thing_t itType{};
for (auto it = m_context->m_deadThings.rbegin(); it != m_context->m_deadThings.rend(); ++it) { for (auto it = m_context->m_deadThingData.rbegin(); it != m_context->m_deadThingData.rend(); ++it) {
std::memcpy(&itType, static_cast<std::byte*>(*it) - sizeof(itType), sizeof(itType)); std::memcpy(&itType, static_cast<std::byte*>(*it) - sizeof(itType), sizeof(itType));
if (size == thing_type_size(itType)) { if (size == thing_type_size(itType)) {
data = static_cast<std::byte*>(*it); data = static_cast<std::byte*>(*it);
m_context->m_deadThingData.erase(std::next(it).base());
break; break;
} }
} }
@@ -40,12 +41,20 @@ thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context)
} }
thing::~thing() { thing::~thing() {
m_context->m_deadThings.push_back(m_data); m_context->m_deadThingData.push_back(m_data);
} }
thing_p thing::create(const context_p& context, thing_t type) { thing_p thing::create(const context_p& context, thing_t type) {
auto th = std::make_shared<thing>(rzecz{}, context->m_things.size(), type, context); thing_handle id = context->m_things.size();
context->m_things.push_back(th); if (!context->m_deadThings.empty()) {
id = context->m_deadThings.front();
context->m_deadThings.pop();
id += 1 << GENERATION_SIZE;
}
thing_handle idx = id & ((1ULL << ((sizeof(id) * 8) - GENERATION_SIZE)) - 1);
auto th = std::make_shared<thing>(rzecz{}, id, type, context);
context->m_things.emplace(context->m_things.begin() + idx, th);
return std::move(th); return std::move(th);
} }