-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpalmtrie.c
169 lines (156 loc) · 4.11 KB
/
palmtrie.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*_
* Copyright (c) 2015-2020 Hirochika Asai <[email protected]>
* All rights reserved.
*
*/
#include "palmtrie.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Initialize an instance
*/
struct palmtrie *
palmtrie_init(struct palmtrie *palmtrie, enum palmtrie_type type)
{
/* Allocate for the data structure when the argument is not NULL, and then
clear all the variables */
if ( NULL == palmtrie ) {
palmtrie = malloc(sizeof(struct palmtrie));
if ( NULL == palmtrie ) {
/* Memory allocation error */
return NULL;
}
(void)memset(palmtrie, 0, sizeof(struct palmtrie));
palmtrie->allocated = 1;
} else {
(void)memset(palmtrie, 0, sizeof(struct palmtrie));
}
/* Set the type and initialize the type-specific data structure */
switch ( type ) {
case PALMTRIE_SORTED_LIST:
/* Sorted list */
palmtrie->u.sl.head = NULL;
break;
case PALMTRIE_BASIC:
/* Ternary PATRICIA */
palmtrie->u.tpt.root = NULL;
break;
case PALMTRIE_DEFAULT:
/* Multiway ternary PATRICIA */
palmtrie->u.mtpt.root = NULL;
break;
case PALMTRIE_PLUS:
/* Multiway ternary PATRICIA */
palmtrie->u.popmtpt.root = 0;
palmtrie->u.popmtpt.nodes.nr = 0;
palmtrie->u.popmtpt.nodes.used = 0;
palmtrie->u.popmtpt.nodes.ptr = NULL;
palmtrie->u.popmtpt.mtpt.root = NULL;
break;
default:
/* Unsupported type */
if ( palmtrie->allocated ) {
free(palmtrie);
}
return NULL;
}
palmtrie->type = type;
return palmtrie;
}
/*
* Release the instance
*/
void
palmtrie_release(struct palmtrie *palmtrie)
{
int ret;
/* Release type-specific variables */
switch ( palmtrie->type ) {
case PALMTRIE_SORTED_LIST:
ret = palmtrie_sl_release(palmtrie);
break;
case PALMTRIE_BASIC:
ret = palmtrie_tpt_release(palmtrie);
break;
case PALMTRIE_DEFAULT:
ret = palmtrie_mtpt_release(palmtrie);
break;
case PALMTRIE_PLUS:
//ret = palmtrie_mtpt_release(palmtrie);
ret = 0;
break;
default:
return;
}
if ( 0 != ret ) {
return;
}
if ( palmtrie->allocated ) {
free(palmtrie);
}
}
/*
* palmtrie_add_data -- add an entry with data for a specified address to the
* trie
*/
int
palmtrie_add_data(struct palmtrie *palmtrie, addr_t addr, addr_t mask,
int priority, u64 data)
{
switch ( palmtrie->type ) {
case PALMTRIE_SORTED_LIST:
return palmtrie_sl_add(palmtrie, addr, mask, priority, (void *)data);
case PALMTRIE_BASIC:
return palmtrie_tpt_add(palmtrie, addr, mask, priority, (void *)data);
case PALMTRIE_DEFAULT:
return palmtrie_mtpt_add(&palmtrie->u.mtpt, addr, mask, priority,
(void *)data);
case PALMTRIE_PLUS:
return palmtrie_popmtpt_add(&palmtrie->u.popmtpt, addr, mask, priority,
(void *)data);
default:
/* Not supported type */
return -1;
}
}
/*
* palmtrie_lookup -- lookup an entry corresponding to the specified address
* from the trie
*/
u64
palmtrie_lookup(struct palmtrie *palmtrie, addr_t addr)
{
switch ( palmtrie->type ) {
case PALMTRIE_SORTED_LIST:
return (u64)palmtrie_sl_lookup(palmtrie, addr);
case PALMTRIE_BASIC:
return (u64)palmtrie_tpt_lookup(palmtrie, addr);
case PALMTRIE_DEFAULT:
return (u64)palmtrie_mtpt_lookup(palmtrie, addr);
case PALMTRIE_PLUS:
return (u64)palmtrie_popmtpt_lookup(&palmtrie->u.popmtpt, addr);
default:
return 0;
}
return 0;
}
/*
* palmtrie_commit -- compile an optimized trie by applying incremental updates
*/
int
palmtrie_commit(struct palmtrie *palmtrie)
{
if ( PALMTRIE_PLUS == palmtrie->type ) {
return palmtrie_popmtpt_commit(&palmtrie->u.popmtpt);
}
return 0;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/