-
Notifications
You must be signed in to change notification settings - Fork 2
/
tag_pair.c
135 lines (105 loc) · 1.95 KB
/
tag_pair.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
#include "tag_pair.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* map: (tag, tag) -> index */
struct tag_pair *map0; /* root of tree */
size_t tag_pair_elems;
size_t tag_pair_size; /* allocated */
void tag_pair_create()
{
map0 = NULL;
tag_pair_elems = 0;
tag_pair_size = 1;
}
size_t tag_pair_get_elems()
{
return tag_pair_elems;
}
size_t tag_pair_get_size()
{
return tag_pair_size;
}
struct tag_pair make_tag_pair(size_t tag0, size_t tag1)
{
struct tag_pair pair;
pair.tag0 = tag0;
pair.tag1 = tag1;
return pair;
}
int tag_pair_compar(const void *l, const void *r)
{
const struct tag_pair *lpair = l;
const struct tag_pair *rpair = r;
if (lpair->tag0 < rpair->tag0) {
return -1;
}
if (lpair->tag0 > rpair->tag0) {
return +1;
}
if (lpair->tag1 < rpair->tag1) {
return -1;
}
if (lpair->tag1 > rpair->tag1) {
return +1;
}
return 0;
}
void tag_pair_enlarge()
{
tag_pair_size <<= 1;
}
size_t tag_pair_query(struct tag_pair *pair)
{
struct tag_pair *this = map0;
while (this != NULL) {
int r = tag_pair_compar(this, pair);
if (r == 0) {
return this->e;
} else if (r < 0) {
this = this->l;
} else {
this = this->r;
}
}
return (size_t)-1;
}
void tag_pair_free(struct tag_pair *this)
{
if (this != NULL) {
tag_pair_free(this->l);
tag_pair_free(this->r);
free(this);
}
}
int tag_pair_can_add()
{
return tag_pair_elems != tag_pair_size;
}
size_t tag_pair_add(struct tag_pair *pair)
{
assert(tag_pair_query(pair) == (size_t)-1);
assert(tag_pair_elems != tag_pair_size);
struct tag_pair **this = &map0;
while (*this != NULL) {
if (tag_pair_compar(*this, pair) < 0) {
this = & (*this)->l;
} else {
this = & (*this)->r;
}
}
*this = malloc(sizeof(struct tag_pair));
if (*this == NULL) {
abort();
}
**this = *pair;
(*this)->e = tag_pair_elems;
(*this)->l = NULL;
(*this)->r = NULL;
tag_pair_elems++;
return tag_pair_elems - 1;
}
void tag_pair_destroy()
{
tag_pair_free(map0);
}