diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/serd/node.h | 5 | ||||
-rw-r--r-- | include/serd/nodes.h | 88 | ||||
-rw-r--r-- | include/serd/serd.h | 8 |
3 files changed, 100 insertions, 1 deletions
diff --git a/include/serd/node.h b/include/serd/node.h index d140e4c0..8dbdbde4 100644 --- a/include/serd/node.h +++ b/include/serd/node.h @@ -120,7 +120,7 @@ typedef uint32_t SerdNodeFlags; Arguments constructors like #serd_a_file_uri return a temporary view of their arguments, which can be passed (usually inline) to node construction - functions like #serd_node_new, or #serd_node_construct. + functions like #serd_node_new, #serd_node_construct, or #serd_nodes_get. @{ */ @@ -413,6 +413,9 @@ serd_node_construct(size_t buf_size, void* ZIX_NULLABLE buf, SerdNodeArgs args); nodes with an allocator. The returned nodes must be freed with serd_node_free() using the same allocator. + Note that in most cases it is better to use a #SerdNodes instead of managing + individual node allocations. + @{ */ diff --git a/include/serd/nodes.h b/include/serd/nodes.h new file mode 100644 index 00000000..c23fe024 --- /dev/null +++ b/include/serd/nodes.h @@ -0,0 +1,88 @@ +// Copyright 2011-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef SERD_NODES_H +#define SERD_NODES_H + +#include "serd/attributes.h" +#include "serd/memory.h" +#include "serd/node.h" +#include "zix/attributes.h" + +#include <stddef.h> + +SERD_BEGIN_DECLS + +/** + @defgroup serd_nodes Nodes + @ingroup serd_storage + @{ +*/ + +/// Hashing node container for interning and simplified memory management +typedef struct SerdNodesImpl SerdNodes; + +/// Create a new node set +SERD_API SerdNodes* ZIX_ALLOCATED +serd_nodes_new(SerdAllocator* ZIX_NULLABLE allocator); + +/** + Free `nodes` and all nodes that are stored in it. + + Note that this invalidates any node pointers previously returned from + `nodes`. +*/ +SERD_API void +serd_nodes_free(SerdNodes* ZIX_NULLABLE nodes); + +/// Return the number of interned nodes +SERD_PURE_API size_t +serd_nodes_size(const SerdNodes* ZIX_NONNULL nodes); + +/** + Return the existing interned copy of a node if it exists. + + This either returns an equivalent to the given node, or null if this node + has not been interned. +*/ +SERD_API const SerdNode* ZIX_NULLABLE +serd_nodes_existing(const SerdNodes* ZIX_NONNULL nodes, + const SerdNode* ZIX_NULLABLE node); + +/** + Intern `node`. + + Multiple calls with equivalent nodes will return the same pointer. + + @return A node that is different than, but equivalent to, `node`. +*/ +SERD_API const SerdNode* ZIX_ALLOCATED +serd_nodes_intern(SerdNodes* ZIX_NONNULL nodes, + const SerdNode* ZIX_NULLABLE node); + +/** + Make a node of any type. + + A new node will be added if an equivalent node is not already in the set. +*/ +SERD_API const SerdNode* ZIX_ALLOCATED +serd_nodes_get(SerdNodes* ZIX_NONNULL nodes, SerdNodeArgs args); + +/** + Dereference `node`. + + Decrements the reference count of `node`, and frees the internally stored + equivalent node if this was the last reference. Does nothing if no node + equivalent to `node` is stored in `nodes`. +*/ +SERD_API void +serd_nodes_deref(SerdNodes* ZIX_NONNULL nodes, + const SerdNode* ZIX_NULLABLE node); + +/** + @} +*/ + +SERD_END_DECLS + +#endif // SERD_NODES_H diff --git a/include/serd/serd.h b/include/serd/serd.h index d264192f..4f1d97b5 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -88,6 +88,14 @@ /** @} + @defgroup serd_storage Storage + @{ +*/ + +#include "serd/nodes.h" + +/** + @} */ // IWYU pragma: end_exports |