From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- libraries/eina/src/tests/ecore_strings.c | 160 +++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 libraries/eina/src/tests/ecore_strings.c (limited to 'libraries/eina/src/tests/ecore_strings.c') diff --git a/libraries/eina/src/tests/ecore_strings.c b/libraries/eina/src/tests/ecore_strings.c new file mode 100644 index 0000000..d76e4c5 --- /dev/null +++ b/libraries/eina/src/tests/ecore_strings.c @@ -0,0 +1,160 @@ +#include +#include + +#include "Ecore_Data.h" + +static void ecore_string_free_cb(void *data); + +static Ecore_Hash *ecore_strings = NULL; +static int ecore_string_init_count = 0; + +/** + * @defgroup Ecore_String_Group String Instance Functions + * + * These functions allow you to store one copy of a string, and use it + * throughout your program. + * + * This is a method to reduce the number of duplicated strings kept in + * memory. It's pretty common for the same strings to be dynamically + * allocated repeatedly between applications and libraries, especially in + * circumstances where you could have multiple copies of a structure that + * allocates the string. So rather than duplicating and freeing these + * strings, you request a read-only pointer to an existing string and + * only incur the overhead of a hash lookup. + * + * It sounds like micro-optimizing, but profiling has shown this can have + * a significant impact as you scale the number of copies up. It improves + * string creation/destruction speed, reduces memory use and decreases + * memory fragmentation, so a win all-around. + */ + +/** + * Initialize the ecore string internal structure. + * @return Zero on failure, non-zero on successful initialization. + */ +EAPI int +ecore_string_init() +{ + /* + * No strings have been loaded at this point, so create the hash + * table for storing string info for later. + */ + if (!ecore_string_init_count) + { + ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare); + if (!ecore_strings) + return 0; + + ecore_hash_free_value_cb_set(ecore_strings, ecore_string_free_cb); + } + + ecore_string_init_count++; + + return 1; +} + +/** + * Retrieves an instance of a string for use in an ecore program. + * @param string The string to retrieve an instance of. + * @return A pointer to an instance of the string on success. + * @c NULL on failure. + * @ingroup Ecore_String_Group + */ +EAPI const char * +ecore_string_instance(const char *string) +{ + Ecore_String *str; + + CHECK_PARAM_POINTER_RETURN("string", string, NULL); + + /* + * Check for a previous instance of the string, if not found, create + * it. + */ + str = ecore_hash_get(ecore_strings, string); + if (!str) + { + int length; + + /* + * Allocate and initialize a new string reference. + */ + length = strlen(string) + 1; + + str = + (Ecore_String *)malloc(sizeof(Ecore_String) + length * sizeof(char)); + + str->string = (char *)(str + 1); + str->references = 0; + + memcpy(str->string, string, length); + + ecore_hash_set(ecore_strings, str->string, str); + } + + str->references++; + + return str->string; +} + +/** + * Notes that the given string has lost an instance. + * + * It will free the string if no other instances are left. + * + * @param string The given string. + * @ingroup Ecore_String_Group + */ +EAPI void +ecore_string_release(const char *string) +{ + Ecore_String *str; + + CHECK_PARAM_POINTER("string", string); + + str = ecore_hash_get(ecore_strings, (char *)string); + if (!str) + return; + + str->references--; + if (str->references < 1) + { + ecore_hash_remove(ecore_strings, (char *)string); + FREE(str); + } +} + +EAPI void +ecore_string_hash_dump_graph(void) +{ + ecore_hash_dump_graph(ecore_strings); +} + +EAPI void +ecore_string_hash_dump_stats(void) +{ + ecore_hash_dump_stats(ecore_strings); +} + +/** + * Shutdown the ecore string internal structures + */ +EAPI void +ecore_string_shutdown() +{ + --ecore_string_init_count; + if (!ecore_string_init_count) + { + ecore_hash_destroy(ecore_strings); + ecore_strings = NULL; + } +} + +static void +ecore_string_free_cb(void *data) +{ + Ecore_String *str; + + str = data; + FREE(str); +} -- cgit v1.1