123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- #ifndef REALM_NODE_HPP
- #define REALM_NODE_HPP
- #include <realm/node_header.hpp>
- #include <realm/alloc.hpp>
- namespace realm {
- class Mixed;
- const size_t npos = size_t(-1);
- const size_t not_found = npos;
- class ArrayParent {
- public:
- virtual ~ArrayParent() noexcept {}
- virtual ref_type get_child_ref(size_t child_ndx) const noexcept = 0;
- virtual void update_child_ref(size_t child_ndx, ref_type new_ref) = 0;
- };
- class Node : public NodeHeader {
- public:
-
- char* m_data = nullptr;
-
-
- explicit Node(Allocator& allocator) noexcept
- : m_alloc(allocator)
- {
- }
- virtual ~Node() {}
-
-
-
- char* init_from_mem(MemRef mem) noexcept
- {
- char* header = mem.get_addr();
- m_ref = mem.get_ref();
- m_data = get_data_from_header(header);
- m_size = get_size_from_header(header);
- return header;
- }
-
- bool is_attached() const noexcept
- {
- return m_data != nullptr;
- }
- inline bool is_read_only() const noexcept
- {
- REALM_ASSERT_DEBUG(is_attached());
- return m_alloc.is_read_only(m_ref);
- }
- size_t size() const noexcept
- {
- REALM_ASSERT_DEBUG(is_attached());
- return m_size;
- }
- bool is_empty() const noexcept
- {
- return size() == 0;
- }
- ref_type get_ref() const noexcept
- {
- return m_ref;
- }
- MemRef get_mem() const noexcept
- {
- return MemRef(get_header_from_data(m_data), m_ref, m_alloc);
- }
- Allocator& get_alloc() const noexcept
- {
- return m_alloc;
- }
-
- char* get_header() const noexcept
- {
- return get_header_from_data(m_data);
- }
- bool has_parent() const noexcept
- {
- return m_parent != nullptr;
- }
- ArrayParent* get_parent() const noexcept
- {
- return m_parent;
- }
- size_t get_ndx_in_parent() const noexcept
- {
- return m_ndx_in_parent;
- }
- bool has_missing_parent_update() const noexcept
- {
- return m_missing_parent_update;
- }
-
-
-
- ref_type get_ref_from_parent() const noexcept
- {
- REALM_ASSERT_DEBUG(m_parent);
- ref_type ref = m_parent->get_child_ref(m_ndx_in_parent);
- return ref;
- }
-
-
-
- void detach() noexcept
- {
- m_data = nullptr;
- }
-
-
-
-
- void destroy() noexcept
- {
- if (!is_attached())
- return;
- char* header = get_header_from_data(m_data);
- m_alloc.free_(m_ref, header);
- m_data = nullptr;
- }
-
- static void destroy(ref_type ref, Allocator& alloc) noexcept
- {
- destroy(MemRef(ref, alloc), alloc);
- }
-
-
- static void destroy(MemRef mem, Allocator& alloc) noexcept
- {
- alloc.free_(mem);
- }
-
-
-
-
-
- void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept
- {
- m_parent = parent;
- m_ndx_in_parent = ndx_in_parent;
- }
- void set_ndx_in_parent(size_t ndx) noexcept
- {
- m_ndx_in_parent = ndx;
- }
- void clear_missing_parent_update()
- {
- m_missing_parent_update = false;
- }
-
-
-
- void update_parent()
- {
- if (m_parent) {
- m_parent->update_child_ref(m_ndx_in_parent, m_ref);
- }
- else {
- m_missing_parent_update = true;
- }
- }
- protected:
-
-
- static const size_t initial_capacity = 128;
- size_t m_ref;
- Allocator& m_alloc;
- size_t m_size = 0;
- #if REALM_ENABLE_MEMDEBUG
-
-
-
- bool m_no_relocation = false;
- #endif
- void alloc(size_t init_size, size_t new_width);
- void copy_on_write()
- {
- #if REALM_ENABLE_MEMDEBUG
-
-
-
-
- if (!m_no_relocation) {
- #else
- if (is_read_only()) {
- #endif
- do_copy_on_write();
- }
- }
- void copy_on_write(size_t min_size)
- {
- #if REALM_ENABLE_MEMDEBUG
-
-
-
-
- if (!m_no_relocation) {
- #else
- if (is_read_only()) {
- #endif
- do_copy_on_write(min_size);
- }
- }
- void ensure_size(size_t min_size)
- {
- char* header = get_header_from_data(m_data);
- size_t orig_capacity_bytes = get_capacity_from_header(header);
- if (orig_capacity_bytes < min_size) {
- do_copy_on_write(min_size);
- }
- }
- static MemRef create_node(size_t size, Allocator& alloc, bool context_flag = false, Type type = type_Normal,
- WidthType width_type = wtype_Ignore, int width = 1);
- void set_header_size(size_t value) noexcept
- {
- set_size_in_header(value, get_header());
- }
-
- virtual size_t calc_byte_len(size_t num_items, size_t width) const;
- virtual size_t calc_item_count(size_t bytes, size_t width) const noexcept;
- static void init_header(char* header, bool is_inner_bptree_node, bool has_refs, bool context_flag,
- WidthType width_type, int width, size_t size, size_t capacity) noexcept;
- private:
- ArrayParent* m_parent = nullptr;
- size_t m_ndx_in_parent = 0;
- bool m_missing_parent_update = false;
- void do_copy_on_write(size_t minimum_size = 0);
- };
- class Spec;
- class Mixed;
- class ArrayPayload {
- public:
- virtual ~ArrayPayload();
- virtual void init_from_ref(ref_type) noexcept = 0;
- virtual void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept = 0;
- virtual Mixed get_any(size_t ndx) const = 0;
- virtual bool need_spec() const
- {
- return false;
- }
- virtual void set_spec(Spec*, size_t) const {}
- };
- inline void Node::init_header(char* header, bool is_inner_bptree_node, bool has_refs, bool context_flag,
- WidthType width_type, int width, size_t size, size_t capacity) noexcept
- {
-
-
-
- std::fill(header, header + header_size, 0);
- set_is_inner_bptree_node_in_header(is_inner_bptree_node, header);
- set_hasrefs_in_header(has_refs, header);
- set_context_flag_in_header(context_flag, header);
- set_wtype_in_header(width_type, header);
- set_width_in_header(width, header);
- set_size_in_header(size, header);
- set_capacity_in_header(capacity, header);
- }
- }
- #endif
|