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
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to