Enlightenment CVS committal
Author : pfritz
Project : e17
Module : proto/eina
Dir : e17/proto/eina/src/lib
Modified Files:
eina_stringshare.c
Log Message:
- add init() and shutdown() functions
- add doxy
===================================================================
RCS file: /cvs/e/e17/proto/eina/src/lib/eina_stringshare.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- eina_stringshare.c 30 Jul 2008 13:05:13 -0000 1.1
+++ eina_stringshare.c 30 Jul 2008 14:42:37 -0000 1.2
@@ -10,94 +10,24 @@
#include <stdio.h>
#include <string.h>
-
#include "eina_stringshare.h"
-typedef struct _Eina_Stringshare_El Eina_Stringshare_El;
+typedef struct _Eina_Stringshare Eina_Stringshare;
+typedef struct _Eina_Stringshare_Node Eina_Stringshare_Node;
struct _Eina_Stringshare
{
- Eina_Stringshare_El *buckets[1024];
+ Eina_Stringshare_Node *buckets[1024];
};
-struct _Eina_Stringshare_El
+struct _Eina_Stringshare_Node
{
- Eina_Stringshare_El *next;
+ Eina_Stringshare_Node *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 Eina_Stringshare *share = NULL;
+static int eina_stringshare_init_count = 0;
static inline int
_eina_stringshare_hash_gen(const char *str, int *len)
@@ -115,58 +45,116 @@
return (int)hash_num;
}
+/**
+ * @defgroup Eina_Stringshare_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 eina stringshare internal structure.
+ * @return Zero on failure, non-zero on successful initialization.
+ */
+EAPI int
+eina_stringshare_init()
+{
+ /*
+ * No strings have been loaded at this point, so create the hash
+ * table for storing string info for later.
+ */
+ if (!eina_stringshare_init_count)
+ {
+ share = calloc(1, sizeof(Eina_Stringshare));
+ if (!share)
+ return 0;
+ }
+
+ eina_stringshare_init_count++;
+
+ return 1;
+}
+
+/**
+ * Retrieves an instance of a string for use in a program.
+ * @param str The string to retrieve an instance of.
+ * @return A pointer to an instance of the string on success.
+ * @c NULL on failure.
+ * @ingroup Eina_Stringshare_Group
+ */
EAPI const char *
eina_stringshare_add(const char *str)
{
int hash_num, slen;
char *el_str;
- Eina_Stringshare_El *el, *pel = NULL;
+ Eina_Stringshare_Node *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)
+ for (el = share->buckets[hash_num]; el; pel = el, el = el->next)
{
- el_str = ((char *)el) + sizeof(Eina_Stringshare_El);
+ el_str = ((char *)el) + sizeof(Eina_Stringshare_Node);
if (!strcmp(el_str, str))
{
if (pel)
{
pel->next = el->next;
- el->next = share.buckets[hash_num];
- share.buckets[hash_num] = el;
+ 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);
+ if (!(el = malloc(sizeof(Eina_Stringshare_Node) + slen + 1))) return NULL;
+ el_str = ((char *)el) + sizeof(Eina_Stringshare_Node);
strcpy(el_str, str);
el->references = 1;
- el->next = share.buckets[hash_num];
- share.buckets[hash_num] = el;
+ el->next = share->buckets[hash_num];
+ share->buckets[hash_num] = el;
return el_str;
}
+/**
+ * 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 Eina_Stringshare_Group
+ */
EAPI void
eina_stringshare_del(const char *str)
{
int hash_num, slen;
char *el_str;
- Eina_Stringshare_El *el, *pel = NULL;
+ Eina_Stringshare_Node *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)
+ for (el = share->buckets[hash_num]; el; pel = el, el = el->next)
{
- el_str = ((char *)el) + sizeof(Eina_Stringshare_El);
+ el_str = ((char *)el) + sizeof(Eina_Stringshare_Node);
if (el_str == str)
{
el->references--;
if (el->references == 0)
{
if (pel) pel->next = el->next;
- else share.buckets[hash_num] = el->next;
+ else share->buckets[hash_num] = el->next;
free(el);
}
else
@@ -174,8 +162,8 @@
if (pel)
{
pel->next = el->next;
- el->next = share.buckets[hash_num];
- share.buckets[hash_num] = el;
+ el->next = share->buckets[hash_num];
+ share->buckets[hash_num] = el;
}
}
return;
@@ -184,3 +172,32 @@
printf("EEEK trying to del non-shared stringshare \"%s\"\n", str);
abort();
}
+
+/**
+ * Shutdown the ecore string internal structures
+ */
+EAPI void
+eina_stringshare_shutdown()
+{
+ --eina_stringshare_init_count;
+ if (!eina_stringshare_init_count)
+ {
+ int i;
+ /* remove any string still in the table */
+ for (i = 0; i < 1024; i++)
+ {
+ Eina_Stringshare_Node *el = share->buckets[i];
+ while (el)
+ {
+ Eina_Stringshare_Node *cur = el;
+ el = el->next;
+ cur->next = NULL;
+ free(cur);
+ }
+ share->buckets[i] = NULL;
+ }
+ free(share);
+ share = NULL;
+ }
+}
+
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
enlightenment-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs