EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / tests / evas_stringshare.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9
10 #include "Evas_Data.h"
11
12 typedef struct _Evas_Stringshare Evas_Stringshare;
13 typedef struct _Evas_Stringshare_El Evas_Stringshare_El;
14
15 struct _Evas_Stringshare
16 {
17    Evas_Stringshare_El *buckets[1024];
18 };
19
20 struct _Evas_Stringshare_El
21 {
22    Evas_Stringshare_El *next;
23 //   int op;
24    int references;
25 };
26
27 static Evas_Stringshare share =
28 {
29    {
30       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
31       NULL, NULL, NULL, NULL,
32       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
33       NULL, NULL, NULL, NULL,
34       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
35       NULL, NULL, NULL, NULL,
36       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
37       NULL, NULL, NULL, NULL,
38       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
39       NULL, NULL, NULL, NULL,
40       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
41       NULL, NULL, NULL, NULL,
42       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
43       NULL, NULL, NULL, NULL,
44       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
45       NULL, NULL, NULL, NULL,
46       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
47       NULL, NULL, NULL, NULL,
48       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
49       NULL, NULL, NULL, NULL,
50       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
51       NULL, NULL, NULL, NULL,
52       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
53       NULL, NULL, NULL, NULL,
54       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
55       NULL, NULL, NULL, NULL,
56       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
57       NULL, NULL, NULL, NULL,
58       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
59       NULL, NULL, NULL, NULL,
60       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
61       NULL, NULL, NULL, NULL,
62
63       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
64       NULL, NULL, NULL, NULL,
65       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
66       NULL, NULL, NULL, NULL,
67       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
68       NULL, NULL, NULL, NULL,
69       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
70       NULL, NULL, NULL, NULL,
71       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
72       NULL, NULL, NULL, NULL,
73       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
74       NULL, NULL, NULL, NULL,
75       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
76       NULL, NULL, NULL, NULL,
77       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
78       NULL, NULL, NULL, NULL,
79       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
80       NULL, NULL, NULL, NULL,
81       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
82       NULL, NULL, NULL, NULL,
83       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
84       NULL, NULL, NULL, NULL,
85       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
86       NULL, NULL, NULL, NULL,
87       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
88       NULL, NULL, NULL, NULL,
89       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
90       NULL, NULL, NULL, NULL,
91       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
92       NULL, NULL, NULL, NULL,
93       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
94       NULL, NULL, NULL, NULL,
95
96       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
97       NULL, NULL, NULL, NULL,
98       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
99       NULL, NULL, NULL, NULL,
100       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
101       NULL, NULL, NULL, NULL,
102       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
103       NULL, NULL, NULL, NULL,
104       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
105       NULL, NULL, NULL, NULL,
106       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
107       NULL, NULL, NULL, NULL,
108       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
109       NULL, NULL, NULL, NULL,
110       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
111       NULL, NULL, NULL, NULL,
112       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
113       NULL, NULL, NULL, NULL,
114       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
115       NULL, NULL, NULL, NULL,
116       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
117       NULL, NULL, NULL, NULL,
118       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
119       NULL, NULL, NULL, NULL,
120       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
121       NULL, NULL, NULL, NULL,
122       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
123       NULL, NULL, NULL, NULL,
124       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
125       NULL, NULL, NULL, NULL,
126       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
127       NULL, NULL, NULL, NULL,
128
129       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
130       NULL, NULL, NULL, NULL,
131       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
132       NULL, NULL, NULL, NULL,
133       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
134       NULL, NULL, NULL, NULL,
135       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
136       NULL, NULL, NULL, NULL,
137       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
138       NULL, NULL, NULL, NULL,
139       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
140       NULL, NULL, NULL, NULL,
141       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
142       NULL, NULL, NULL, NULL,
143       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
144       NULL, NULL, NULL, NULL,
145       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
146       NULL, NULL, NULL, NULL,
147       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
148       NULL, NULL, NULL, NULL,
149       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
150       NULL, NULL, NULL, NULL,
151       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
152       NULL, NULL, NULL, NULL,
153       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
154       NULL, NULL, NULL, NULL,
155       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
156       NULL, NULL, NULL, NULL,
157       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
158       NULL, NULL, NULL, NULL,
159       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
160       NULL, NULL, NULL, NULL
161    }
162 };
163
164 //static int op = 0;
165 //static FILE *f = NULL;
166
167 static inline int
168 _evas_stringshare_hash_gen(const char *str, int *len)
169 {
170    unsigned int hash_num = 5381;
171    const unsigned char *ptr;
172
173    for (ptr = (const unsigned char *)str; *ptr; ptr++)
174      {
175         hash_num = (hash_num * 33) ^ *ptr;
176      }
177
178    hash_num &= 0x3ff;
179    *len = ptr - (const unsigned char *)str;
180    return (int)hash_num;
181 }
182
183 EAPI const char *
184 evas_stringshare_add(const char *str)
185 {
186    int hash_num, slen;
187    char *el_str;
188    Evas_Stringshare_El *el, *pel = NULL;
189
190    if (!str)
191      {
192         return NULL; //   if (!f)
193
194      }
195
196 //     {
197 //      char bf[256];
198 //      snprintf(bf, sizeof(bf), "strlog-%i", getpid());
199 //      f = fopen(bf, "w");
200 //     }
201    hash_num = _evas_stringshare_hash_gen(str, &slen);
202    for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
203      {
204         el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
205         if (!strcmp(el_str, str))
206           {
207              if (pel)
208                {
209                   pel->next = el->next;
210                   el->next = share.buckets[hash_num];
211                   share.buckets[hash_num] = el;
212                }
213
214              el->references++;
215 //           fprintf(f, "strings[%i] = str->add(strings[%i]);\n", el->op, el->op);
216 //           fflush(f);
217              return el_str;
218           }
219      }
220    if (!(el = malloc(sizeof(Evas_Stringshare_El) + slen + 1)))
221       return NULL;
222
223    el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
224    strcpy(el_str, str);
225    el->references = 1;
226    el->next = share.buckets[hash_num];
227    share.buckets[hash_num] = el;
228 //   el->op = op;
229 //   fprintf(f, "strings[%i] = str->add(\"%s\");\n", el->op, el_str);
230 //   fflush(f);
231 //   op++;
232    return el_str;
233 }
234
235 EAPI void
236 evas_stringshare_del(const char *str)
237 {
238    int hash_num, slen;
239    char *el_str;
240    Evas_Stringshare_El *el, *pel = NULL;
241
242    if (!str)
243       return;
244
245    hash_num = _evas_stringshare_hash_gen(str, &slen);
246    for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
247      {
248         el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
249         if (el_str == str)
250           {
251              el->references--;
252 //           fprintf(f, "str->del(strings[%i]);\n", el->op);
253 //           fflush(f);
254              if (el->references == 0)
255                {
256                   if (pel)
257                      pel->next = el->next;
258                   else
259                      share.buckets[hash_num] = el->next;
260
261                   free(el);
262                }
263              else if (pel)
264                {
265                   pel->next = el->next;
266                   el->next = share.buckets[hash_num];
267                   share.buckets[hash_num] = el;
268                }
269
270              return;
271           }
272      }
273    printf("EEEK trying to del non-shared stringshare \"%s\"\n", str);
274    abort();
275 }