forked from enlightenment/efl
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:
parent
83e6dc6afb
commit
648b7deab7
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue