1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-18 08:22:04 +00:00

util: various FixedMap fixes

This commit is contained in:
Michael Scire 2021-02-04 02:08:21 -08:00
parent c1d93a9495
commit a9c6476416
2 changed files with 74 additions and 49 deletions

View file

@ -33,8 +33,12 @@ namespace ams::util {
using TreeType = ::ams::util::FixedTree<KeyValuePair, LessTypeForMap, KeyValuePair, BufferAlignment>; using TreeType = ::ams::util::FixedTree<KeyValuePair, LessTypeForMap, KeyValuePair, BufferAlignment>;
using iterator = typename TreeType::Iterator; using iterator = typename TreeType::iterator;
using const_iterator = typename TreeType::ConstIterator; using const_iterator = typename TreeType::const_iterator;
public:
static constexpr size_t GetRequiredMemorySize(size_t num_elements) {
return TreeType::GetRequiredMemorySize(num_elements);
}
private: private:
TreeType m_tree; TreeType m_tree;
public: public:
@ -56,6 +60,8 @@ namespace ams::util {
ALWAYS_INLINE const_iterator find(const Key &key) const { const KeyValuePair pair(key, Value{}); return m_tree.find(pair); } ALWAYS_INLINE const_iterator find(const Key &key) const { const KeyValuePair pair(key, Value{}); return m_tree.find(pair); }
ALWAYS_INLINE std::pair<iterator, bool> insert(const KeyValuePair &pair) { return m_tree.insert(pair); } ALWAYS_INLINE std::pair<iterator, bool> insert(const KeyValuePair &pair) { return m_tree.insert(pair); }
ALWAYS_INLINE size_t size() const { return m_tree.size(); }
}; };
} }

View file

@ -64,7 +64,7 @@ namespace ams::util {
u32 _48; u32 _48;
u32 _4C; u32 _4C;
void InitializeHeader(u32 _08, s32 max_e, s32 cur_e, u32 ind_sig, u32 node_sz, u32 e_sz, u32 _30, u32 _34, u32 _38, u32 _3C, u32 _40, u32 _44) { void InitializeHeader(u32 _08, s32 max_e, s32 cur_e, u32 ind_sig, u32 buf_sz, u32 node_sz, u32 e_sz, u32 _30, u32 _34, u32 _38, u32 _3C, u32 _40, u32 _44) {
this->header_size = sizeof(Header); this->header_size = sizeof(Header);
this->header_signature = Signature; this->header_signature = Signature;
this->_08 = _08; this->_08 = _08;
@ -74,6 +74,7 @@ namespace ams::util {
this->left_most_index = Index_Nil; this->left_most_index = Index_Nil;
this->right_most_index = Index_Nil; this->right_most_index = Index_Nil;
this->index_signature = ind_sig; this->index_signature = ind_sig;
this->buffer_size = buf_sz;
this->node_size = node_sz; this->node_size = node_sz;
this->element_size = e_sz; this->element_size = e_sz;
this->_30 = _30; this->_30 = _30;
@ -111,12 +112,17 @@ namespace ams::util {
} }
}; };
class Iterator;
class ConstIterator;
class IteratorBase { class IteratorBase {
protected: private:
friend class ConstIterator;
private:
const FixedTree *m_this; const FixedTree *m_this;
int m_index; int m_index;
protected: protected:
constexpr IteratorBase(const FixedTree *tree, int index) : m_this(tree), m_index(index) { /* ... */ } constexpr ALWAYS_INLINE IteratorBase(const FixedTree *tree, int index) : m_this(tree), m_index(index) { /* ... */ }
constexpr bool IsEqualImpl(const IteratorBase &rhs) const { constexpr bool IsEqualImpl(const IteratorBase &rhs) const {
/* Validate pre-conditions. */ /* Validate pre-conditions. */
@ -144,11 +150,11 @@ namespace ams::util {
return m_this->m_nodes[m_index].m_data; return m_this->m_nodes[m_index].m_data;
} else { } else {
AMS_ASSERT(false); AMS_ASSERT(false);
return m_this->GetNode(std::numeric_limits<int>::max()).m_data; return m_this->GetNode(std::numeric_limits<int>::max())->m_data;
} }
} }
constexpr IteratorBase &IncrementImpl() { constexpr ALWAYS_INLINE IteratorBase &IncrementImpl() {
/* Validate pre-conditions. */ /* Validate pre-conditions. */
AMS_ASSERT(m_this); AMS_ASSERT(m_this);
@ -156,7 +162,7 @@ namespace ams::util {
return *this; return *this;
} }
constexpr IteratorBase &DecrementImpl() { constexpr ALWAYS_INLINE IteratorBase &DecrementImpl() {
/* Validate pre-conditions. */ /* Validate pre-conditions. */
AMS_ASSERT(m_this); AMS_ASSERT(m_this);
@ -191,60 +197,71 @@ namespace ams::util {
class Iterator : public IteratorBase { class Iterator : public IteratorBase {
public: public:
constexpr Iterator(const FixedTree &tree) : IteratorBase(std::addressof(tree), tree.size() ? tree.GetLMost() : Index_Leaf) { /* ... */ } constexpr ALWAYS_INLINE Iterator(const FixedTree &tree) : IteratorBase(std::addressof(tree), tree.size() ? tree.GetLMost() : Index_Leaf) { /* ... */ }
constexpr Iterator(const FixedTree &tree, int index) : IteratorBase(std::addressof(tree), index) { /* ... */ } constexpr ALWAYS_INLINE Iterator(const FixedTree &tree, int index) : IteratorBase(std::addressof(tree), index) { /* ... */ }
constexpr Iterator(const Iterator &rhs) = default; constexpr ALWAYS_INLINE Iterator(const Iterator &rhs) = default;
constexpr bool operator==(const Iterator &rhs) const { constexpr ALWAYS_INLINE bool operator==(const Iterator &rhs) const {
return this->IsEqualImpl(rhs); return this->IsEqualImpl(rhs);
} }
constexpr bool operator!=(const Iterator &rhs) const { constexpr ALWAYS_INLINE bool operator!=(const Iterator &rhs) const {
return !(*this == rhs); return !(*this == rhs);
} }
constexpr IteratorMember &operator*() const { constexpr ALWAYS_INLINE IteratorMember &operator*() const {
return static_cast<IteratorMember &>(this->DereferenceImpl()); return static_cast<IteratorMember &>(this->DereferenceImpl());
} }
constexpr Iterator &operator++() { constexpr ALWAYS_INLINE IteratorMember *operator->() const {
return std::addressof(this->operator *());
}
constexpr ALWAYS_INLINE Iterator &operator++() {
return static_cast<Iterator &>(this->IncrementImpl()); return static_cast<Iterator &>(this->IncrementImpl());
} }
constexpr Iterator &operator--() { constexpr ALWAYS_INLINE Iterator &operator--() {
return static_cast<Iterator &>(this->DecrementImpl()); return static_cast<Iterator &>(this->DecrementImpl());
} }
}; };
class ConstIterator : public IteratorBase { class ConstIterator : public IteratorBase {
public: public:
constexpr ConstIterator(const FixedTree &tree) : IteratorBase(std::addressof(tree), tree.size() ? tree.GetLMost() : Index_Leaf) { /* ... */ } constexpr ALWAYS_INLINE ConstIterator(const FixedTree &tree) : IteratorBase(std::addressof(tree), tree.size() ? tree.GetLMost() : Index_Leaf) { /* ... */ }
constexpr ConstIterator(const FixedTree &tree, int index) : IteratorBase(std::addressof(tree), index) { /* ... */ } constexpr ALWAYS_INLINE ConstIterator(const FixedTree &tree, int index) : IteratorBase(std::addressof(tree), index) { /* ... */ }
constexpr ConstIterator(const ConstIterator &rhs) = default; constexpr ALWAYS_INLINE ConstIterator(const ConstIterator &rhs) = default;
constexpr ConstIterator(const Iterator &rhs) : IteratorBase(rhs.m_this, rhs.m_index) { /* ... */ } constexpr ALWAYS_INLINE ConstIterator(const Iterator &rhs) : IteratorBase(rhs.m_this, rhs.m_index) { /* ... */ }
constexpr bool operator==(const ConstIterator &rhs) const { constexpr ALWAYS_INLINE bool operator==(const ConstIterator &rhs) const {
return this->IsEqualImpl(rhs); return this->IsEqualImpl(rhs);
} }
constexpr bool operator!=(const ConstIterator &rhs) const { constexpr ALWAYS_INLINE bool operator!=(const ConstIterator &rhs) const {
return !(*this == rhs); return !(*this == rhs);
} }
constexpr const IteratorMember &operator*() const { constexpr ALWAYS_INLINE const IteratorMember &operator*() const {
return static_cast<const IteratorMember &>(this->DereferenceImpl()); return static_cast<const IteratorMember &>(this->DereferenceImpl());
} }
constexpr ConstIterator &operator++() { constexpr ALWAYS_INLINE const IteratorMember *operator->() const {
return std::addressof(this->operator *());
}
constexpr ALWAYS_INLINE ConstIterator &operator++() {
return static_cast<ConstIterator &>(this->IncrementImpl()); return static_cast<ConstIterator &>(this->IncrementImpl());
} }
constexpr ConstIterator &operator--() { constexpr ALWAYS_INLINE ConstIterator &operator--() {
return static_cast<ConstIterator &>(this->DecrementImpl()); return static_cast<ConstIterator &>(this->DecrementImpl());
} }
}; };
public:
using iterator = Iterator;
using const_iterator = ConstIterator;
private: private:
impl::AvailableIndexFinder m_index_finder; impl::AvailableIndexFinder m_index_finder;
Node m_dummy_leaf; Node m_dummy_leaf;
@ -252,7 +269,7 @@ namespace ams::util {
u8 *m_buffer; u8 *m_buffer;
Header *m_header; Header *m_header;
Node *m_nodes; Node *m_nodes;
Iterator m_end_iterator; iterator m_end_iterator;
public: public:
FixedTree() : m_end_iterator(*this, Index_Nil) { FixedTree() : m_end_iterator(*this, Index_Nil) {
this->SetDummyMemory(); this->SetDummyMemory();
@ -304,7 +321,7 @@ namespace ams::util {
m_header->InitializeHeader(1, num_elements, 0, signature, buffer_size, sizeof(Node), sizeof(Member), 4, 4, 4, 4, 4, BufferAlignment); m_header->InitializeHeader(1, num_elements, 0, signature, buffer_size, sizeof(Node), sizeof(Member), 4, 4, 4, 4, 4, BufferAlignment);
/* Setup index finder. */ /* Setup index finder. */
m_index_finder.Initialize(std::addressof(m_header->max_elements), std::addressof(m_header->cur_elements), m_buffer + sizeof(*m_header) + SizeOfNodes(num_elements)); m_index_finder.Initialize(std::addressof(m_header->cur_elements), std::addressof(m_header->max_elements), m_buffer + sizeof(*m_header) + SizeOfNodes(num_elements));
/* Set nodes array. */ /* Set nodes array. */
m_nodes = reinterpret_cast<Node *>(m_buffer + sizeof(*m_header)); m_nodes = reinterpret_cast<Node *>(m_buffer + sizeof(*m_header));
@ -349,7 +366,7 @@ namespace ams::util {
void ReleaseIndex(int index) { return m_index_finder.ReleaseIndex(index); } void ReleaseIndex(int index) { return m_index_finder.ReleaseIndex(index); }
int EraseByIndex(int target_index) { int EraseByIndex(int target_index) {
/* Seutp tracking variables. */ /* Setup tracking variables. */
const auto next_index = this->UncheckedPP(target_index); const auto next_index = this->UncheckedPP(target_index);
auto *target_node = this->GetNode(target_index); auto *target_node = this->GetNode(target_index);
@ -559,13 +576,13 @@ namespace ams::util {
return target_index; return target_index;
} }
int FindIndex(const Member &elem) { int FindIndex(const Member &elem) const {
return this->FindIndexSub(this->GetRoot(), elem); return this->FindIndexSub(this->GetRoot(), elem);
} }
int FindIndexSub(int index, const Member &elem) { int FindIndexSub(int index, const Member &elem) const {
if (index != Index_Nil) { if (index != Index_Nil) {
auto *node = this->GetNode(elem); auto *node = this->GetNode(index);
if (Compare{}(elem, node->m_data)) { if (Compare{}(elem, node->m_data)) {
if (!this->IsLeaf(node->m_left)) { if (!this->IsLeaf(node->m_left)) {
return this->FindIndexSub(node->m_left, elem); return this->FindIndexSub(node->m_left, elem);
@ -610,7 +627,7 @@ namespace ams::util {
node->m_parent = parent; node->m_parent = parent;
node->m_right = Index_Leaf; node->m_right = Index_Leaf;
node->m_left = Index_Leaf; node->m_left = Index_Leaf;
std::memcpy(std::addressof(node->m_data), std::addressof(elem), sizeof(elem)); std::memcpy(reinterpret_cast<u8 *>(std::addressof(node->m_data)), reinterpret_cast<const u8 *>(std::addressof(elem)), sizeof(node->m_data));
/* Fix up the parent node. */ /* Fix up the parent node. */
auto *parent_node = this->GetNode(parent); auto *parent_node = this->GetNode(parent);
@ -641,7 +658,7 @@ namespace ams::util {
p_node->m_color = Color::Black; p_node->m_color = Color::Black;
gr_node->m_color = Color::Black; gr_node->m_color = Color::Black;
g_node->m_color = Color::Red; g_node->m_color = Color::Red;
AMS_ASSERT(m_p_dummy_leaf->color != Color::Red); AMS_ASSERT(m_p_dummy_leaf->m_color != Color::Red);
cur_index = p_node->m_parent; cur_index = p_node->m_parent;
continue; continue;
@ -659,7 +676,7 @@ namespace ams::util {
g_node = this->GetNode(p_node->m_parent); g_node = this->GetNode(p_node->m_parent);
g_node->m_color = Color::Red; g_node->m_color = Color::Red;
AMS_ASSERT(m_p_dummy_leaf->color != Color::Red); AMS_ASSERT(m_p_dummy_leaf->m_color != Color::Red);
this->RotateRight(p_node->m_parent); this->RotateRight(p_node->m_parent);
} else { } else {
@ -667,7 +684,7 @@ namespace ams::util {
p_node->m_color = Color::Black; p_node->m_color = Color::Black;
gl_node->m_color = Color::Black; gl_node->m_color = Color::Black;
g_node->m_color = Color::Red; g_node->m_color = Color::Red;
AMS_ASSERT(m_p_dummy_leaf->color != Color::Red); AMS_ASSERT(m_p_dummy_leaf->m_color != Color::Red);
cur_index = p_node->m_parent; cur_index = p_node->m_parent;
continue; continue;
@ -685,7 +702,7 @@ namespace ams::util {
g_node = this->GetNode(p_node->m_parent); g_node = this->GetNode(p_node->m_parent);
g_node->m_color = Color::Red; g_node->m_color = Color::Red;
AMS_ASSERT(m_p_dummy_leaf->color != Color::Red); AMS_ASSERT(m_p_dummy_leaf->m_color != Color::Red);
this->RotateLeft(p_node->m_parent); this->RotateLeft(p_node->m_parent);
} }
@ -703,6 +720,7 @@ namespace ams::util {
bool less = true; bool less = true;
while (cur_index != Index_Nil && cur_index != Index_Leaf) { while (cur_index != Index_Nil && cur_index != Index_Leaf) {
auto *node = this->GetNode(cur_index); auto *node = this->GetNode(cur_index);
prev_index = cur_index;
if (before) { if (before) {
less = Compare{}(node->m_data, elem); less = Compare{}(node->m_data, elem);
@ -725,7 +743,7 @@ namespace ams::util {
node->m_parent = Index_Nil; node->m_parent = Index_Nil;
node->m_right = Index_Leaf; node->m_right = Index_Leaf;
node->m_left = Index_Leaf; node->m_left = Index_Leaf;
std::memcpy(std::addressof(node->m_data), std::addressof(elem), sizeof(elem)); std::memcpy(reinterpret_cast<u8 *>(std::addressof(node->m_data)), reinterpret_cast<const u8 *>(std::addressof(elem)), sizeof(node->m_data));
this->SetRoot(index); this->SetRoot(index);
this->SetLMost(index); this->SetLMost(index);
@ -813,7 +831,7 @@ namespace ams::util {
node->SetRight(r_index, r_node, index); node->SetRight(r_index, r_node, index);
} }
int UncheckedMM(int index) { int UncheckedMM(int index) const {
auto *node = this->GetNode(index); auto *node = this->GetNode(index);
if (this->IsNil(index)) { if (this->IsNil(index)) {
index = this->GetRMost(); index = this->GetRMost();
@ -844,7 +862,7 @@ namespace ams::util {
} }
} }
int UncheckedPP(int index) { int UncheckedPP(int index) const {
auto *node = this->GetNode(index); auto *node = this->GetNode(index);
if (!this->IsNil(index)) { if (!this->IsNil(index)) {
@ -879,11 +897,11 @@ namespace ams::util {
return this->InitializeImpl(static_cast<int>(num_elements), buffer, buffer_size); return this->InitializeImpl(static_cast<int>(num_elements), buffer, buffer_size);
} }
Iterator begin() { return Iterator(*this); } iterator begin() { return iterator(*this); }
ConstIterator begin() const { return ConstIterator(*this); } const_iterator begin() const { return const_iterator(*this); }
Iterator end() { return m_end_iterator; } iterator end() { return m_end_iterator; }
ConstIterator end() const { return m_end_iterator; } const_iterator end() const { return m_end_iterator; }
size_t size() const { return m_header->cur_elements; } size_t size() const { return m_header->cur_elements; }
@ -905,25 +923,25 @@ namespace ams::util {
} }
} }
Iterator find(const Member &elem) { iterator find(const Member &elem) {
if (const auto index = this->FindIndex(elem); index >= 0) { if (const auto index = this->FindIndex(elem); index >= 0) {
return Iterator(*this, index); return iterator(*this, index);
} else { } else {
return this->end(); return this->end();
} }
} }
ConstIterator find(const Member &elem) const { const_iterator find(const Member &elem) const {
if (const auto index = this->FindIndex(elem); index >= 0) { if (const auto index = this->FindIndex(elem); index >= 0) {
return Iterator(*this, index); return const_iterator(*this, index);
} else { } else {
return this->end(); return this->end();
} }
} }
std::pair<Iterator, bool> insert(const Member &elem) { std::pair<iterator, bool> insert(const Member &elem) {
const auto index = this->InsertNoHint(false, elem); const auto index = this->InsertNoHint(false, elem);
const auto it = Iterator(*this, index); const auto it = iterator(*this, index);
return std::make_pair(it, !this->IsNil(index)); return std::make_pair(it, !this->IsNil(index));
} }
@ -970,6 +988,7 @@ namespace ams::util {
cur_node = this->GetNode(cur_index); cur_node = this->GetNode(cur_index);
} }
AMS_UNUSED(min_node);
return IndexPair{min_index, max_index}; return IndexPair{min_index, max_index};
} }
}; };