From 9d16212401d2a738bf865d1e12ca42ffdfd37456 Mon Sep 17 00:00:00 2001 From: Joao Paulo Magalhaes Date: Sun, 12 May 2024 14:35:10 +0100 Subject: [PATCH] soa hierarchy wip --- src/c4/yml/detail/checks.hpp | 81 ++++--- src/c4/yml/tree.cpp | 429 +++++++++++++++++++---------------- src/c4/yml/tree.hpp | 95 ++++---- test/test_lib/test_case.cpp | 4 +- test/test_tree.cpp | 48 +++- 5 files changed, 347 insertions(+), 310 deletions(-) diff --git a/src/c4/yml/detail/checks.hpp b/src/c4/yml/detail/checks.hpp index d57b9645..a1cdad6f 100644 --- a/src/c4/yml/detail/checks.hpp +++ b/src/c4/yml/detail/checks.hpp @@ -34,11 +34,10 @@ inline void check_invariants(Tree const& t, id_type node) node = t.root_id(); } - NodeRelation const& n = t.m_relation[node]; #if defined(RYML_DBG) && 0 - if(n.m_first_child != NONE || n.m_last_child != NONE) + if(t.m_first_child[node] != NONE || t.m_last_child[node] != NONE) { - printf("check(%zu): fc=%zu lc=%zu\n", node, n.m_first_child, n.m_last_child); + printf("check(%zu): fc=%zu lc=%zu\n", node, t.m_first_child[node], t.m_last_child[node]); } else { @@ -46,78 +45,77 @@ inline void check_invariants(Tree const& t, id_type node) } #endif - C4_CHECK(n.m_parent != node); - if(n.m_parent == NONE) + C4_CHECK(t.m_parent[node] != node); + if(t.m_parent[node] == NONE) { C4_CHECK(t.is_root(node)); } - else //if(n.m_parent != NONE) + else //if(t.m_parent[node] != NONE) { - C4_CHECK(t.has_child(n.m_parent, node)); + C4_CHECK(t.has_child(t.m_parent[node], node)); - NodeRelation const& p = t.m_relation[n.m_parent]; - if(n.m_prev_sibling == NONE) + id_type p = t.m_parent[node]; + if(t.m_prev_sibling[node] == NONE) { - C4_CHECK(p.m_first_child == node); + C4_CHECK(t.m_first_child[p] == node); C4_CHECK(t.first_sibling(node) == node); } else { - C4_CHECK(p.m_first_child != node); + C4_CHECK(t.m_first_child[p] != node); C4_CHECK(t.first_sibling(node) != node); } - if(n.m_next_sibling == NONE) + if(t.m_next_sibling[node] == NONE) { - C4_CHECK(p.m_last_child == node); + C4_CHECK(t.m_last_child[p] == node); C4_CHECK(t.last_sibling(node) == node); } else { - C4_CHECK(p.m_last_child != node); + C4_CHECK(t.m_last_child[p] != node); C4_CHECK(t.last_sibling(node) != node); } } - C4_CHECK(n.m_first_child != node); - C4_CHECK(n.m_last_child != node); - if(n.m_first_child != NONE || n.m_last_child != NONE) + C4_CHECK(t.m_first_child[node] != node); + C4_CHECK(t.m_last_child[node] != node); + if(t.m_first_child[node] != NONE || t.m_last_child[node] != NONE) { - C4_CHECK(n.m_first_child != NONE); - C4_CHECK(n.m_last_child != NONE); + C4_CHECK(t.m_first_child[node] != NONE); + C4_CHECK(t.m_last_child[node] != NONE); } - C4_CHECK(n.m_prev_sibling != node); - C4_CHECK(n.m_next_sibling != node); - if(n.m_prev_sibling != NONE) + C4_CHECK(t.m_prev_sibling[node] != node); + C4_CHECK(t.m_next_sibling[node] != node); + if(t.m_prev_sibling[node] != NONE) { - C4_CHECK(t.m_relation[n.m_prev_sibling].m_next_sibling == node); - C4_CHECK(t.m_relation[n.m_prev_sibling].m_prev_sibling != node); + C4_CHECK(t.m_next_sibling[t.m_prev_sibling[node]] == node); + C4_CHECK(t.m_prev_sibling[t.m_prev_sibling[node]] != node); } - if(n.m_next_sibling != NONE) + if(t.m_next_sibling[node] != NONE) { - C4_CHECK(t.m_relation[n.m_next_sibling].m_prev_sibling == node); - C4_CHECK(t.m_relation[n.m_next_sibling].m_next_sibling != node); + C4_CHECK(t.m_prev_sibling[t.m_next_sibling[node]] == node); + C4_CHECK(t.m_next_sibling[t.m_next_sibling[node]] != node); } id_type count = 0; - for(id_type i = n.m_first_child; i != NONE; i = t.next_sibling(i)) + for(id_type i = t.m_first_child[node]; i != NONE; i = t.next_sibling(i)) { #if defined(RYML_DBG) && 0 printf("check(%zu): descend to child[%zu]=%zu\n", node, count, i); #endif - NodeRelation const& ch = t.m_relation[i]; - C4_CHECK(ch.m_parent == node); - C4_CHECK(ch.m_next_sibling != i); + C4_CHECK(t.m_parent[i] == node); + C4_CHECK(t.m_next_sibling[i] != i); ++count; } C4_CHECK(count == t.num_children(node)); - if(n.m_prev_sibling == NONE && n.m_next_sibling == NONE) + if(t.m_prev_sibling[node] == NONE && t.m_next_sibling[node] == NONE) { - if(n.m_parent != NONE) + if(t.m_parent[node] != NONE) { - C4_CHECK(t.num_children(n.m_parent) == 1); + C4_CHECK(t.num_children(t.m_parent[node]) == 1); C4_CHECK(t.num_siblings(node) == 1); } } @@ -153,19 +151,18 @@ inline void check_free_list(Tree const& t) C4_CHECK(t.m_free_head >= 0 && t.m_free_head < t.m_cap); C4_CHECK(t.m_free_tail >= 0 && t.m_free_tail < t.m_cap); - NodeRelation const& head = t.m_relation[t.m_free_head]; - //NodeRelation const& tail = t.m_relation[t.m_free_tail]; + id_type head = t.m_free_head; + //id_type tail = t.m_free_tail; - //C4_CHECK(head.m_prev_sibling == NONE); - //C4_CHECK(tail.m_next_sibling == NONE); + //C4_CHECK(m_prev_sibling[head] == NONE); + //C4_CHECK(m_next_sibling[tail] == NONE); id_type count = 0; - for(id_type i = t.m_free_head, prev = NONE; i != NONE; i = t.m_relation[i].m_next_sibling) + for(id_type i = t.m_free_head, prev = NONE; i != NONE; i = t.m_next_sibling[i]) { - NodeRelation const& elm = t.m_relation[i]; - if(&elm != &head) + if(i != head) { - C4_CHECK(elm.m_prev_sibling == prev); + C4_CHECK(t.m_prev_sibling[i] == prev); } prev = i; ++count; diff --git a/src/c4/yml/tree.cpp b/src/c4/yml/tree.cpp index 6800e127..5635c099 100644 --- a/src/c4/yml/tree.cpp +++ b/src/c4/yml/tree.cpp @@ -13,6 +13,7 @@ namespace c4 { namespace yml { #define _ryml_num_val_arrays (size_t(6u)) +#define _ryml_num_hcy_arrays (size_t(5u)) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -82,8 +83,8 @@ ConstNodeRef Tree::cdocref(id_type i) const //----------------------------------------------------------------------------- -// the tree's node data arrays are allocated all into a single buffer. -// these utilities help doing that. +// the tree's node data and hierarchy arrays are allocated all into a +// single buffer. these utilities help doing that. namespace { template bool _is_aligned(T const* ptr) @@ -108,9 +109,9 @@ struct node_buf_data size_for_val_align = _get_padding(size_for_type, alignof(csubstr)); val_start = size_for_type + size_for_val_align; size_for_val = _ryml_num_val_arrays * new_cap * sizeof(csubstr); - size_for_rel_align = _get_padding(val_start + size_for_val, alignof(NodeRelation)); + size_for_rel_align = _get_padding(val_start + size_for_val, alignof(id_type)); rel_start = val_start + size_for_val + size_for_rel_align; - size_for_rel = new_cap * sizeof(NodeRelation); + size_for_rel = _ryml_num_val_arrays * new_cap * sizeof(id_type); total_size = rel_start + size_for_rel; } size_t size_for_type; @@ -132,20 +133,28 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb, csubstr *C4_RESTRICT * m_key, csubstr *C4_RESTRICT * m_key_tag, csubstr *C4_RESTRICT * m_key_anchor, - NodeRelation *C4_RESTRICT * m_relation) + id_type *C4_RESTRICT * m_parent, + id_type *C4_RESTRICT * m_first_child, + id_type *C4_RESTRICT * m_last_child, + id_type *C4_RESTRICT * m_prev_sibling, + id_type *C4_RESTRICT * m_next_sibling) { _RYML_CB_ASSERT(cb, new_cap > 0); const node_buf_data newsz(new_cap); uint8_t *buf = _RYML_CB_ALLOC_HINT(cb, uint8_t, (size_t)newsz.total_size, *m_type); _RYML_CB_CHECK(cb, buf != nullptr); - NodeType *type = reinterpret_cast(buf); - csubstr *val = reinterpret_cast(buf + newsz.val_start); - csubstr *val_tag = reinterpret_cast(buf + newsz.val_start + 1 * new_cap * sizeof(csubstr)); - csubstr *val_anchor = reinterpret_cast(buf + newsz.val_start + 2 * new_cap * sizeof(csubstr)); - csubstr *key = reinterpret_cast(buf + newsz.val_start + 3 * new_cap * sizeof(csubstr)); - csubstr *key_tag = reinterpret_cast(buf + newsz.val_start + 4 * new_cap * sizeof(csubstr)); - csubstr *key_anchor = reinterpret_cast(buf + newsz.val_start + 5 * new_cap * sizeof(csubstr)); - NodeRelation *rel = reinterpret_cast(buf + newsz.rel_start); + NodeType *type = reinterpret_cast(buf); + csubstr *val = reinterpret_cast(buf + newsz.val_start); + csubstr *val_tag = reinterpret_cast(buf + newsz.val_start + 1 * new_cap * sizeof(csubstr)); + csubstr *val_anchor = reinterpret_cast(buf + newsz.val_start + 2 * new_cap * sizeof(csubstr)); + csubstr *key = reinterpret_cast(buf + newsz.val_start + 3 * new_cap * sizeof(csubstr)); + csubstr *key_tag = reinterpret_cast(buf + newsz.val_start + 4 * new_cap * sizeof(csubstr)); + csubstr *key_anchor = reinterpret_cast(buf + newsz.val_start + 5 * new_cap * sizeof(csubstr)); + id_type *parent = reinterpret_cast(buf + newsz.rel_start + 0 * new_cap * sizeof(id_type)); + id_type *first_child = reinterpret_cast(buf + newsz.rel_start + 1 * new_cap * sizeof(id_type)); + id_type *last_child = reinterpret_cast(buf + newsz.rel_start + 2 * new_cap * sizeof(id_type)); + id_type *prev_sibling = reinterpret_cast(buf + newsz.rel_start + 3 * new_cap * sizeof(id_type)); + id_type *next_sibling = reinterpret_cast(buf + newsz.rel_start + 4 * new_cap * sizeof(id_type)); _RYML_CB_ASSERT(cb, _is_aligned(type)); _RYML_CB_ASSERT(cb, _is_aligned(val)); _RYML_CB_ASSERT(cb, _is_aligned(val_tag)); @@ -153,7 +162,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb, _RYML_CB_ASSERT(cb, _is_aligned(key)); _RYML_CB_ASSERT(cb, _is_aligned(key_tag)); _RYML_CB_ASSERT(cb, _is_aligned(key_anchor)); - _RYML_CB_ASSERT(cb, _is_aligned(rel)); + _RYML_CB_ASSERT(cb, _is_aligned(parent)); + _RYML_CB_ASSERT(cb, _is_aligned(first_child)); + _RYML_CB_ASSERT(cb, _is_aligned(last_child)); + _RYML_CB_ASSERT(cb, _is_aligned(prev_sibling)); + _RYML_CB_ASSERT(cb, _is_aligned(next_sibling)); if(old_cap) { memcpy(type, *m_type, old_cap * sizeof(NodeType)); @@ -163,7 +176,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb, memcpy(key, *m_key, old_cap * sizeof(csubstr)); memcpy(key_tag, *m_key_tag, old_cap * sizeof(csubstr)); memcpy(key_anchor, *m_key_anchor, old_cap * sizeof(csubstr)); - memcpy(rel, *m_relation, old_cap * sizeof(NodeRelation)); + memcpy(parent, *m_parent, old_cap * sizeof(id_type)); + memcpy(first_child, *m_first_child, old_cap * sizeof(id_type)); + memcpy(last_child, *m_last_child, old_cap * sizeof(id_type)); + memcpy(prev_sibling, *m_prev_sibling, old_cap * sizeof(id_type)); + memcpy(next_sibling, *m_next_sibling, old_cap * sizeof(id_type)); const node_buf_data oldsz(old_cap); _RYML_CB_FREE(cb, *m_type, uint8_t, oldsz.total_size); } @@ -174,7 +191,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb, *m_key = key; *m_key_tag = key_tag; *m_key_anchor = key_anchor; - *m_relation = rel; + *m_parent = parent; + *m_first_child = first_child; + *m_last_child = last_child; + *m_prev_sibling = prev_sibling; + *m_next_sibling = next_sibling; } } // namespace @@ -188,7 +209,11 @@ Tree::Tree(Callbacks const& cb) , m_key(nullptr) , m_key_tag(nullptr) , m_key_anchor(nullptr) - , m_relation(nullptr) + , m_parent(nullptr) + , m_first_child(nullptr) + , m_last_child(nullptr) + , m_prev_sibling(nullptr) + , m_next_sibling(nullptr) , m_cap(0) , m_size(0) , m_free_head(NONE) @@ -244,7 +269,7 @@ void Tree::_free() if(m_type) // allocated for everything { _RYML_CB_ASSERT(m_callbacks, m_cap > 0); - const node_buf_data oldsz(m_cap); + const node_buf_data oldsz((size_t)m_cap); _RYML_CB_FREE(m_callbacks, m_type, uint8_t, oldsz.total_size); } if(m_arena.str) @@ -264,7 +289,11 @@ void Tree::_clear() m_key = nullptr; m_key_tag = nullptr; m_key_anchor = nullptr; - m_relation = nullptr; + m_parent = nullptr; + m_first_child = nullptr; + m_last_child = nullptr; + m_prev_sibling = nullptr; + m_next_sibling = nullptr; m_cap = 0; m_size = 0; m_free_head = 0; @@ -284,14 +313,18 @@ void Tree::_copy(Tree const& that) _RYML_CB_ASSERT(m_callbacks, m_key == nullptr); _RYML_CB_ASSERT(m_callbacks, m_key_tag == nullptr); _RYML_CB_ASSERT(m_callbacks, m_key_anchor == nullptr); - _RYML_CB_ASSERT(m_callbacks, m_relation == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_parent == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_first_child == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_last_child == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_next_sibling == nullptr); _RYML_CB_ASSERT(m_callbacks, m_arena.str == nullptr); _RYML_CB_ASSERT(m_callbacks, m_arena.len == 0); if(that.m_cap) { _resize_node_data(m_callbacks, - 0, - that.m_cap, + (size_t)0, + (size_t)that.m_cap, &m_type, &m_val, &m_val_tag, @@ -299,10 +332,14 @@ void Tree::_copy(Tree const& that) &m_key, &m_key_tag, &m_key_anchor, - &m_relation); + &m_parent, + &m_first_child, + &m_last_child, + &m_prev_sibling, + &m_next_sibling); memcpy(m_type, that.m_type, (size_t)that.m_cap * sizeof(NodeType)); - memcpy(m_val, that.m_val, (size_t)that.m_cap * _ryml_num_val_arrays * sizeof(csubstr)); - memcpy(m_relation, that.m_relation, (size_t)that.m_cap * sizeof(NodeRelation)); + memcpy(m_val, that.m_val, _ryml_num_val_arrays * (size_t)that.m_cap * sizeof(csubstr)); + memcpy(m_parent, that.m_parent, _ryml_num_hcy_arrays * (size_t)that.m_cap * sizeof(id_type)); m_cap = that.m_cap; m_size = that.m_size; m_free_head = that.m_free_head; @@ -332,7 +369,11 @@ void Tree::_move(Tree & that) noexcept _RYML_CB_ASSERT(m_callbacks, m_key == nullptr); _RYML_CB_ASSERT(m_callbacks, m_key_tag == nullptr); _RYML_CB_ASSERT(m_callbacks, m_key_anchor == nullptr); - _RYML_CB_ASSERT(m_callbacks, m_relation == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_parent == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_first_child == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_last_child == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling == nullptr); + _RYML_CB_ASSERT(m_callbacks, m_next_sibling == nullptr); _RYML_CB_ASSERT(m_callbacks, m_arena.str == nullptr); _RYML_CB_ASSERT(m_callbacks, m_arena.len == 0); m_type = that.m_type; @@ -342,7 +383,11 @@ void Tree::_move(Tree & that) noexcept m_key = that.m_key; m_key_tag = that.m_key_tag; m_key_anchor = that.m_key_anchor; - m_relation = that.m_relation; + m_parent = that.m_parent; + m_first_child = that.m_first_child; + m_last_child = that.m_last_child; + m_prev_sibling = that.m_prev_sibling; + m_next_sibling = that.m_next_sibling; m_cap = that.m_cap; m_size = that.m_size; m_free_head = that.m_free_head; @@ -407,7 +452,11 @@ void Tree::reserve(id_type cap) &m_key, &m_key_tag, &m_key_anchor, - &m_relation); + &m_parent, + &m_first_child, + &m_last_child, + &m_prev_sibling, + &m_next_sibling); id_type first = m_cap; id_type del = cap - m_cap; m_cap = cap; @@ -416,8 +465,8 @@ void Tree::reserve(id_type cap) { _RYML_CB_ASSERT(m_callbacks, m_val != nullptr); _RYML_CB_ASSERT(m_callbacks, m_free_tail != NONE); - m_relation[m_free_tail].m_next_sibling = first; - m_relation[first].m_prev_sibling = m_free_tail; + m_next_sibling[m_free_tail] = first; + m_prev_sibling[first] = m_free_tail; m_free_tail = cap-1; } else @@ -472,10 +521,10 @@ void Tree::_clear_range(id_type first, id_type num) for(id_type i = first, e = first + num; i < e; ++i) { _clear(i); - m_relation[i].m_prev_sibling = i - 1; - m_relation[i].m_next_sibling = i + 1; + m_prev_sibling[i] = i - 1; + m_next_sibling[i] = i + 1; } - m_relation[first + num - 1].m_next_sibling = NONE; + m_next_sibling[first + num - 1] = NONE; // we don't need to clear the node data } @@ -495,12 +544,11 @@ void Tree::_release(id_type i) void Tree::_free_list_add(id_type i) { _RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap); - NodeRelation &C4_RESTRICT w = m_relation[i]; - w.m_parent = NONE; - w.m_next_sibling = m_free_head; - w.m_prev_sibling = NONE; + m_parent[i] = NONE; + m_next_sibling[i] = m_free_head; + m_prev_sibling[i] = NONE; if(m_free_head != NONE) - m_relation[m_free_head].m_prev_sibling = i; + m_prev_sibling[m_free_head] = i; m_free_head = i; if(m_free_tail == NONE) m_free_tail = m_free_head; @@ -510,7 +558,7 @@ void Tree::_free_list_rem(id_type i) { _RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap); if(m_free_head == i) - m_free_head = m_relation[i].m_next_sibling; + m_free_head = m_next_sibling[i]; _rem_hierarchy(i); } @@ -528,7 +576,7 @@ id_type Tree::_claim() _RYML_CB_ASSERT(m_callbacks, m_free_head >= 0 && m_free_head < m_cap); const id_type ichild = m_free_head; ++m_size; - m_free_head = m_relation[ichild].m_next_sibling; + m_free_head = m_next_sibling[ichild]; if(m_free_head == NONE) { m_free_tail = NONE; @@ -553,52 +601,47 @@ C4_SUPPRESS_WARNING_GCC("-Wanalyzer-fd-leak") #endif #endif -void Tree::_set_hierarchy(id_type ichild, id_type iparent, id_type iprev_sibling) +void Tree::_set_hierarchy(id_type child, id_type parent, id_type iprev_sibling) { - _RYML_CB_ASSERT(m_callbacks, m_relation != nullptr); - _RYML_CB_ASSERT(m_callbacks, ichild >= 0 && ichild < m_cap); - _RYML_CB_ASSERT(m_callbacks, iparent == NONE || (iparent >= 0 && iparent < m_cap)); + _RYML_CB_ASSERT(m_callbacks, m_cap > 0); + _RYML_CB_ASSERT(m_callbacks, m_parent != nullptr); + _RYML_CB_ASSERT(m_callbacks, child >= 0 && child < m_cap); + _RYML_CB_ASSERT(m_callbacks, parent == NONE || (parent >= 0 && parent < m_cap)); _RYML_CB_ASSERT(m_callbacks, iprev_sibling == NONE || (iprev_sibling >= 0 && iprev_sibling < m_cap)); - NodeRelation *C4_RESTRICT child = &m_relation[ichild]; - child->m_parent = iparent; - child->m_prev_sibling = NONE; - child->m_next_sibling = NONE; - _RYML_CB_ASSERT(m_callbacks, iparent != NONE || ichild == 0); - _RYML_CB_ASSERT(m_callbacks, iparent != NONE || iprev_sibling == NONE); - if(iparent == NONE) + m_parent[child] = parent; + m_prev_sibling[child] = NONE; + m_next_sibling[child] = NONE; + _RYML_CB_ASSERT(m_callbacks, parent != NONE || child == 0); + _RYML_CB_ASSERT(m_callbacks, parent != NONE || iprev_sibling == NONE); + if(parent == NONE) return; - id_type inext_sibling = iprev_sibling != NONE ? next_sibling(iprev_sibling) : first_child(iparent); - NodeRelation *C4_RESTRICT psib = nullptr; - NodeRelation *C4_RESTRICT nsib = nullptr; + id_type inext_sibling = iprev_sibling != NONE ? next_sibling(iprev_sibling) : first_child(parent); if(iprev_sibling != NONE) { - psib = &m_relation[iprev_sibling]; _RYML_CB_ASSERT(m_callbacks, next_sibling(iprev_sibling) == inext_sibling); - child->m_prev_sibling = iprev_sibling; - psib->m_next_sibling = ichild; - _RYML_CB_ASSERT(m_callbacks, psib->m_prev_sibling != psib->m_next_sibling || psib->m_prev_sibling == NONE); + m_prev_sibling[child] = iprev_sibling; + m_next_sibling[iprev_sibling] = child; + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[iprev_sibling] != m_next_sibling[iprev_sibling] || m_prev_sibling[iprev_sibling] == NONE); } if(inext_sibling != NONE) { - nsib = &m_relation[inext_sibling]; _RYML_CB_ASSERT(m_callbacks, prev_sibling(inext_sibling) == iprev_sibling); - child->m_next_sibling = inext_sibling; - nsib->m_prev_sibling = ichild; - _RYML_CB_ASSERT(m_callbacks, nsib->m_prev_sibling != nsib->m_next_sibling || nsib->m_prev_sibling == NONE); + m_next_sibling[child] = inext_sibling; + m_prev_sibling[inext_sibling] = child; + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[inext_sibling] != m_next_sibling[inext_sibling] || m_prev_sibling[inext_sibling]); } - NodeRelation *C4_RESTRICT parent = &m_relation[iparent]; - if(parent->m_first_child != NONE) + if(m_first_child[parent] != NONE) { - if(child->m_next_sibling == parent->m_first_child) - parent->m_first_child = ichild; - if(child->m_prev_sibling == parent->m_last_child) - parent->m_last_child = ichild; + if(m_next_sibling[child] == m_first_child[parent]) + m_first_child[parent] = child; + if(m_prev_sibling[child] == m_last_child[parent]) + m_last_child[parent] = child; } else { - _RYML_CB_ASSERT(m_callbacks, parent->m_last_child == NONE); - parent->m_first_child = ichild; - parent->m_last_child = ichild; + _RYML_CB_ASSERT(m_callbacks, m_last_child[parent] == NONE); + m_first_child[parent] = child; + m_last_child[parent] = child; } } @@ -610,32 +653,20 @@ C4_SUPPRESS_WARNING_CLANG_POP void Tree::_rem_hierarchy(id_type i) { _RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap); - NodeRelation &C4_RESTRICT w = m_relation[i]; // remove from the parent - if(w.m_parent != NONE) + const id_type parent = m_parent[i]; + if(parent != NONE) { - NodeRelation &C4_RESTRICT p = m_relation[w.m_parent]; - if(p.m_first_child == i) - { - p.m_first_child = w.m_next_sibling; - } - if(p.m_last_child == i) - { - p.m_last_child = w.m_prev_sibling; - } + if(m_first_child[parent] == i) + m_first_child[parent] = m_next_sibling[i]; + if(m_last_child[parent] == i) + m_last_child[parent] = m_prev_sibling[i]; } - // remove from the used list - if(w.m_prev_sibling != NONE) - { - NodeRelation *C4_RESTRICT prev = &m_relation[w.m_prev_sibling]; - prev->m_next_sibling = w.m_next_sibling; - } - if(w.m_next_sibling != NONE) - { - NodeRelation *C4_RESTRICT next = &m_relation[w.m_next_sibling]; - next->m_prev_sibling = w.m_prev_sibling; - } + if(m_prev_sibling[i] != NONE) + m_next_sibling[m_prev_sibling[i]] = m_next_sibling[i]; + if(m_next_sibling[i] != NONE) + m_prev_sibling[m_next_sibling[i]] = m_prev_sibling[i]; } //----------------------------------------------------------------------------- @@ -701,153 +732,151 @@ void Tree::_swap(id_type n_, id_type m_) } //----------------------------------------------------------------------------- -void Tree::_swap_hierarchy(id_type ia, id_type ib) +void Tree::_swap_hierarchy(id_type a, id_type b) { - if(ia == ib) return; + if(a == b) return; - for(id_type i = first_child(ia); i != NONE; i = next_sibling(i)) + for(id_type i = first_child(a); i != NONE; i = next_sibling(i)) { - if(i == ib || i == ia) + if(i == b || i == a) continue; - m_relation[i].m_parent = ib; + m_parent[i] = b; } - for(id_type i = first_child(ib); i != NONE; i = next_sibling(i)) + for(id_type i = first_child(b); i != NONE; i = next_sibling(i)) { - if(i == ib || i == ia) + if(i == b || i == a) continue; - m_relation[i].m_parent = ia; + m_parent[i] = a; } - auto & C4_RESTRICT a = m_relation[ia]; - auto & C4_RESTRICT b = m_relation[ib]; - auto & C4_RESTRICT pa = m_relation[a.m_parent]; - auto & C4_RESTRICT pb = m_relation[b.m_parent]; + auto & C4_RESTRICT pa = m_parent[a]; + auto & C4_RESTRICT pb = m_parent[b]; - if(&pa == &pb) + if(pa == pb) { - if((pa.m_first_child == ib && pa.m_last_child == ia) + if((m_first_child[pa] == b && m_last_child[pa] == a) || - (pa.m_first_child == ia && pa.m_last_child == ib)) + (m_first_child[a] == a && m_last_child[pa] == b)) { - std::swap(pa.m_first_child, pa.m_last_child); + std::swap(m_first_child[pa], m_last_child[pa]); } else { bool changed = false; - if(pa.m_first_child == ia) + if(m_first_child[pa] == a) { - pa.m_first_child = ib; + m_first_child[pa] = b; changed = true; } - if(pa.m_last_child == ia) + if(m_last_child[pa] == a) { - pa.m_last_child = ib; + m_last_child[pa] = b; changed = true; } - if(pb.m_first_child == ib && !changed) + if(m_first_child[pb] == b && !changed) { - pb.m_first_child = ia; + m_first_child[pb] = a; } - if(pb.m_last_child == ib && !changed) + if(m_last_child[pb] == b && !changed) { - pb.m_last_child = ia; + m_last_child[pb] = a; } } } else { - if(pa.m_first_child == ia) - pa.m_first_child = ib; - if(pa.m_last_child == ia) - pa.m_last_child = ib; - if(pb.m_first_child == ib) - pb.m_first_child = ia; - if(pb.m_last_child == ib) - pb.m_last_child = ia; + if(m_first_child[pa] == a) + m_first_child[pa] = b; + if(m_last_child[pa] == a) + m_last_child[pa] = b; + if(m_first_child[pb] == b) + m_first_child[pb] = a; + if(m_last_child[pb] == b) + m_last_child[pb] = a; } - std::swap(a.m_first_child , b.m_first_child); - std::swap(a.m_last_child , b.m_last_child); + std::swap(m_first_child[a] , m_first_child[b]); + std::swap(m_last_child[a] , m_last_child[b]); - if(a.m_prev_sibling != ib && b.m_prev_sibling != ia && - a.m_next_sibling != ib && b.m_next_sibling != ia) + if(m_prev_sibling[a] != b && m_prev_sibling[b] != a && + m_next_sibling[a] != b && m_next_sibling[b] != a) { - if(a.m_prev_sibling != NONE && a.m_prev_sibling != ib) - m_relation[a.m_prev_sibling].m_next_sibling = ib; - if(a.m_next_sibling != NONE && a.m_next_sibling != ib) - m_relation[a.m_next_sibling].m_prev_sibling = ib; - if(b.m_prev_sibling != NONE && b.m_prev_sibling != ia) - m_relation[b.m_prev_sibling].m_next_sibling = ia; - if(b.m_next_sibling != NONE && b.m_next_sibling != ia) - m_relation[b.m_next_sibling].m_prev_sibling = ia; - std::swap(a.m_prev_sibling, b.m_prev_sibling); - std::swap(a.m_next_sibling, b.m_next_sibling); + if(m_prev_sibling[a] != NONE && m_prev_sibling[a] != b) + m_next_sibling[m_prev_sibling[a]] = b; + if(m_next_sibling[a] != NONE && m_next_sibling[a] != b) + m_prev_sibling[m_next_sibling[a]] = b; + if(m_prev_sibling[b] != NONE && m_prev_sibling[b] != a) + m_next_sibling[m_prev_sibling[b]] = a; + if(m_next_sibling[b] != NONE && m_next_sibling[b] != a) + m_prev_sibling[m_next_sibling[b]] = a; + std::swap(m_prev_sibling[a], m_prev_sibling[b]); + std::swap(m_next_sibling[a], m_next_sibling[b]); } else { - if(a.m_next_sibling == ib) // n will go after m + if(m_next_sibling[a] == b) // n will go after m { - _RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling == ia); - if(a.m_prev_sibling != NONE) + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] == a); + if(m_prev_sibling[a] != NONE) { - _RYML_CB_ASSERT(m_callbacks, a.m_prev_sibling != ib); - m_relation[a.m_prev_sibling].m_next_sibling = ib; + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[a] != b); + m_next_sibling[m_prev_sibling[a]] = b; } - if(b.m_next_sibling != NONE) + if(m_next_sibling[b] != NONE) { - _RYML_CB_ASSERT(m_callbacks, b.m_next_sibling != ia); - m_relation[b.m_next_sibling].m_prev_sibling = ia; + _RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] != a); + m_prev_sibling[m_next_sibling[b]] = a; } - id_type ns = b.m_next_sibling; - b.m_prev_sibling = a.m_prev_sibling; - b.m_next_sibling = ia; - a.m_prev_sibling = ib; - a.m_next_sibling = ns; + id_type ns = m_next_sibling[b]; + m_prev_sibling[b] = m_prev_sibling[a]; + m_next_sibling[b] = a; + m_prev_sibling[a] = b; + m_next_sibling[a] = ns; } - else if(a.m_prev_sibling == ib) // m will go after n + else if(m_prev_sibling[a] == b) // m will go after n { - _RYML_CB_ASSERT(m_callbacks, b.m_next_sibling == ia); - if(b.m_prev_sibling != NONE) + _RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] == a); + if(m_prev_sibling[b] != NONE) { - _RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling != ia); - m_relation[b.m_prev_sibling].m_next_sibling = ia; + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] != a); + m_next_sibling[m_prev_sibling[b]] = a; } - if(a.m_next_sibling != NONE) + if(m_next_sibling[a] != NONE) { - _RYML_CB_ASSERT(m_callbacks, a.m_next_sibling != ib); - m_relation[a.m_next_sibling].m_prev_sibling = ib; + _RYML_CB_ASSERT(m_callbacks, m_next_sibling[a] != b); + m_prev_sibling[m_next_sibling[a]] = b; } - id_type ns = b.m_prev_sibling; - a.m_prev_sibling = b.m_prev_sibling; - a.m_next_sibling = ib; - b.m_prev_sibling = ia; - b.m_next_sibling = ns; + id_type ns = m_prev_sibling[b]; + m_prev_sibling[a] = m_prev_sibling[b]; + m_next_sibling[a] = b; + m_prev_sibling[b] = a; + m_next_sibling[b] = ns; } else { C4_NEVER_REACH(); } } - _RYML_CB_ASSERT(m_callbacks, a.m_next_sibling != ia); - _RYML_CB_ASSERT(m_callbacks, a.m_prev_sibling != ia); - _RYML_CB_ASSERT(m_callbacks, b.m_next_sibling != ib); - _RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling != ib); + _RYML_CB_ASSERT(m_callbacks, m_next_sibling[a] != a); + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[a] != a); + _RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] != b); + _RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] != b); - if(a.m_parent != ib && b.m_parent != ia) + if(m_parent[a] != b && m_parent[b] != a) { - std::swap(a.m_parent, b.m_parent); + std::swap(m_parent[a], m_parent[b]); } else { - if(a.m_parent == ib && b.m_parent != ia) + if(m_parent[a] == b && m_parent[b] != a) { - a.m_parent = b.m_parent; - b.m_parent = ia; + m_parent[a] = m_parent[b]; + m_parent[b] = a; } - else if(a.m_parent != ib && b.m_parent == ia) + else if(m_parent[a] != b && m_parent[b] == a) { - b.m_parent = a.m_parent; - a.m_parent = ib; + m_parent[b] = m_parent[a]; + m_parent[a] = b; } else { @@ -859,34 +888,32 @@ void Tree::_swap_hierarchy(id_type ia, id_type ib) //----------------------------------------------------------------------------- void Tree::_copy_hierarchy(id_type dst_, id_type src_) { - auto const& C4_RESTRICT src = m_relation[src_]; - auto & C4_RESTRICT dst = m_relation[dst_]; - auto & C4_RESTRICT prt = m_relation[src.m_parent]; - for(id_type i = src.m_first_child; i != NONE; i = next_sibling(i)) + const id_type prt = m_parent[src_]; + for(id_type i = m_first_child[src_]; i != NONE; i = next_sibling(i)) { - m_relation[i].m_parent = dst_; + m_parent[i] = dst_; } - if(src.m_prev_sibling != NONE) + if(m_prev_sibling[src_] != NONE) { - m_relation[src.m_prev_sibling].m_next_sibling = dst_; + m_next_sibling[m_prev_sibling[src_]] = dst_; } - if(src.m_next_sibling != NONE) + if(m_next_sibling[src_] != NONE) { - m_relation[src.m_next_sibling].m_prev_sibling = dst_; + m_prev_sibling[m_next_sibling[src_]] = dst_; } - if(prt.m_first_child == src_) + if(m_first_child[prt] == src_) { - prt.m_first_child = dst_; + m_first_child[prt] = dst_; } - if(prt.m_last_child == src_) + if(m_last_child[prt] == src_) { - prt.m_last_child = dst_; + m_last_child[prt] = dst_; } - dst.m_parent = src.m_parent; - dst.m_first_child = src.m_first_child; - dst.m_last_child = src.m_last_child; - dst.m_prev_sibling = src.m_prev_sibling; - dst.m_next_sibling = src.m_next_sibling; + m_parent[dst_] = m_parent[src_]; + m_first_child[dst_] = m_first_child[src_]; + m_last_child[dst_] = m_last_child[src_]; + m_prev_sibling[dst_] = m_prev_sibling[src_]; + m_next_sibling[dst_] = m_next_sibling[src_]; } //----------------------------------------------------------------------------- @@ -981,14 +1008,14 @@ void Tree::set_root_as_stream() void Tree::remove_children(id_type node) { _ryml_chkid(node); - id_type ich = m_relation[node].m_first_child; + id_type ich = m_first_child[node]; while(ich != NONE) { remove_children(ich); _ryml_chkid(ich); - const id_type next = m_relation[ich].m_next_sibling; + const id_type next = m_next_sibling[ich]; _release(ich); - if(ich == m_relation[node].m_last_child) + if(ich == m_last_child[node]) break; ich = next; } @@ -1301,14 +1328,14 @@ id_type Tree::find_child(id_type node, csubstr const& name) const _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, node != NONE); _RYML_CB_ASSERT(m_callbacks, is_map(node)); - if(m_relation[node].m_first_child == NONE) + if(m_first_child[node] == NONE) { - _RYML_CB_ASSERT(m_callbacks, m_relation[node].m_last_child == NONE); + _RYML_CB_ASSERT(m_callbacks, m_last_child[node] == NONE); return NONE; } else { - _RYML_CB_ASSERT(m_callbacks, m_relation[node].m_last_child != NONE); + _RYML_CB_ASSERT(m_callbacks, m_last_child[node] != NONE); } for(id_type i = first_child(node); i != NONE; i = next_sibling(i)) { diff --git a/src/c4/yml/tree.hpp b/src/c4/yml/tree.hpp index e73d00c1..bf3a7359 100644 --- a/src/c4/yml/tree.hpp +++ b/src/c4/yml/tree.hpp @@ -200,22 +200,6 @@ public: }; -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - - -struct RYML_EXPORT NodeRelation -{ - id_type m_parent; - id_type m_first_child; - id_type m_last_child; - id_type m_next_sibling; - id_type m_prev_sibling; -}; -C4_MUST_BE_TRIVIAL_COPY(NodeRelation); - - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -367,8 +351,8 @@ public: C4_ALWAYS_INLINE bool is_val_ref(id_type node) const { _ryml_chkid(node); return m_type[node].is_val_ref(); } C4_ALWAYS_INLINE bool is_ref(id_type node) const { _ryml_chkid(node); return m_type[node].is_ref(); } - C4_ALWAYS_INLINE bool parent_is_seq(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_seq(m_relation[node].m_parent); } - C4_ALWAYS_INLINE bool parent_is_map(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_map(m_relation[node].m_parent); } + C4_ALWAYS_INLINE bool parent_is_seq(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_seq(m_parent[node]); } + C4_ALWAYS_INLINE bool parent_is_map(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_map(m_parent[node]); } /** true when the node has an anchor named a */ C4_ALWAYS_INLINE bool has_anchor(id_type node, csubstr a) const { _ryml_chkid(node); return ((m_type[node] & KEYANCH) && m_key_anchor[node] == a) || ((m_type[node] & VALANCH) && m_val_anchor[node] == a); } @@ -401,9 +385,9 @@ public: /** @name hierarchy predicates */ /** @{ */ - bool is_root(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, m_relation[node].m_parent != NONE || node == 0); return m_relation[node].m_parent == NONE; } + bool is_root(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, m_parent[node] != NONE || node == 0); return m_parent[node] == NONE; } - bool has_parent(id_type node) const { _ryml_chkid(node); return m_relation[node].m_parent != NONE; } + bool has_parent(id_type node) const { _ryml_chkid(node); return m_parent[node] != NONE; } /** true when key and val are empty, and has no children */ bool empty(id_type node) const @@ -414,26 +398,23 @@ public: } /** true if @p node has a child with id @p ch */ - bool has_child(id_type node, id_type ch) const { _ryml_chkid(node); return m_relation[ch].m_parent == node; } + bool has_child(id_type node, id_type ch) const { _ryml_chkid(node); return m_parent[ch] == node; } /** true if @p node has a child with key @p key */ bool has_child(id_type node, csubstr key) const { _ryml_chkid(node); return find_child(node, key) != NONE; } /** true if @p node has any children key */ - bool has_children(id_type node) const { _ryml_chkid(node); return m_relation[node].m_first_child != NONE; } + bool has_children(id_type node) const { _ryml_chkid(node); return m_first_child[node] != NONE; } /** true if @p node has a sibling with id @p sib */ - bool has_sibling(id_type node, id_type sib) const { _ryml_chkid(node); return m_relation[node].m_parent == m_relation[sib].m_parent; } + bool has_sibling(id_type node, id_type sib) const { _ryml_chkid(node); return m_parent[node] == m_parent[sib]; } /** true if one of the node's siblings has the given key */ bool has_sibling(id_type node, csubstr key) const { _ryml_chkid(node); return find_sibling(node, key) != NONE; } /** true if node is not a single child */ bool has_other_siblings(id_type node) const { _ryml_chkid(node); - NodeRelation const *C4_RESTRICT n = &m_relation[node]; - if(C4_LIKELY(n->m_parent != NONE)) - { - n = &m_relation[n->m_parent]; - return n->m_first_child != n->m_last_child; - } + const id_type parent = m_parent[node]; + if(C4_LIKELY(parent != NONE)) + return m_first_child[parent] != m_last_child[parent]; return false; } @@ -446,29 +427,29 @@ public: /** @name hierarchy getters */ /** @{ */ - id_type parent(id_type node) const { _ryml_chkid(node); return m_relation[node].m_parent; } + id_type parent(id_type node) const { _ryml_chkid(node); return m_parent[node]; } - id_type prev_sibling(id_type node) const { _ryml_chkid(node); return m_relation[node].m_prev_sibling; } - id_type next_sibling(id_type node) const { _ryml_chkid(node); return m_relation[node].m_next_sibling; } + id_type prev_sibling(id_type node) const { _ryml_chkid(node); return m_prev_sibling[node]; } + id_type next_sibling(id_type node) const { _ryml_chkid(node); return m_next_sibling[node]; } /** O(#num_children) */ id_type num_children(id_type node) const; id_type child_pos(id_type node, id_type ch) const; - id_type first_child(id_type node) const { _ryml_chkid(node); return m_relation[node].m_first_child; } - id_type last_child(id_type node) const { _ryml_chkid(node); return m_relation[node].m_last_child; } + id_type first_child(id_type node) const { _ryml_chkid(node); return m_first_child[node]; } + id_type last_child(id_type node) const { _ryml_chkid(node); return m_last_child[node]; } id_type child(id_type node, id_type pos) const; id_type find_child(id_type node, csubstr const& key) const; /** O(#num_siblings) */ /** counts with this */ - id_type num_siblings(id_type node) const { _ryml_chkid(node); return is_root(node) ? 1 : num_children(m_relation[node].m_parent); } + id_type num_siblings(id_type node) const { _ryml_chkid(node); return is_root(node) ? 1 : num_children(m_parent[node]); } /** does not count with this */ id_type num_other_siblings(id_type node) const { _ryml_chkid(node); id_type ns = num_siblings(node); _RYML_CB_ASSERT(m_callbacks, ns > 0); return ns-1; } - id_type sibling_pos(id_type node, id_type sib) const { _ryml_chkid(node); _ryml_chkid(sib); _RYML_CB_ASSERT(m_callbacks, ! is_root(node) || node == root_id()); return child_pos(m_relation[node].m_parent, sib); } - id_type first_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_relation[m_relation[node].m_parent].m_first_child; } - id_type last_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_relation[m_relation[node].m_parent].m_last_child; } - id_type sibling(id_type node, id_type pos) const { _ryml_chkid(node); return child(m_relation[node].m_parent, pos); } - id_type find_sibling(id_type node, csubstr const& key) const { _ryml_chkid(node); return find_child(m_relation[node].m_parent, key); } + id_type sibling_pos(id_type node, id_type sib) const { _ryml_chkid(node); _ryml_chkid(sib); _RYML_CB_ASSERT(m_callbacks, ! is_root(node) || node == root_id()); return child_pos(m_parent[node], sib); } + id_type first_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_first_child[m_parent[node]]; } + id_type last_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_last_child[m_parent[node]]; } + id_type sibling(id_type node, id_type pos) const { _ryml_chkid(node); return child(m_parent[node], pos); } + id_type find_sibling(id_type node, csubstr const& key) const { _ryml_chkid(node); return find_child(m_parent[node], key); } id_type doc(id_type i) const { id_type rid = root_id(); _RYML_CB_ASSERT(m_callbacks, is_stream(rid)); return child(rid, i); } //!< gets the @p i document node index. requires that the root node is a stream. @@ -646,7 +627,7 @@ public: { _RYML_CB_ASSERT(m_callbacks, parent != NONE); _RYML_CB_ASSERT(m_callbacks, is_container(parent) || is_root(parent)); - _RYML_CB_ASSERT(m_callbacks, after == NONE || (m_relation[after].m_parent == parent)); + _RYML_CB_ASSERT(m_callbacks, after == NONE || (m_parent[after] == parent)); id_type child = _claim(); _set_hierarchy(child, parent, after); return child; @@ -654,11 +635,11 @@ public: /** create and insert a node as the first child of @p parent */ C4_ALWAYS_INLINE id_type prepend_child(id_type parent) { return insert_child(parent, NONE); } /** create and insert a node as the last child of @p parent */ - C4_ALWAYS_INLINE id_type append_child(id_type parent) { return insert_child(parent, m_relation[parent].m_last_child); } + C4_ALWAYS_INLINE id_type append_child(id_type parent) { return insert_child(parent, m_last_child[parent]); } C4_ALWAYS_INLINE id_type _append_child__unprotected(id_type parent) { id_type child = _claim(); - _set_hierarchy(child, parent, m_relation[parent].m_last_child); + _set_hierarchy(child, parent, m_last_child[parent]); return child; } @@ -667,11 +648,11 @@ public: //! create and insert a new sibling of n. insert after "after" C4_ALWAYS_INLINE id_type insert_sibling(id_type node, id_type after) { - return insert_child(m_relation[node].m_parent, after); + return insert_child(m_parent[node], after); } /** create and insert a node as the first node of @p parent */ - C4_ALWAYS_INLINE id_type prepend_sibling(id_type node) { return prepend_child(m_relation[node].m_parent); } - C4_ALWAYS_INLINE id_type append_sibling(id_type node) { return append_child(m_relation[node].m_parent); } + C4_ALWAYS_INLINE id_type prepend_sibling(id_type node) { return prepend_child(m_parent[node]); } + C4_ALWAYS_INLINE id_type append_sibling(id_type node) { return append_child(m_parent[node]); } public: @@ -1076,12 +1057,6 @@ public: /** @cond dev*/ - id_type _id(NodeRelation const* C4_RESTRICT nr) const - { - _RYML_CB_ASSERT(m_callbacks, nr == nullptr || (nr >= m_relation && nr < m_relation + m_cap)); - return nr ? (id_type)(nr - m_relation) : NONE; - } - #if ! RYML_USE_ASSERT C4_ALWAYS_INLINE void _check_next_flags(id_type, type_bits) {} #else @@ -1176,7 +1151,7 @@ public: void _set_parent_as_container_if_needed(id_type node) { - id_type parent = m_relation[node].m_parent; + id_type parent = m_parent[node]; if(parent != NONE) { if( ! (is_seq(parent) || is_map(parent))) @@ -1279,9 +1254,9 @@ public: //m_val[node].clear(); //m_val_tag[node].clear(); //m_val_anchor[node].clear(); - m_relation[node].m_parent = NONE; - m_relation[node].m_first_child = NONE; - m_relation[node].m_last_child = NONE; + m_parent[node] = NONE; + m_first_child[node] = NONE; + m_last_child[node] = NONE; } inline void _clear_key(id_type node) @@ -1324,13 +1299,19 @@ public: // formerly NodeData NodeType *C4_RESTRICT m_type; + csubstr *C4_RESTRICT m_val; csubstr *C4_RESTRICT m_val_tag; csubstr *C4_RESTRICT m_val_anchor; csubstr *C4_RESTRICT m_key; csubstr *C4_RESTRICT m_key_tag; csubstr *C4_RESTRICT m_key_anchor; - NodeRelation *C4_RESTRICT m_relation; + + id_type *C4_RESTRICT m_parent; + id_type *C4_RESTRICT m_first_child; + id_type *C4_RESTRICT m_last_child; + id_type *C4_RESTRICT m_prev_sibling; + id_type *C4_RESTRICT m_next_sibling; id_type m_cap; id_type m_size; diff --git a/test/test_lib/test_case.cpp b/test/test_lib/test_case.cpp index 947f3681..bc59b0a5 100644 --- a/test/test_lib/test_case.cpp +++ b/test/test_lib/test_case.cpp @@ -562,7 +562,7 @@ size_t test_tree_invariants(ConstNodeRef const& n) ConstNodeRef parent = n.parent(); Tree const& t = *n.tree(); id_type id = n.id(); - if(t.m_relation[id].m_prev_sibling == NONE) + if(t.m_prev_sibling[id] == NONE) { if(parent.readable()) { @@ -570,7 +570,7 @@ size_t test_tree_invariants(ConstNodeRef const& n) } } - if(t.m_relation[id].m_next_sibling == NONE) + if(t.m_next_sibling[id] == NONE) { if(parent.readable()) { diff --git a/test/test_tree.cpp b/test/test_tree.cpp index 4fed8e8a..4e0269e3 100644 --- a/test/test_tree.cpp +++ b/test/test_tree.cpp @@ -867,7 +867,11 @@ TEST(Tree, reserve) csubstr const* m_key = t.m_key; csubstr const* m_key_tag = t.m_key_tag; csubstr const* m_key_anchor = t.m_key_anchor; - NodeRelation const* m_relation = t.m_relation; + id_type const* m_parent = t.m_parent; + id_type const* m_first_child = t.m_first_child; + id_type const* m_last_child = t.m_last_child; + id_type const* m_prev_sibling = t.m_prev_sibling; + id_type const* m_next_sibling = t.m_next_sibling; t.reserve(16); t.reserve_arena(64); EXPECT_EQ(t.m_type, m_type); @@ -877,7 +881,11 @@ TEST(Tree, reserve) EXPECT_EQ(t.m_key, m_key); EXPECT_EQ(t.m_key_tag, m_key_tag); EXPECT_EQ(t.m_key_anchor, m_key_anchor); - EXPECT_EQ(t.m_relation, m_relation); + EXPECT_EQ(t.m_parent, m_parent); + EXPECT_EQ(t.m_first_child, m_first_child); + EXPECT_EQ(t.m_last_child, m_last_child); + EXPECT_EQ(t.m_prev_sibling, m_prev_sibling); + EXPECT_EQ(t.m_next_sibling, m_next_sibling); EXPECT_EQ(t.capacity(), 16); EXPECT_EQ(t.slack(), 15); EXPECT_EQ(t.size(), 1); @@ -903,7 +911,11 @@ TEST(Tree, reserve) m_key = t.m_key; m_key_tag = t.m_key_tag; m_key_anchor = t.m_key_anchor; - m_relation = t.m_relation; + m_parent = t.m_parent; + m_first_child = t.m_first_child; + m_last_child = t.m_last_child; + m_prev_sibling = t.m_prev_sibling; + m_next_sibling = t.m_next_sibling; parse_in_arena("[a, b, c, d, e, f]", &t); EXPECT_EQ(t.m_type, m_type); EXPECT_EQ(t.m_val, m_val); @@ -912,7 +924,11 @@ TEST(Tree, reserve) EXPECT_EQ(t.m_key, m_key); EXPECT_EQ(t.m_key_tag, m_key_tag); EXPECT_EQ(t.m_key_anchor, m_key_anchor); - EXPECT_EQ(t.m_relation, m_relation); + EXPECT_EQ(t.m_parent, m_parent); + EXPECT_EQ(t.m_first_child, m_first_child); + EXPECT_EQ(t.m_last_child, m_last_child); + EXPECT_EQ(t.m_prev_sibling, m_prev_sibling); + EXPECT_EQ(t.m_next_sibling, m_next_sibling); EXPECT_EQ(t.capacity(), 32); EXPECT_EQ(t.slack(), 25); EXPECT_EQ(t.size(), 7); @@ -986,7 +1002,11 @@ TEST(Tree, clear) csubstr const* m_key = t.m_key; csubstr const* m_key_tag = t.m_key_tag; csubstr const* m_key_anchor = t.m_key_anchor; - NodeRelation const* m_relation = t.m_relation; + id_type const* m_parent = t.m_parent; + id_type const* m_first_child = t.m_first_child; + id_type const* m_last_child = t.m_last_child; + id_type const* m_prev_sibling = t.m_prev_sibling; + id_type const* m_next_sibling = t.m_next_sibling; t.reserve(16); t.reserve_arena(64); EXPECT_EQ(t.m_type, m_type); @@ -996,7 +1016,11 @@ TEST(Tree, clear) EXPECT_EQ(t.m_key, m_key); EXPECT_EQ(t.m_key_tag, m_key_tag); EXPECT_EQ(t.m_key_anchor, m_key_anchor); - EXPECT_EQ(t.m_relation, m_relation); + EXPECT_EQ(t.m_parent, m_parent); + EXPECT_EQ(t.m_first_child, m_first_child); + EXPECT_EQ(t.m_last_child, m_last_child); + EXPECT_EQ(t.m_prev_sibling, m_prev_sibling); + EXPECT_EQ(t.m_next_sibling, m_next_sibling); EXPECT_EQ(t.capacity(), 16); EXPECT_EQ(t.slack(), 15); EXPECT_EQ(t.size(), 1); @@ -1022,7 +1046,11 @@ TEST(Tree, clear) m_key = t.m_key; m_key_tag = t.m_key_tag; m_key_anchor = t.m_key_anchor; - m_relation = t.m_relation; + m_parent = t.m_parent; + m_first_child = t.m_first_child; + m_last_child = t.m_last_child; + m_prev_sibling = t.m_prev_sibling; + m_next_sibling = t.m_next_sibling; parse_in_arena("[a, b, c, d, e, f]", &t); EXPECT_EQ(t.m_type, m_type); EXPECT_EQ(t.m_val, m_val); @@ -1031,7 +1059,11 @@ TEST(Tree, clear) EXPECT_EQ(t.m_key, m_key); EXPECT_EQ(t.m_key_tag, m_key_tag); EXPECT_EQ(t.m_key_anchor, m_key_anchor); - EXPECT_EQ(t.m_relation, m_relation); + EXPECT_EQ(t.m_parent, m_parent); + EXPECT_EQ(t.m_first_child, m_first_child); + EXPECT_EQ(t.m_last_child, m_last_child); + EXPECT_EQ(t.m_prev_sibling, m_prev_sibling); + EXPECT_EQ(t.m_next_sibling, m_next_sibling); EXPECT_EQ(t.capacity(), 32); EXPECT_EQ(t.slack(), 25); EXPECT_EQ(t.size(), 7);