less overhead per string for stringshare (overhead right now is 2 pointers, 1

int (ie 12 bytes on 32bit, 20 bytes on 64bit systems). this removes 2 ptrs of
overhead (8 or 16 bytes) compared to before.


SVN revision: 18685
This commit is contained in:
Carsten Haitzler 2005-11-29 03:01:56 +00:00
parent 96015f59ab
commit 8a65399e27
1 changed files with 35 additions and 22 deletions

View File

@ -11,9 +11,8 @@ struct _Evas_Stringshare
struct _Evas_Stringshare_El struct _Evas_Stringshare_El
{ {
Evas_Object_List _list_data; int references;
char *str; Evas_Stringshare_El *next, *prev;
int references;
}; };
static inline int _evas_stringshare_hash_gen(const char *str); static inline int _evas_stringshare_hash_gen(const char *str);
@ -59,55 +58,69 @@ const char *
evas_stringshare_add(const char *str) evas_stringshare_add(const char *str)
{ {
int hash_num; int hash_num;
char *el_str;
Evas_Stringshare_El *el; Evas_Stringshare_El *el;
Evas_Object_List *l;
hash_num = _evas_stringshare_hash_gen(str); hash_num = _evas_stringshare_hash_gen(str);
for (l = share.buckets[hash_num]; l; l = l->next) for (el = share.buckets[hash_num]; el; el = el->next)
{ {
el = (Evas_Stringshare_El *)l; el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (!strcmp(el->str, str)) if (!strcmp(el_str, str))
{ {
if (l != share.buckets[hash_num]) if (el->prev)
{ {
share.buckets[hash_num] = evas_object_list_remove(share.buckets[hash_num], el); el->prev->next = el->next;
share.buckets[hash_num] = evas_object_list_prepend(share.buckets[hash_num], el); if (el->next) el->next->prev = el->prev;
el->prev = NULL;
el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
} }
el->references++; el->references++;
return el->str; return el_str;
} }
} }
if (!(el = malloc(sizeof(struct _Evas_Stringshare_El) + strlen(str) + 1))) return NULL; if (!(el = malloc(sizeof(Evas_Stringshare_El) + strlen(str) + 1))) return NULL;
el->str = ((unsigned char *)el) + sizeof(struct _Evas_Stringshare_El); el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
strcpy(el->str, str); strcpy(el_str, str);
el->references = 1; el->references = 1;
share.buckets[hash_num] = evas_object_list_prepend(share.buckets[hash_num], el); el->prev = NULL;
return el->str; el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
return el_str;
} }
void void
evas_stringshare_del(const char *str) evas_stringshare_del(const char *str)
{ {
int hash_num; int hash_num;
char *el_str;
Evas_Stringshare_El *el; Evas_Stringshare_El *el;
Evas_Object_List *l;
hash_num = _evas_stringshare_hash_gen(str); hash_num = _evas_stringshare_hash_gen(str);
for (l = share.buckets[hash_num]; l; l = l->next) for (el = share.buckets[hash_num]; el; el = el->next)
{ {
el = (Evas_Stringshare_El *)l; el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (!strcmp(el->str, str)) if (!strcmp(el_str, str))
{ {
el->references--; el->references--;
if (el->references == 0) if (el->references == 0)
{ {
if (el->next) el->next->prev = el->prev;
if (el->prev) el->prev->next = el->next;
else share.buckets[hash_num] = el->next;
share.buckets[hash_num] = evas_object_list_remove(share.buckets[hash_num], el); share.buckets[hash_num] = evas_object_list_remove(share.buckets[hash_num], el);
free(el); free(el);
} }
else else
{ {
share.buckets[hash_num] = evas_object_list_remove(share.buckets[hash_num], el); if (el->prev)
share.buckets[hash_num] = evas_object_list_prepend(share.buckets[hash_num], el); {
el->prev->next = el->next;
if (el->next) el->next->prev = el->prev;
el->prev = NULL;
el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
}
} }
return; return;
} }