From 6e74d010305558d1d3256ca31079182a978957d7 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 30 Jul 2008 13:05:13 +0000 Subject: [PATCH] Adding stringshare from evas inside eina. SVN revision: 35249 --- legacy/eina/src/include/Makefile.am | 3 +- legacy/eina/src/include/eina_stringshare.h | 18 ++ legacy/eina/src/lib/Makefile.am | 3 +- legacy/eina/src/lib/eina_stringshare.c | 186 +++++++++++++++++++++ 4 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 legacy/eina/src/include/eina_stringshare.h create mode 100644 legacy/eina/src/lib/eina_stringshare.c diff --git a/legacy/eina/src/include/Makefile.am b/legacy/eina/src/include/Makefile.am index cddfaad1a5..9a65096491 100644 --- a/legacy/eina/src/include/Makefile.am +++ b/legacy/eina/src/include/Makefile.am @@ -11,7 +11,8 @@ eina_file.h \ eina_mempool.h \ eina_module.h \ eina_rectangle.h \ -eina_types.h +eina_types.h \ +eina_stringshare.h include_HEADERS = \ Eina.h diff --git a/legacy/eina/src/include/eina_stringshare.h b/legacy/eina/src/include/eina_stringshare.h new file mode 100644 index 0000000000..2a50ca7ad1 --- /dev/null +++ b/legacy/eina/src/include/eina_stringshare.h @@ -0,0 +1,18 @@ +#ifndef EINA_STRINGSHARE_H_ +#define EINA_STRINGSHARE_H_ + +#include "eina_types.h" + +/** + * @defgroup Stringshare_Group Shared strings. + * @{ + */ + +typedef struct _Eina_Stringshare Eina_Stringshare; + +EAPI const char *eina_stringshare_add(const char *str); +EAPI void eina_stringshare_del(const char *str); + +/** @} */ + +#endif /* EINA_STRINGSHARE_H_ */ diff --git a/legacy/eina/src/lib/Makefile.am b/legacy/eina/src/lib/Makefile.am index 666aed8612..b6e6a41156 100644 --- a/legacy/eina/src/lib/Makefile.am +++ b/legacy/eina/src/lib/Makefile.am @@ -14,7 +14,8 @@ eina_file.c \ eina_mempool.c \ eina_list.c \ eina_module.c \ -eina_value.c +eina_value.c \ +eina_stringshare.c libeina_la_LIBADD = -ldl libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ diff --git a/legacy/eina/src/lib/eina_stringshare.c b/legacy/eina/src/lib/eina_stringshare.c new file mode 100644 index 0000000000..6e9e5d4a77 --- /dev/null +++ b/legacy/eina/src/lib/eina_stringshare.c @@ -0,0 +1,186 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + + +#include "eina_stringshare.h" + +typedef struct _Eina_Stringshare_El Eina_Stringshare_El; + +struct _Eina_Stringshare +{ + Eina_Stringshare_El *buckets[1024]; +}; + +struct _Eina_Stringshare_El +{ + Eina_Stringshare_El *next; + int references; +}; + +static Eina_Stringshare share = +{ + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + } +}; + +static inline int +_eina_stringshare_hash_gen(const char *str, int *len) +{ + unsigned int hash_num = 5381; + const unsigned char *ptr; + + for (ptr = (const unsigned char *)str; *ptr; ptr++) + { + hash_num = (hash_num * 33) ^ *ptr; + } + + hash_num &= 0x3ff; + *len = ptr - (const unsigned char *)str; + return (int)hash_num; +} + +EAPI const char * +eina_stringshare_add(const char *str) +{ + int hash_num, slen; + char *el_str; + Eina_Stringshare_El *el, *pel = NULL; + + if (!str) return NULL; + hash_num = _eina_stringshare_hash_gen(str, &slen); + for (el = share.buckets[hash_num]; el; pel = el, el = el->next) + { + el_str = ((char *)el) + sizeof(Eina_Stringshare_El); + if (!strcmp(el_str, str)) + { + if (pel) + { + pel->next = el->next; + el->next = share.buckets[hash_num]; + share.buckets[hash_num] = el; + } + el->references++; + return el_str; + } + } + if (!(el = malloc(sizeof(Eina_Stringshare_El) + slen + 1))) return NULL; + el_str = ((char *)el) + sizeof(Eina_Stringshare_El); + strcpy(el_str, str); + el->references = 1; + el->next = share.buckets[hash_num]; + share.buckets[hash_num] = el; + return el_str; +} + +EAPI void +eina_stringshare_del(const char *str) +{ + int hash_num, slen; + char *el_str; + Eina_Stringshare_El *el, *pel = NULL; + + if (!str) return; + hash_num = _eina_stringshare_hash_gen(str, &slen); + for (el = share.buckets[hash_num]; el; pel = el, el = el->next) + { + el_str = ((char *)el) + sizeof(Eina_Stringshare_El); + if (el_str == str) + { + el->references--; + if (el->references == 0) + { + if (pel) pel->next = el->next; + else share.buckets[hash_num] = el->next; + free(el); + } + else + { + if (pel) + { + pel->next = el->next; + el->next = share.buckets[hash_num]; + share.buckets[hash_num] = el; + } + } + return; + } + } + printf("EEEK trying to del non-shared stringshare \"%s\"\n", str); + abort(); +}