aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/tests/ecore_strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/tests/ecore_strings.c')
-rw-r--r--libraries/eina/src/tests/ecore_strings.c160
1 files changed, 160 insertions, 0 deletions
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 @@
1#include <stdlib.h>
2#include <string.h>
3
4#include "Ecore_Data.h"
5
6static void ecore_string_free_cb(void *data);
7
8static Ecore_Hash *ecore_strings = NULL;
9static int ecore_string_init_count = 0;
10
11/**
12 * @defgroup Ecore_String_Group String Instance Functions
13 *
14 * These functions allow you to store one copy of a string, and use it
15 * throughout your program.
16 *
17 * This is a method to reduce the number of duplicated strings kept in
18 * memory. It's pretty common for the same strings to be dynamically
19 * allocated repeatedly between applications and libraries, especially in
20 * circumstances where you could have multiple copies of a structure that
21 * allocates the string. So rather than duplicating and freeing these
22 * strings, you request a read-only pointer to an existing string and
23 * only incur the overhead of a hash lookup.
24 *
25 * It sounds like micro-optimizing, but profiling has shown this can have
26 * a significant impact as you scale the number of copies up. It improves
27 * string creation/destruction speed, reduces memory use and decreases
28 * memory fragmentation, so a win all-around.
29 */
30
31/**
32 * Initialize the ecore string internal structure.
33 * @return Zero on failure, non-zero on successful initialization.
34 */
35EAPI int
36ecore_string_init()
37{
38 /*
39 * No strings have been loaded at this point, so create the hash
40 * table for storing string info for later.
41 */
42 if (!ecore_string_init_count)
43 {
44 ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare);
45 if (!ecore_strings)
46 return 0;
47
48 ecore_hash_free_value_cb_set(ecore_strings, ecore_string_free_cb);
49 }
50
51 ecore_string_init_count++;
52
53 return 1;
54}
55
56/**
57 * Retrieves an instance of a string for use in an ecore program.
58 * @param string The string to retrieve an instance of.
59 * @return A pointer to an instance of the string on success.
60 * @c NULL on failure.
61 * @ingroup Ecore_String_Group
62 */
63EAPI const char *
64ecore_string_instance(const char *string)
65{
66 Ecore_String *str;
67
68 CHECK_PARAM_POINTER_RETURN("string", string, NULL);
69
70 /*
71 * Check for a previous instance of the string, if not found, create
72 * it.
73 */
74 str = ecore_hash_get(ecore_strings, string);
75 if (!str)
76 {
77 int length;
78
79 /*
80 * Allocate and initialize a new string reference.
81 */
82 length = strlen(string) + 1;
83
84 str =
85 (Ecore_String *)malloc(sizeof(Ecore_String) + length * sizeof(char));
86
87 str->string = (char *)(str + 1);
88 str->references = 0;
89
90 memcpy(str->string, string, length);
91
92 ecore_hash_set(ecore_strings, str->string, str);
93 }
94
95 str->references++;
96
97 return str->string;
98}
99
100/**
101 * Notes that the given string has lost an instance.
102 *
103 * It will free the string if no other instances are left.
104 *
105 * @param string The given string.
106 * @ingroup Ecore_String_Group
107 */
108EAPI void
109ecore_string_release(const char *string)
110{
111 Ecore_String *str;
112
113 CHECK_PARAM_POINTER("string", string);
114
115 str = ecore_hash_get(ecore_strings, (char *)string);
116 if (!str)
117 return;
118
119 str->references--;
120 if (str->references < 1)
121 {
122 ecore_hash_remove(ecore_strings, (char *)string);
123 FREE(str);
124 }
125}
126
127EAPI void
128ecore_string_hash_dump_graph(void)
129{
130 ecore_hash_dump_graph(ecore_strings);
131}
132
133EAPI void
134ecore_string_hash_dump_stats(void)
135{
136 ecore_hash_dump_stats(ecore_strings);
137}
138
139/**
140 * Shutdown the ecore string internal structures
141 */
142EAPI void
143ecore_string_shutdown()
144{
145 --ecore_string_init_count;
146 if (!ecore_string_init_count)
147 {
148 ecore_hash_destroy(ecore_strings);
149 ecore_strings = NULL;
150 }
151}
152
153static void
154ecore_string_free_cb(void *data)
155{
156 Ecore_String *str;
157
158 str = data;
159 FREE(str);
160}