Multi-ApplicationOnlineProfiling  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Trie.c
Go to the documentation of this file.
1 #include "Trie.h"
2 
3 #include <string.h>
4 #include <stdio.h>
5 
7 {
8  struct Trie_node * ret = malloc( sizeof( struct Trie_node ) );
9 
10  if( !ret )
11  {
12  perror("malloc");
13  return NULL;
14  }
15 
16  memset( ret, 0, sizeof( struct Trie_node ) );
17 
18  return ret;
19 }
20 
21 struct Trie_node * Trie_node_init_noalloc( void *payload, size_t size )
22 {
23  struct Trie_node * ret = Trie_node_init_empty();
24 
25  if( !ret )
26  return NULL;
27 
28  ret->payload = payload;
29  ret->size = size;
30 
31  return ret;
32 }
33 
34 int Trie_node_set( struct Trie_node *tn, void *payload, size_t size )
35 {
36  if( tn->size != size )
37  {
38  tn->payload = realloc( tn->payload, size );
39 
40  if( !tn->payload )
41  {
42  perror("realloc");
43  return 1;
44  }
45  }
46 
47  memcpy( tn->payload, payload, size );
48  tn->size = size;
49 
50  return 0;
51 }
52 
53 void Trie_node_free_payload( struct Trie_node * tn )
54 {
55  if( !tn )
56  return;
57 
58  free( tn->payload );
59  tn->payload = NULL;
60  tn->size = 0;
61 }
62 
63 
64 void Trie_node_release( struct Trie_node * tn )
65 {
66  int i;
67 
69 
70  for( i = 0 ; i < 94 ; i++ )
71  {
72  if( tn->children[i] )
73  Trie_node_release( tn->children[i] );
74  }
75 
76  free( tn->payload );
77  memset( tn, 0, sizeof( struct Trie_node ) );
78 
79  free( tn );
80 }
81 
82 
83 int Trie_init( struct Trie *tr )
84 {
85  tr->root = Trie_node_init_empty();
86  return 0;
87 }
88 
89 int Trie_release( struct Trie *tr )
90 {
91  Trie_node_release( tr->root );
92  tr->root = NULL;
93  return 0;
94 }
95 
96 
97 int Trie_set( struct Trie *tr, char *key, void *payload, size_t size )
98 {
99  struct Trie_node *tn = Trie_acquire_node( tr, key );
100 
101  if( !tn )
102  return 1;
103 
104  if( Trie_node_set( tn, payload, size ) )
105  return 1;
106 
107  Trie_relax_node( tn );
108 
109  return 0;
110 }
111 
112 int Trie_set_no_alloc( struct Trie *tr, char *key, void *payload, size_t size )
113 {
114  struct Trie_node *tn = Trie_acquire_node( tr, key );
115 
116  if( !tn )
117  return 1;
118 
120  tn->payload = payload;
121  tn->size = size;
122 
123  Trie_relax_node( tn );
124 
125  return 0;
126 }
127 
128 int _Trie_delete( struct Trie_node *tn, char *key, int depth )
129 {
130  if( !tn )
131  return 0;
132 
133  MALP_Spinlock_lock(&tn->lock);
134 
135  char c = *key;
136 
137  key++;
138 
139  if( c == '\0' )
140  {
141 
142  // Found it at least clear the payload
144 
145  int i;
146 
147  for( i = 0 ; i < 94 ; i++ )
148  {
149  if( tn->children[i] )
150  {
151  /* No children we are about to free the node*/
153  return 0;
154  }
155  }
156 
157 
158  return 1;
159  }
160 
161  int val = c - 32;
162 
163  if( _Trie_delete( tn->children[ val ], key, depth + 1 ) && depth /* Make sure we do not clear the root */ )
164  {
165  /* If node is a leaf we can even clear the node itself */
166  Trie_node_release( tn->children[ val ] );
167  tn->children[ val ] = NULL;
168  }
169 
171  return 0;
172 }
173 
174 
175 void Trie_delete( struct Trie *tr, char *key )
176 {
177  _Trie_delete( tr->root, key, 0 );
178 }
static struct Trie_node * Trie_acquire_node(struct Trie *tr, char *key)
Definition: Trie.h:39
struct Trie_node * Trie_node_init_empty()
Definition: Trie.c:6
int Trie_node_set(struct Trie_node *tn, void *payload, size_t size)
Definition: Trie.c:34
struct Trie_node * root
Definition: Trie.h:36
void Trie_node_release(struct Trie_node *tn)
Definition: Trie.c:64
size_t size
Definition: Trie.h:18
int MALP_Spinlock_unlock(MALP_Spinlock *mutex)
Unlocks the given MALP_Spinlock.
Definition: Spinlock.c:41
struct Trie_node * children[94]
Definition: Trie.h:22
static void Trie_relax_node(struct Trie_node *tn)
Definition: Trie.h:75
void Trie_delete(struct Trie *tr, char *key)
Definition: Trie.c:175
int Trie_init(struct Trie *tr)
Definition: Trie.c:83
void * payload
Definition: Trie.h:16
Definition: Trie.h:14
void Trie_node_free_payload(struct Trie_node *tn)
Definition: Trie.c:53
int MALP_Spinlock_lock(MALP_Spinlock *mutex)
Locks the given MALP_Spinlock.
Definition: Spinlock.c:29
struct Trie_node * Trie_node_init_noalloc(void *payload, size_t size)
Definition: Trie.c:21
int Trie_set_no_alloc(struct Trie *tr, char *key, void *payload, size_t size)
Definition: Trie.c:112
int Trie_release(struct Trie *tr)
Definition: Trie.c:89
int _Trie_delete(struct Trie_node *tn, char *key, int depth)
Definition: Trie.c:128
MALP_Spinlock lock
Definition: Trie.h:19
int MALP_Spinlock_trylock(MALP_Spinlock *mutex)
Tries to lock the given MALP_Spinlock.
Definition: Spinlock.c:22
int Trie_set(struct Trie *tr, char *key, void *payload, size_t size)
Definition: Trie.c:97
Definition: Trie.h:34