Reduct  v4.0.5-1-g4851deb
A functional and immutable language.
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1#ifndef REDUCT_LIST_H
2#define REDUCT_LIST_H 1
3
4#include <reduct/arena.h>
5#include <reduct/defs.h>
6
7#include <stdatomic.h>
8#include <stdbool.h>
9#include <stddef.h>
10
11struct reduct;
12struct reduct_item;
13
14/**
15 * @file list.h
16 * @brief List management.
17 * @defgroup list List
18 *
19 * A list is a sequence of handles. Small lists are stored directly within the item,
20 * while larger lists are allocated from an arena.
21 *
22 * ## Overlapping List Optimization
23 *
24 * When creating new lists by appending or prepending elements to existing lists, Reduct will attempt to reuse the
25 * existing list.
26 *
27 * This is done by allocating additional "tailroom" and "headroom" when creating large lists. When appending or
28 * prepending, if the existing list has unused tailroom or headroom, a new list can be created that overlaps with the
29 * existing list's buffer, avoiding the need to copy elements.
30 *
31 * This in combination with the fact that the structure is an contiguous array makes random-access, appending,
32 * prepending, sliceing and concatenation `O(1)` in the common case. With appending, prepending and concatenation being
33 * `O(n)` in the worse case. While also providing good caching and list iteration.
34 *
35 */
36
37#define REDUCT_LIST_SMALL_MAX 4 ///< The maximum number of elements in a small list.
38#define REDUCT_LIST_LARGE_MIN 16 ///< The minimum number of elements in a large list.
39#define REDUCT_LIST_EXTRA_ROOM_FACTOR 2 ///< The factor of extra capacity to allocate around large lists.
40
41typedef uint8_t reduct_list_flags_t;
42#define REDUCT_LIST_FLAG_NONE 0 ///< No flags.
43#define REDUCT_LIST_FLAG_LARGE (1 << 0) ///< List has an allocated buffer within an arena.
44#define REDUCT_LIST_FLAG_USED_HEAD (1 << 1) ///< Reserved headroom has been used by a derivative list.
45#define REDUCT_LIST_FLAG_USED_TAIL (1 << 2) ///< Reserved tailroom has been used by a derivative list.
46
47/**
48 * @brief List structure.
49 * @struct reduct_list_t
50 */
51typedef struct reduct_list
52{
53 uint32_t length; ///< The length of the list (must be first, check the `reduct_item_t` structure).
54 uint32_t capacity; ///< The current capacity of the handle buffer.
55 uint32_t offset; ///< Offset of elements from the start of the buffer.
56 _Atomic(reduct_list_flags_t) flags; ///< List flags.
57 uint8_t _padding[3];
58 reduct_handle_t* handles; ///< Pointer to the handle data.
59 union {
60 reduct_handle_t smallHandles[REDUCT_LIST_SMALL_MAX]; ///< Small list data.
61 reduct_arena_t* arena; ///< The arena this list was allocated from.
62 };
64
65/**
66 * @brief A key-value pair for creating association lists.
67 * @struct reduct_list_entry_t
68 */
69typedef struct
70{
71 const char* key;
74
75/**
76 * @brief Create a new editable list.
77 *
78 * @param reduct Pointer to the Reduct structure.
79 * @param length The predetermined length of the list.
80 * @return A pointer to the newly created list.
81 */
82REDUCT_API reduct_list_t* reduct_list_new(struct reduct* reduct, size_t length);
83
84/**
85 * @brief Create a new list from an array of handles.
86 *
87 * @param reduct Pointer to the Reduct structure.
88 * @param count The number of handles.
89 * @param handles The array of handles.
90 * @return A pointer to the newly created list.
91 */
92REDUCT_API reduct_list_t* reduct_list_new_handles(struct reduct* reduct, size_t count, reduct_handle_t* handles);
93
94/**
95 * @brief Create a new association list (list storing key-value pairs) from a variable number of pairs.
96 *
97 * @param reduct Pointer to the Reduct structure.
98 * @param count The number of pairs.
99 * @param ... Each pair should be provided as a `(const char*, reduct_handle_t)`.
100 * @return A pointer to the newly created association list.
101 */
102REDUCT_API reduct_list_t* reduct_list_new_alist(struct reduct* reduct, size_t count, ...);
103
104/**
105 * @brief Create a new association list from an array of entries.
106 *
107 * @param reduct Pointer to the Reduct structure.
108 * @param count Number of entries.
109 * @param entries Array of key-value pairs.
110 */
111REDUCT_API reduct_list_t* reduct_list_new_alist_entries(struct reduct* reduct, size_t count,
112 const reduct_list_entry_t* entries);
113
114/**
115 * @brief Create a new list by slicing an existing list.
116 *
117 * @param reduct Pointer to the Reduct structure.
118 * @param list Pointer to the source list.
119 * @param start The starting index (inclusive).
120 * @param end The ending index (exclusive).
121 * @return A pointer to the newly created list slice.
122 */
123REDUCT_API reduct_list_t* reduct_list_slice(struct reduct* reduct, reduct_list_t* list, size_t start, size_t end);
124
125/**
126 * @brief Create a new list by appending an element to an existing list.
127 *
128 * @param reduct Pointer to the Reduct structure.
129 * @param list Pointer to the source list.
130 * @param val The value to append.
131 * @return A pointer to the newly created list.
132 */
134
135/**
136 * @brief Create a new list by prepending an element to an existing list.
137 *
138 * @param reduct Pointer to the Reduct structure.
139 * @param list Pointer to the source list.
140 * @param val The value to prepend.
141 * @return A pointer to the newly created list.
142 */
144
145/**
146 * @brief Create a new list by concatenating two existing lists.
147 *
148 * @param reduct Pointer to the Reduct structure.
149 * @param a Pointer to the first list.
150 * @param b Pointer to the second list.
151 * @return A pointer to the newly created list.
152 */
154
155/**
156 * @brief Retain a list, preventing it from being collected by the garbage collector.
157 *
158 * @param reduct Pointer to the Reduct structure.
159 * @param list Pointer to the list.
160 */
161REDUCT_API void reduct_list_retain(struct reduct* reduct, reduct_list_t* list);
162
163/**
164 * @brief Release a list, potentially allowing the garbage collector to collect it.
165 *
166 * @param reduct Pointer to the Reduct structure.
167 * @param list Pointer to the list.
168 */
169REDUCT_API void reduct_list_release(struct reduct* reduct, reduct_list_t* list);
170
171/** @} */
172
173#endif
Arena allocation.
#define REDUCT_API
Definition defs.h:24
uint8_t reduct_list_flags_t
Definition list.h:41
REDUCT_API reduct_list_t * reduct_list_slice(struct reduct *reduct, reduct_list_t *list, size_t start, size_t end)
Create a new list by slicing an existing list.
REDUCT_API reduct_list_t * reduct_list_new(struct reduct *reduct, size_t length)
Create a new editable list.
#define REDUCT_LIST_SMALL_MAX
The maximum number of elements in a small list.
Definition list.h:37
REDUCT_API reduct_list_t * reduct_list_new_handles(struct reduct *reduct, size_t count, reduct_handle_t *handles)
Create a new list from an array of handles.
REDUCT_API reduct_list_t * reduct_list_concat(struct reduct *reduct, reduct_list_t *a, reduct_list_t *b)
Create a new list by concatenating two existing lists.
REDUCT_API reduct_list_t * reduct_list_new_alist(struct reduct *reduct, size_t count,...)
Create a new association list (list storing key-value pairs) from a variable number of pairs.
REDUCT_API void reduct_list_retain(struct reduct *reduct, reduct_list_t *list)
Retain a list, preventing it from being collected by the garbage collector.
REDUCT_API reduct_list_t * reduct_list_prepend(struct reduct *reduct, reduct_list_t *list, reduct_handle_t val)
Create a new list by prepending an element to an existing list.
REDUCT_API reduct_list_t * reduct_list_append(struct reduct *reduct, reduct_list_t *list, reduct_handle_t val)
Create a new list by appending an element to an existing list.
REDUCT_API reduct_list_t * reduct_list_new_alist_entries(struct reduct *reduct, size_t count, const reduct_list_entry_t *entries)
Create a new association list from an array of entries.
REDUCT_API void reduct_list_release(struct reduct *reduct, reduct_list_t *list)
Release a list, potentially allowing the garbage collector to collect it.
Arena structure.
Definition arena.h:26
Handle type.
Definition defs.h:119
A key-value pair for creating association lists.
Definition list.h:70
const char * key
Definition list.h:71
reduct_handle_t value
Definition list.h:72
List structure.
Definition list.h:52
reduct_arena_t * arena
The arena this list was allocated from.
Definition list.h:61
uint32_t offset
Offset of elements from the start of the buffer.
Definition list.h:55
uint32_t capacity
The current capacity of the handle buffer.
Definition list.h:54
reduct_handle_t * handles
Pointer to the handle data.
Definition list.h:58
_Atomic(reduct_list_flags_t) flags
List flags.
uint32_t length
The length of the list (must be first, check the reduct_item_t structure).
Definition list.h:53