3 #include "../../include/tlist.h"
6 #define UINT_MAX 0xffffffffU
9 static int mrand(unsigned *seed
)
11 return (*seed
= (*seed
+1) * 1103515245 + 12345 - 1)+1 & 0x7fffffff;
14 typedef struct item
* pitem
;
20 static unsigned cnt (pitem it
) {
21 return it
? it
->cnt
: 0;
24 static void upd_cnt (pitem it
) {
26 it
->cnt
= cnt(it
->l
) + cnt(it
->r
) + 1;
29 static void merge (pitem
*t
, pitem l
, pitem r
) {
32 else if (l
->prior
> r
->prior
)
33 merge (&l
->r
, l
->r
, r
), *t
= l
;
35 merge (&r
->l
, l
, r
->l
), *t
= r
;
39 static void split (pitem t
, pitem
*l
, pitem
*r
, unsigned key
, unsigned add
) {
44 unsigned cur_key
= add
+ cnt(t
->l
);
46 split (t
->l
, l
, &t
->l
, key
, add
), *r
= t
;
48 split (t
->r
, &t
->r
, r
, key
, add
+ 1 + cnt(t
->l
)), *l
= t
;
52 static pitem
getitem(pitem t
, unsigned idx
, unsigned add
) {
54 unsigned ls
= cnt (t
->l
), cur_key
= add
+ ls
;
55 if (cur_key
== idx
) return t
;
57 return getitem (t
->r
, idx
, add
+ 1 + ls
);
59 return getitem (t
->l
, idx
, add
);
62 static void insert(pitem
*t
, pitem n
, unsigned idx
) {
64 split (*t
, &t1
, &t2
, idx
, 0);
69 static void remove(pitem
*t
, unsigned idx
, unsigned add
) {
72 unsigned cur_key
= add
+ cnt ((*t
)->l
), new_add
= cur_key
+ 1;
73 unsigned rk
, lk
= rk
= UINT_MAX
;
74 if ((*t
)->l
) lk
= cnt ((*t
)->l
->l
) + add
;
75 if ((*t
)->r
) rk
= cnt ((*t
)->r
->l
) + new_add
;
77 merge (t
, (*t
)->l
, (*t
)->r
);
78 } else if (lk
== idx
) {
79 merge (&n
, (*t
)->l
->l
, (*t
)->l
->r
);
82 } else if (rk
== idx
) {
83 merge (&n
, (*t
)->r
->l
, (*t
)->r
->r
);
86 } else if (cur_key
< idx
) {
87 remove (&(*t
)->r
, idx
, new_add
);
90 remove (&(*t
)->l
, idx
, add
);
95 static pitem
new_item(void* value
, unsigned valsz
, unsigned *seed
) {
96 pitem n
= malloc(sizeof(struct item
) + valsz
);
98 memcpy(n
+1, value
, valsz
);
99 n
->prior
= mrand(seed
);
111 struct tlist
*tlist_new(unsigned itemsize
) {
112 struct tlist
* new = malloc(sizeof (struct tlist
));
115 new->itemsize
= itemsize
;
120 static void* data(pitem it
) {
124 size_t tlist_getsize(struct tlist
* t
) {
128 void* tlist_get(struct tlist
* t
, size_t idx
) {
129 return data(getitem(t
->root
, idx
, 0));
132 int tlist_insert(struct tlist
* t
, size_t idx
, void *value
) {
133 if(idx
> cnt (t
->root
)) return 0;
134 pitem
new = new_item(value
, t
->itemsize
, &t
->seed
);
136 insert(&t
->root
, new, idx
);
140 int tlist_append(struct tlist
* t
, void *value
) {
141 return tlist_insert(t
, cnt(t
->root
), value
);
144 static int tlist_delete_impl(struct tlist
*t
, size_t idx
, int deep
) {
145 if(idx
>= cnt (t
->root
)) return 0;
146 pitem it
= getitem(t
->root
, idx
, 0);
147 if(deep
) free(data(it
));
148 remove(&t
->root
, idx
, 0);
153 int tlist_delete(struct tlist
*t
, size_t idx
) {
154 return tlist_delete_impl(t
, idx
, 0);
157 int tlist_delete_deep(struct tlist
*t
, size_t idx
) {
158 return tlist_delete_impl(t
, idx
, 1);
161 static void tlist_free_items_impl(struct tlist
*t
, int deep
) {
162 while(cnt(t
->root
)) tlist_delete_impl(t
, 0, deep
);
165 void tlist_free_items(struct tlist
*t
) {
166 tlist_free_items_impl(t
, 0);
169 void tlist_free_items_deep(struct tlist
*t
) {
170 tlist_free_items_impl(t
, 1);
173 static void* tlist_free_impl(struct tlist
*t
, int deep
) {
174 tlist_free_items_impl(t
, deep
);
179 void *tlist_free(struct tlist
*t
) {
180 return tlist_free_impl(t
, 0);
183 void *tlist_free_deep(struct tlist
*t
) {
184 return tlist_free_impl(t
, 1);
188 extern int printf(const char *__restrict
, ...);
189 float tlist_getbalance(struct tlist
*t
) {
190 size_t n
= tlist_getsize(t
);
192 if (n
== 0) return 1.0;
193 l
= cnt (t
->root
->l
);
194 r
= cnt (t
->root
->r
);
195 printf("l %d, r %d, diff %d\n", l
, r
, abs(l
-r
));
196 return 100.f
- ((float)abs(l
- r
)/(n
/100.f
));