-
Notifications
You must be signed in to change notification settings - Fork 0
/
intmap.c
85 lines (76 loc) · 1.93 KB
/
intmap.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
#include "intmap.h"
#include "iterator.h"
#include "utils.h"
#include <string.h>
#include <stdlib.h>
void *intmap_get(struct intmap *v, int index) {
if (!v->data) return 0;
return v->data[index - v->min];
}
int intmap_init(struct intmap *v, int center) {
int min = TCAMAX(0, center - 32);
int max = center + 32;
v->data = calloc(max - min, sizeof(void *));
v->min = min;
v->max = max;
return 0;
}
void intmap_set(struct intmap *v, int index, void *data) {
if (v->data == 0) {
intmap_init(v, index);
}
if (index < v->min) {
int offset = v->min - index;
void **newdata = calloc(v->max - index + 1, sizeof(void *));
memcpy(newdata + offset, v->data, sizeof(void *) * (v->max - v->min));
free(v->data);
v->data = newdata;
v->min = index;
} else if (index >= v->max) {
int newsize = TCAMAX((v->max - v->min) * 2, index - v->min);
int cursize = intmap_size(v);
v->data = realloc(v->data, newsize * sizeof(void *));
memset(v->data + cursize, 0, (newsize - cursize) * sizeof(void *));
v->max = newsize + v->min;
}
v->data[index - v->min] = data;
}
int intmap_size(struct intmap *v) {
return v->max - v->min;
}
void *__intmap_iterate(struct iterator *it) {
struct intmap *v = (struct intmap *)it->container;
it->i++;
while (it->i < v->max) {
if (v->data[it->i - v->min]) {
return v->data[it->i - v->min];
}
it->i++;
}
return 0;
}
void *__intmap_iterate_rev(struct iterator *it) {
struct intmap *v = (struct intmap *)it->container;
it->i--;
while (it->i >= v->min) {
if (v->data[it->i - v->min]) {
return v->data[it->i - v->min];
}
it->i--;
}
return 0;
}
struct iterator intmap_iterator(struct intmap *v) {
struct iterator result;
result.container = v;
result.i = v->min - 1;
result.iterate = __intmap_iterate;
return result;
}
struct iterator intmap_rev_iterator(struct intmap *v) {
struct iterator result;
result.container = v;
result.i = v->max;
result.iterate = __intmap_iterate_rev;
return result;
}