-
Notifications
You must be signed in to change notification settings - Fork 1
/
dict.c
129 lines (117 loc) · 2.58 KB
/
dict.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
#include "dict.h"
#include <stdio.h>
#include <string.h>
#include "k.h"
#include "x.h"
#include "sym.h"
#include "fn.h"
dict* dnew(void) {
return xcalloc(1,sizeof(dict));
}
void dfree(dict *d) {
if(!d) return;
if(d->r) { d->r--; return; }
DO(d->c,kfree(d->v[i]))
xfree(d->k);
xfree(d->v);
xfree(d);
}
dict* l2d(K *l) {
int i;
K *p;
dict *d = xmalloc(sizeof(dict));
d->c = l->c;
d->k = xmalloc(sizeof(char*)*d->c);
d->v = xmalloc(sizeof(K*)*d->c);
d->r = 0;
for(i=0;i<d->c;i++) {
p = v0(l)[i];
if(p->t == 0) {
d->k[i] = v3(v0(p)[0]);
d->v[i] = kref(v0(p)[1]);
} else if(p->t == -4) {
d->k[i] = v4(p)[0];
d->v[i] = k4(v4(p)[1]);
} else {
fprintf(stderr, "l2d\n");
exit(1);
}
}
return d;
}
K* d2l(dict *d) {
unsigned int i;
K *r = kv0(d->c);
K *q = 0;
for(i=0;i<r->c;i++) {
v0(r)[i] = kv0(3);
v0(v0(r)[i])[0] = k4(d->k[i]);
q = kref(d->v[i]);
v0(v0(r)[i])[1] = q;
v0(v0(r)[i])[2] = null;
}
return r;
}
dict *dcp(dict *d) {
dict *d2 = xmalloc(sizeof(dict));
d2->c = d->c;
d2->k = xmalloc(sizeof(char*)*d2->c);
d2->v = xmalloc(sizeof(K*)*d2->c);
d2->r = 0;
DO(d->c, d2->k[i]=d->k[i]; d2->v[i]=kref(d->v[i]))
return d2;
}
K* dget(dict *d, char *key) {
K *r = 0;
char *kk=sp(key);
DO(d->c,if(kk == d->k[i]) { r=kref(d->v[i]); break; })
return r;
}
void dset(dict *d, char *key, K *v) {
K *r = 0;
char *kk=sp(key);
kref(v);
DO(d->c,if(kk == d->k[i]) { r=d->v[i]; kfree(r); d->v[i]=v; break; })
if(!r) {
d->k = xrealloc(d->k, sizeof(char*)*(d->c+1));
d->v = xrealloc(d->v, sizeof(K*)*(d->c+1));
d->k[d->c]=kk;
d->v[d->c]=v;
d->c++;
}
}
K* dvals(dict *d) {
K *r = kv0(d->c);
DO(d->c, v0(r)[i]=kref(d->v[i]))
return knorm(r);
}
K* dkeys(dict *d) {
K *r = 0;
r = kv4(d->c);
DO(d->c,v4(r)[i] = d->k[i])
return r;
}
int dcmp(dict *d0, dict *d1) {
int i=0,r=0;
for(;;) {
if(i==d0->c && i==d1->c) break;
else if(i==d0->c && i<d1->c) {r=r?r:-1;break;} /* count */
else if(i<d0->c && i==d1->c) {r=r?r:1;break;} /* count */
else if(strcmp(d0->k[i],d1->k[i])<0) r=-1; /* key */
else if(strcmp(d0->k[i],d1->k[i])>0) r=1; /* key */
else if(kcmpr(d0->v[i],d1->v[i])<0) r=-1;
else if(kcmpr(d0->v[i],d1->v[i])>0) r=1;
i++;
}
return r;
}
uint64_t dhash(dict *d) {
uint64_t r=0;
DO(d->c,r^=xfnv1a(d->k[i],strlen(d->k[i])))
DO(d->c,r^=khash(d->v[i]))
return r;
}
void dreplace(dict *d, K *keys, K *v) {
if(keys->t==4) dset(d,keys->v,v);
else DO(keys->c,dset(d,v4(keys)[i],v->c?v0(v)[i]:v))
}