#include "serene/rt/impl/seq.h"
#include <stdint.h>
#include <stdio.h>
#include "serene/rt/context.h"
#include "serene/utils.h"
Go to the source code of this file.
|
| static uint16_t | seq_depth_index (const uint8_t depth, const uint64_t index) |
| | Find the array index of the given index, considering the given depth.
|
| |
| static seq_elem_t * | seq_create_page (const srn_context_t *ctx) |
| | Create a PAGE (just slots for the data)
|
| |
| static seq_node_t * | seq_new_node (const srn_context_t *ctx) |
| |
| static seq_node_t * | seq_new_path (const srn_context_t *ctx, uint8_t depth, seq_node_t *leaf) |
| | Walk from the root to a possible leaf node and create all the inner and leaf nodes if necessary.
|
| |
| static seq_node_t * | seq_next_child (const srn_context_t *ctx, seq_node_t *n, uint16_t index) |
| | Get or create the next node of the tree.
|
| |
| seq_t | seq_empty (const srn_context_t *ctx) |
| |
| seq_t | seq_push (const srn_context_t *ctx, const seq_t *seq, seq_elem_t x) |
| |
| seq_lookup_result_t | seq_get (const srn_context_t *ctx, const seq_t *seq, size_t n) |
| | Negative index is not supported.
|
| |
◆ SEQ_LOG
| #define SEQ_LOG |
( |
| FMT, |
|
|
| ... ) |
Definition at line 30 of file seq.c.
◆ seq_create_page()
Create a PAGE (just slots for the data)
Definition at line 40 of file seq.c.
40 {
43 for (
size_t i = 0; i <
SEQ_BR; i++) {
44 p[i] = nullptr;
45 }
46 return p;
47}
#define ALLOCN(ctx, T, N)
#define SEQ_BR
branching factor (power of two)
void * seq_elem_t
We use generic pointers to refer to internal nodes, leaf nodes and even elements.
#define PANIC_IF_NULL(ptr)
◆ seq_depth_index()
| static uint16_t seq_depth_index |
( |
const uint8_t | depth, |
|
|
const uint64_t | index ) |
|
inlinestatic |
Find the array index of the given index, considering the given depth.
depth can be thought of, as which 5 bits of the index are we looking at. (SEQ_SHIFT is 5).
Definition at line 35 of file seq.c.
35 {
37}
#define SEQ_SHIFT
log2(SEQ_BR)
◆ seq_empty()
Definition at line 76 of file seq.c.
76 {
81 seq.maybe_error = nullptr;
84 return seq;
85}
static seq_elem_t * seq_create_page(const srn_context_t *ctx)
Create a PAGE (just slots for the data)
size_t len
logical length.
seq_node_t * root
NULL means “all data is in tail”
seq_elem_t * tail
small tail array for fast push/pop.
uint8_t depth
tree depth in levels (0 == leaf level)
uint16_t tail_len
0..SEQ_BR
◆ seq_get()
Negative index is not supported.
Definition at line 173 of file seq.c.
173 {
175
177 char *err_msg = (
char *)
ALLOC(ctx,
size_t);
178
179 SNPRINTF(err_msg,
sizeof(
size_t) + 1,
"%zu",
n);
180
182 result.
data =
nullptr;
183 return result;
184 }
185
186 size_t tail_start = seq->
len - (size_t)seq->
tail_len;
187 if (
n >= tail_start) {
188
189 size_t off =
n - tail_start;
191 return result;
192 }
193
196 for (int16_t d = seq->
depth; d >= 0; d--) {
198 SEQ_LOG(
"Looking up in trie: D: %d, I: %hu", d, index);
199
200 if (d == 0) {
201 SEQ_LOG(
"We're at depth zero");
203 return result;
204 }
205
207 if (!node) {
209 result.
data =
nullptr;
210 return result;
211 }
212 }
213
214 PANIC(
"It should never happen");
215
216 result.
data =
nullptr;
217 result.maybe_error =
ERR(ctx,
ABSURD,
"");
218 return result;
219}
@ CORRUPTED_SEQ
When the memory layout of a seq is incorrect.
#define ERR(ctx, err, msg)
static seq_node_t * seq_next_child(const srn_context_t *ctx, seq_node_t *n, uint16_t index)
Get or create the next node of the tree.
static uint16_t seq_depth_index(const uint8_t depth, const uint64_t index)
Find the array index of the given index, considering the given depth.
We have two type of node that both are implemented using the same data structure.
seq_elem_t * children
We allocate children to be a buffer of SEQ_BR number of pointers.
#define SNPRINTF(buf, s, f,...)
◆ seq_new_node()
Definition at line 49 of file seq.c.
◆ seq_new_path()
Walk from the root to a possible leaf node and create all the inner and leaf nodes if necessary.
We use this only when we insert new data
Definition at line 58 of file seq.c.
58 {
59 if (depth == 0) {
60 return leaf;
61 }
62
66}
static seq_node_t * seq_new_node(const srn_context_t *ctx)
static seq_node_t * seq_new_path(const srn_context_t *ctx, uint8_t depth, seq_node_t *leaf)
Walk from the root to a possible leaf node and create all the inner and leaf nodes if necessary.
◆ seq_next_child()
Get or create the next node of the tree.
Definition at line 69 of file seq.c.
69 {
70 if (
n->children[index] ==
nullptr) {
72 }
73 return n->children[index];
74}
◆ seq_push()
Definition at line 87 of file seq.c.
87 {
88 if (seq->
len >= SIZE_MAX) {
90 failed_seq.maybe_error =
94 return failed_seq;
95 }
96
98
100 new_seq.maybe_error = nullptr;
101
105 return new_seq;
106 }
107
108
109 size_t sz_without_tail = seq->
len - (size_t)seq->
tail_len;
110
113
114
115
116 if (seq->
root ==
nullptr) {
117
118
119 seq_t new_seq = *seq;
120 new_seq.maybe_error = nullptr;
128
129 return new_seq;
130 }
131
132
133
134
136
137
141 seq_t new_seq = *seq;
142 new_seq.
root = new_root;
146 new_seq.
len = seq->
len + 1;
148 return new_seq;
149 }
150
152
153 for (uint8_t d = seq->
depth; d > 1; --d) {
155
157 }
158
159
160 uint16_t leaf_parent_idx =
seq_depth_index(1, (uint64_t)sz_without_tail);
162
163
164 seq_t new_seq = *seq;
167 new_seq.
len = seq->
len + 1;
169 return new_seq;
170}