haze: improve object database API

This commit is contained in:
Liam 2023-04-16 15:02:52 -04:00
commit 9c922e4774
2 changed files with 37 additions and 36 deletions

View file

@ -23,19 +23,20 @@ namespace haze {
struct PtpObject {
public:
util::IntrusiveRedBlackTreeNode m_object_name_to_id_node;
util::IntrusiveRedBlackTreeNode m_object_id_to_name_node;
util::IntrusiveRedBlackTreeNode m_name_node;
util::IntrusiveRedBlackTreeNode m_object_id_node;
u32 m_parent_id;
u32 m_object_id;
char m_name[];
public:
explicit PtpObject(char *name, u32 parent_id, u32 object_id) : m_object_name_to_id_node(), m_object_id_to_name_node(), m_parent_id(parent_id), m_object_id(object_id) { /* ... */ }
const char *GetName() const { return m_name; }
u32 GetParentId() const { return m_parent_id; }
u32 GetObjectId() const { return m_object_id; }
public:
bool GetIsRegistered() const { return m_object_id != 0; }
void Register(u32 object_id) { m_object_id = object_id; }
void Unregister() { m_object_id = 0; }
public:
struct NameComparator {
struct RedBlackKeyType {
const char *m_name;
@ -73,18 +74,18 @@ namespace haze {
class PtpObjectDatabase {
private:
using ObjectNameToIdTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_object_name_to_id_node>;
using ObjectNameToIdTree = ObjectNameToIdTreeTraits::TreeType<PtpObject::NameComparator>;
using ObjectNameTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_name_node>;
using ObjectNameTree = ObjectNameTreeTraits::TreeType<PtpObject::NameComparator>;
using ObjectIdToNameTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_object_id_to_name_node>;
using ObjectIdToNameTree = ObjectIdToNameTreeTraits::TreeType<PtpObject::IdComparator>;
using ObjectIdTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_object_id_node>;
using ObjectIdTree = ObjectIdTreeTraits::TreeType<PtpObject::IdComparator>;
PtpObjectHeap *m_object_heap;
ObjectNameToIdTree m_name_to_object_id;
ObjectIdToNameTree m_object_id_to_name;
ObjectNameTree m_name_tree;
ObjectIdTree m_object_id_tree;
u32 m_next_object_id;
public:
constexpr explicit PtpObjectDatabase() : m_object_heap(), m_name_to_object_id(), m_object_id_to_name(), m_next_object_id() { /* ... */ }
constexpr explicit PtpObjectDatabase() : m_object_heap(), m_name_tree(), m_object_id_tree(), m_next_object_id() { /* ... */ }
void Initialize(PtpObjectHeap *object_heap);
void Finalize();

View file

@ -21,15 +21,15 @@ namespace haze {
m_object_heap = object_heap;
m_object_heap->Initialize();
std::construct_at(std::addressof(m_name_to_object_id));
std::construct_at(std::addressof(m_object_id_to_name));
std::construct_at(std::addressof(m_name_tree));
std::construct_at(std::addressof(m_object_id_tree));
m_next_object_id = 1;
}
void PtpObjectDatabase::Finalize() {
std::destroy_at(std::addressof(m_object_id_to_name));
std::destroy_at(std::addressof(m_name_to_object_id));
std::destroy_at(std::addressof(m_object_id_tree));
std::destroy_at(std::addressof(m_name_tree));
m_next_object_id = 0;
@ -47,30 +47,30 @@ namespace haze {
const size_t terminator_len = 1;
const size_t alloc_len = sizeof(PtpObject) + parent_name_len + separator_len + name_len + terminator_len;
/* Allocate memory for the node. */
/* Allocate memory for the object. */
PtpObject * const object = m_object_heap->Allocate<PtpObject>(alloc_len);
R_UNLESS(object != nullptr, haze::ResultOutOfMemory());
/* Build the object name. */
std::strncpy(object->m_name, parent_name, parent_name_len + terminator_len);
std::strncpy(object->m_name + parent_name_len, separator, separator_len + terminator_len);
std::strncpy(object->m_name + parent_name_len + separator_len, name, name_len + terminator_len);
{
/* Ensure we maintain a clean state on failure. */
auto guard = SCOPE_GUARD { m_object_heap->Deallocate(object, alloc_len); };
/* Take ownership of the name. */
std::strncpy(object->m_name, parent_name, parent_name_len + terminator_len);
std::strncpy(object->m_name + parent_name_len, separator, separator_len + terminator_len);
std::strncpy(object->m_name + parent_name_len + separator_len, name, name_len + terminator_len);
/* Check if an object with this name already exists. If it does, we can just return it here. */
if (auto * const existing = this->GetObjectByName(object->GetName()); existing != nullptr) {
*out_object = existing;
R_SUCCEED();
}
/* Persist the reference to the node. */
/* Persist the reference to the object. */
guard.Cancel();
}
/* Set node properties. */
/* Set object properties. */
object->m_parent_id = parent_id;
object->m_object_id = 0;
@ -92,10 +92,10 @@ namespace haze {
desired_id = m_next_object_id++;
}
/* Insert node into trees. */
object->m_object_id = desired_id;
m_name_to_object_id.insert(*object);
m_object_id_to_name.insert(*object);
/* Insert object into trees. */
object->Register(desired_id);
m_object_id_tree.insert(*object);
m_name_tree.insert(*object);
}
void PtpObjectDatabase::UnregisterObject(PtpObject *object) {
@ -104,10 +104,10 @@ namespace haze {
return;
}
/* Remove node from trees. */
m_object_id_to_name.erase(m_object_id_to_name.iterator_to(*object));
m_name_to_object_id.erase(m_name_to_object_id.iterator_to(*object));
object->m_object_id = 0;
/* Remove object from trees. */
m_object_id_tree.erase(m_object_id_tree.iterator_to(*object));
m_name_tree.erase(m_name_tree.iterator_to(*object));
object->Unregister();
}
void PtpObjectDatabase::DeleteObject(PtpObject *object) {
@ -134,8 +134,8 @@ namespace haze {
PtpObject *PtpObjectDatabase::GetObjectById(u32 object_id) {
/* Find in ID mapping. */
auto it = m_object_id_to_name.find_key(object_id);
if (it == m_object_id_to_name.end()) {
auto it = m_object_id_tree.find_key(object_id);
if (it == m_object_id_tree.end()) {
return nullptr;
}
@ -144,8 +144,8 @@ namespace haze {
PtpObject *PtpObjectDatabase::GetObjectByName(const char *name) {
/* Find in name mapping. */
auto it = m_name_to_object_id.find_key(name);
if (it == m_name_to_object_id.end()) {
auto it = m_name_tree.find_key(name);
if (it == m_name_tree.end()) {
return nullptr;
}