-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathbase.util.longmap.c
126 lines (98 loc) · 3.11 KB
/
base.util.longmap.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
#include "brl.mod/blitz.mod/blitz.h"
#include "brl.mod/blitz.mod/tree/tree.h"
#if !defined(generic_compare)
# define generic_compare(x, y) (((x) > (y)) - ((x) < (y)))
#endif
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */
struct longmap_node {
struct avl_root link;
BBLONG key;
BBOBJECT value;
};
static int compare_longmap_nodes(const void *x, const void *y) {
struct longmap_node * node_x = (struct longmap_node *)x;
struct longmap_node * node_y = (struct longmap_node *)y;
return generic_compare(node_x->key, node_y->key);
}
void bmx_map_longmap_clear(struct avl_root ** root) {
struct longmap_node *node;
struct longmap_node *tmp;
avl_for_each_entry_safe(node, tmp, *root, link) {
avl_del(&node->link, root);
GC_FREE(node);
}
}
int bmx_map_longmap_isempty(struct avl_root ** root) {
return *root == 0;
}
void bmx_map_longmap_insert( BBLONG key, BBObject *value, struct avl_root ** root ) {
struct longmap_node * node = (struct longmap_node *)GC_malloc_uncollectable(sizeof(struct longmap_node));
node->key = key;
node->value = value;
struct longmap_node * old_node = (struct longmap_node *)avl_map(&node->link, compare_longmap_nodes, root);
if (&node->link != &old_node->link) {
// key already exists. Store the value in this node.
old_node->value = value;
// delete the new node, since we don't need it
GC_FREE(node);
}
}
int bmx_map_longmap_contains(BBLONG key, struct avl_root ** root) {
struct longmap_node node;
node.key = key;
struct longmap_node * found = (struct longmap_node *)TREE_SEARCH(&node, compare_longmap_nodes, *root);
if (found) {
return 1;
} else {
return 0;
}
}
BBObject * bmx_map_longmap_valueforkey(BBLONG key, struct avl_root ** root) {
struct longmap_node node;
node.key = key;
struct longmap_node * found = (struct longmap_node *)TREE_SEARCH(&node, compare_longmap_nodes, *root);
if (found) {
return found->value;
}
return &bbNullObject;
}
int bmx_map_longmap_remove(BBLONG key, struct avl_root ** root) {
struct longmap_node node;
node.key = key;
struct longmap_node * found = (struct longmap_node *)TREE_SEARCH(&node, compare_longmap_nodes, *root);
if (found) {
avl_del(&found->link, root);
GC_FREE(found);
return 1;
} else {
return 0;
}
}
struct longmap_node * bmx_map_longmap_nextnode(struct longmap_node * node) {
return (struct longmap_node *)TREE_SUCCESSOR(node);
}
struct longmap_node * bmx_map_longmap_firstnode(struct avl_root * root) {
return (struct longmap_node *)TREE_MIN(root);
}
BBLONG bmx_map_longmap_key(struct longmap_node * node) {
return node->key;
}
BBObject * bmx_map_longmap_value(struct longmap_node * node) {
return node->value;
}
int bmx_map_longmap_hasnext(struct longmap_node * node, struct avl_root * root) {
if (!root) {
return 0;
}
if (!node) {
return 1;
}
return (TREE_SUCCESSOR(node) != 0) ? 1 : 0;
}
void bmx_map_longmap_copy(struct avl_root ** dst_root, struct avl_root * src_root) {
struct longmap_node *src_node;
struct longmap_node *tmp;
avl_for_each_entry_safe(src_node, tmp, src_root, link) {
bmx_map_longmap_insert(src_node->key, src_node->value, dst_root);
}
}