remove 1 pointer overhead for stringshare (4 bytes or 8) and optimsie free

lookup a little.

amazingly stringshare is showing a double speedup over strdup/free on this p4.


SVN revision: 18741
This commit is contained in:
Carsten Haitzler 2005-12-01 03:47:14 +00:00
parent 83e6dc6afb
commit 648b7deab7
1 changed files with 18 additions and 30 deletions

View File

@ -11,24 +11,21 @@ struct _Evas_Stringshare
struct _Evas_Stringshare_El struct _Evas_Stringshare_El
{ {
Evas_Stringshare_El *next, *prev; Evas_Stringshare_El *next;
int references; int references;
}; };
static inline int _evas_stringshare_hash_gen(const char *str);
static inline int static inline int
_evas_stringshare_hash_gen(const char *str) _evas_stringshare_hash_gen(const char *str, int *len)
{ {
unsigned int hash_num = 0, i; unsigned int hash_num = 0, i;
const unsigned char *ptr; const unsigned char *ptr;
if (!str) return 0;
for (i = 0, ptr = (unsigned char *)str; *ptr; ptr++, i++) for (i = 0, ptr = (unsigned char *)str; *ptr; ptr++, i++)
hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8); hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8);
hash_num &= 0xff; hash_num &= 0xff;
*len = i;
return (int)hash_num; return (int)hash_num;
} }
@ -57,23 +54,20 @@ static Evas_Stringshare share =
const char * const char *
evas_stringshare_add(const char *str) evas_stringshare_add(const char *str)
{ {
int hash_num; int hash_num, slen;
char *el_str; char *el_str;
Evas_Stringshare_El *el; Evas_Stringshare_El *el, *pel = NULL;
hash_num = _evas_stringshare_hash_gen(str); hash_num = _evas_stringshare_hash_gen(str, &slen);
for (el = share.buckets[hash_num]; el; el = el->next) for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
{ {
el_str = ((char *)el) + sizeof(Evas_Stringshare_El); el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (!strcmp(el_str, str)) if (!strcmp(el_str, str))
{ {
if (el->prev) if (pel)
{ {
el->prev->next = el->next; pel->next = el->next;
if (el->next) el->next->prev = el->prev;
el->prev = NULL;
el->next = share.buckets[hash_num]; el->next = share.buckets[hash_num];
el->next->prev = el;
share.buckets[hash_num] = el; share.buckets[hash_num] = el;
} }
el->references++; el->references++;
@ -81,13 +75,11 @@ evas_stringshare_add(const char *str)
return el_str; return el_str;
} }
} }
if (!(el = malloc(sizeof(Evas_Stringshare_El) + strlen(str) + 1))) return NULL; if (!(el = malloc(sizeof(Evas_Stringshare_El) + slen + 1))) return NULL;
el_str = ((char *)el) + sizeof(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;
el->prev = NULL;
el->next = share.buckets[hash_num]; el->next = share.buckets[hash_num];
if (el->next) el->next->prev = el;
share.buckets[hash_num] = el; share.buckets[hash_num] = el;
return el_str; return el_str;
} }
@ -95,33 +87,29 @@ evas_stringshare_add(const char *str)
void void
evas_stringshare_del(const char *str) evas_stringshare_del(const char *str)
{ {
int hash_num; int hash_num, slen;
char *el_str; char *el_str;
Evas_Stringshare_El *el; Evas_Stringshare_El *el, *pel = NULL;
hash_num = _evas_stringshare_hash_gen(str); hash_num = _evas_stringshare_hash_gen(str, &slen);
for (el = share.buckets[hash_num]; el; el = el->next) for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
{ {
el_str = ((char *)el) + sizeof(Evas_Stringshare_El); el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (!strcmp(el_str, str)) if (el_str == str)
{ {
el->references--; el->references--;
if (el->references == 0) if (el->references == 0)
{ {
if (el->next) el->next->prev = el->prev; if (pel) pel->next = el->next;
if (el->prev) el->prev->next = el->next;
else share.buckets[hash_num] = el->next; else share.buckets[hash_num] = el->next;
free(el); free(el);
} }
else else
{ {
if (el->prev) if (pel)
{ {
el->prev->next = el->next; pel->next = el->next;
if (el->next) el->next->prev = el->prev;
el->prev = NULL;
el->next = share.buckets[hash_num]; el->next = share.buckets[hash_num];
el->next->prev = el;
share.buckets[hash_num] = el; share.buckets[hash_num] = el;
} }
} }