SpiNNFrontEndCommon 7.3.1
Common support code for user-facing front end systems.
Loading...
Searching...
No Matches
aliases.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 The University of Manchester
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
21#ifndef __ALIASES_H__
22#define __ALIASES_H__
23
24#include <malloc_extras.h>
25#include "../common/routing_table.h"
26#include <debug.h>
27
28/*****************************************************************************/
29/* Vector-like object ********************************************************/
30
32typedef struct _alias_element_t { // Element of an alias list
35
37 uint32_t source;
39
41typedef struct _alias_list_t {
43 unsigned int n_elements;
45 unsigned int max_size;
47 struct _alias_list_t *next;
51
55static alias_list_t* alias_list_new(unsigned int max_size) {
56 // Compute how much memory to allocate
57 unsigned int size =
58 sizeof(alias_list_t) + (max_size - 1) * sizeof(alias_element_t);
59
60 // Allocate and then fill in values
61 alias_list_t *as = MALLOC(size);
62 if (as == NULL){
63 return NULL;
64 }
65
66 as->n_elements = 0;
67 as->max_size = max_size;
68 as->next = NULL;
69 return as;
70}
71
78 alias_list_t *as, key_mask_t val, uint32_t source) {
79 if (as->n_elements < as->max_size) {
80 (&as->data)[as->n_elements].key_mask = val;
81 (&as->data)[as->n_elements].source = source;
82 as->n_elements++;
83 return true;
84 }
85 // Cannot append!
86 return false;
87}
88
93static alias_element_t alias_list_get(alias_list_t *as, unsigned int i) {
94 return (&as->data)[i];
95}
96
101 // Traverse the list elements until we reach the end.
102 while (a->next != NULL) {
103 a = a->next;
104 }
105
106 // Store the next element
107 a->next = b;
108}
109
113 if (a->next != NULL) {
115 a->next = NULL;
116 }
117 FREE(a);
118}
119
120/*****************************************************************************/
121
122
123/*****************************************************************************/
124/* Map-like object ***********************************************************/
125// Implemented as an AA tree
126
128typedef union a_key_t {
131
133 int64_t as_int;
134} a_key_t;
135
137typedef struct node_t {
140
143
145 unsigned int level;
146
148 struct node_t *left;
149
151 struct node_t *right;
152} node_t;
153
155typedef struct aliases_t {
158} aliases_t;
159
163 aliases_t aliases = {NULL};
164 return aliases;
165}
166
171static inline node_t *_aliases_find_node(node_t *node, a_key_t key) {
172 while (node != NULL) {
173 if (key.as_int == node->key.as_int) {
174 // This is the requested item, return it
175 return node;
176 }
177
178 if (key.as_int < node->key.as_int) {
179 // Go left
180 node = node->left;
181 } else {
182 // Go right
183 node = node->right;
184 }
185 }
186 return NULL; // We didn't find the requested item
187}
188
194 // Search the tree
195 node_t *node = _aliases_find_node(a->root, (a_key_t) key);
196 if (node == NULL) {
197 return NULL;
198 }
199 return node->val;
200}
201
206static inline bool aliases_contains(aliases_t *a, key_mask_t key) {
207 return aliases_find(a, key) != NULL;
208}
209
213static inline node_t *_aliases_skew(node_t *n) {
214 if (n == NULL) {
215 return NULL;
216 }
217 if (n->left == NULL || n->level != n->left->level) {
218 return n;
219 }
220
221 node_t *node_pointer = n->left;
222 n->left = node_pointer->right;
223 node_pointer->right = n;
224 return node_pointer;
225}
226
230static inline node_t *_aliases_split(node_t *n) {
231 if (n == NULL) {
232 return NULL;
233 }
234 if (n->right == NULL || n->right->right == NULL
235 || n->level != n->right->right->level) {
236 return n;
237 }
238
239 node_t *r = n->right;
240 n->right = r->left;
241 r->left = n;
242 r->level++;
243 return r;
244}
245
251static bool _aliases_insert( // DO NOT INLINE; RECURSIVE!
252 node_t *n, a_key_t key, alias_list_t *val) {
253 if (n == NULL) {
254 // If the node is NULL then create a new Node
255 // Malloc room for the node
256 n = MALLOC(sizeof(node_t));
257 if (n == NULL) {
258 log_error("failed to allocate memory for node");
259 return false;
260 }
261
262 // Assign the values
263 n->key = key;
264 n->val = val;
265 n->left = n->right = NULL;
266 n->level = 1;
267
268 return true;
269 }
270
271 if (key.as_int < n->key.as_int) {
272 // Go left
273 bool success = _aliases_insert(n->left, key, val);
274 if (!success) {
275 return false;
276 }
277 } else if (key.as_int > n->key.as_int) {
278 // Go right
279 bool success = _aliases_insert(n->right, key, val);
280 if (!success) {
281 return false;
282 }
283 } else {
284 // Replace the value
285 n->val = val;
286 }
287
288 // Rebalance the tree
289 n = _aliases_skew(n);
290 n = _aliases_split(n);
291
292 return true;
293}
294
295
301static inline bool aliases_insert(
302 aliases_t *a, key_mask_t key, alias_list_t *value) {
303 // Insert into, and balance, the tree
304
305 return _aliases_insert(a->root, (a_key_t) key, value);
306}
307
308
312static inline void aliases_remove(aliases_t *a, key_mask_t key) {
313 // XXX This is a hack which removes the reference to the element in the
314 // tree but doesn't remove the Node from the tree.
315 node_t *n = _aliases_find_node(a->root, (a_key_t) key);
316 if (n != NULL) {
317 n->val = NULL;
318 }
319}
320
323static void _aliases_clear(node_t *n) { // DO NOT INLINE; RECURSIVE!
324 if (n == NULL) {
325 return;
326 }
327
328 // Remove any children
329 if (n->left != NULL) {
330 _aliases_clear(n->left);
331 }
332 if (n->right != NULL) {
333 _aliases_clear(n->right);
334 }
335
336 // Clear the value
337 if (n->val != NULL) {
339 }
340
341 // Remove self
342 FREE(n);
343}
344
345
349static inline void aliases_clear(aliases_t *a) {
350 _aliases_clear(a->root);
351}
352
353/*****************************************************************************/
354
355#endif // __ALIASES_H__
static bool aliases_insert(aliases_t *a, key_mask_t key, alias_list_t *value)
Add/overwrite an element into an aliases tree.
Definition aliases.h:301
key_mask_t km
key mast combo
Definition aliases.h:130
static bool alias_list_append(alias_list_t *as, key_mask_t val, uint32_t source)
Append an element to a list.
Definition aliases.h:77
unsigned int n_elements
Elements in this instance.
Definition aliases.h:43
struct _alias_list_t * next
Next element in list of lists.
Definition aliases.h:47
void alias_list_delete(alias_list_t *a)
Delete all elements in an alias list.
Definition aliases.h:112
int64_t as_int
the 64 bit int version
Definition aliases.h:133
alias_element_t data
Data region.
Definition aliases.h:49
a_key_t key
Key and value of this node.
Definition aliases.h:139
static alias_list_t * alias_list_new(unsigned int max_size)
Create a new list on the stack.
Definition aliases.h:55
key_mask_t key_mask
key_mask of the element
Definition aliases.h:34
node_t * root
pointer to first element
Definition aliases.h:157
static void alias_list_join(alias_list_t *a, alias_list_t *b)
Append a list to an existing list.
Definition aliases.h:100
static alias_list_t * aliases_find(aliases_t *a, key_mask_t key)
Retrieve an element from an aliases container.
Definition aliases.h:193
unsigned int max_size
Max number of elements in this instance.
Definition aliases.h:45
static bool aliases_contains(aliases_t *a, key_mask_t key)
See if the aliases contain holds an element.
Definition aliases.h:206
static alias_element_t alias_list_get(alias_list_t *as, unsigned int i)
Get an element from the list.
Definition aliases.h:93
static void aliases_remove(aliases_t *a, key_mask_t key)
Remove an element from an aliases tree.
Definition aliases.h:312
struct node_t * left
left child
Definition aliases.h:148
uint32_t source
Source of packets matching the element.
Definition aliases.h:37
struct node_t * right
right child
Definition aliases.h:151
alias_list_t * val
alias ......
Definition aliases.h:142
static aliases_t aliases_init(void)
Create a new, empty, aliases container.
Definition aliases.h:162
static void aliases_clear(aliases_t *a)
Remove all elements from an aliases container and free all sub-containers.
Definition aliases.h:349
unsigned int level
tree level maybe?
Definition aliases.h:145
Copy of key mask needed for Mundy compressor.
Definition aliases.h:32
Linked list of arrays.
Definition aliases.h:41
top of tree
Definition aliases.h:155
node struct
Definition aliases.h:137
the key union from a key and mask to a 64 bit number
Definition aliases.h:128
SpiNNaker debug header file.
void log_error(const char *message,...)
This function logs errors. Errors usually indicate a serious fault in the program,...
Support for adding debugging information to dynamic allocation.
#define MALLOC
An easily-insertable name for the memory allocator.
#define FREE
An easily-insertable name for the memory free.
Holds key and mask.
#define NULL