Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
stringpool.c
Go to the documentation of this file.
00001 /*
00002  * Audacious
00003  * Copyright © 2009 William Pitcock <nenolod@atheme.org>
00004  * Copyright © 2010 John Lindgren <john.lindgren@tds.net>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; under version 3 of the License.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses>.
00017  *
00018  * The Audacious team does not consider modular code linking to
00019  * Audacious or using our public API to be a derived work.
00020  */
00021 
00022 #include <assert.h>
00023 #include <glib.h>
00024 #include <mowgli.h>
00025 
00026 static mowgli_patricia_t *stringpool_tree = NULL;
00027 static GStaticMutex stringpool_mutex = G_STATIC_MUTEX_INIT;
00028 
00029 #define MAXLEN 100
00030 
00031 gchar *
00032 stringpool_get(gchar *str, gboolean take)
00033 {
00034     if (str == NULL)
00035         return NULL;
00036 
00037     if (strlen(str) > MAXLEN)
00038         return take ? str : g_strdup(str);
00039 
00040     g_static_mutex_lock(&stringpool_mutex);
00041 
00042     if (stringpool_tree == NULL)
00043         stringpool_tree = mowgli_patricia_create(NULL);
00044 
00045     mowgli_patricia_elem_t *elem = mowgli_patricia_elem_find(stringpool_tree, str);
00046     if (elem != NULL)
00047     {
00048         gint refcount = GPOINTER_TO_INT(mowgli_patricia_elem_get_data(elem));
00049         mowgli_patricia_elem_set_data(elem, GINT_TO_POINTER(refcount + 1));
00050     }
00051     else
00052     {
00053         elem = mowgli_patricia_elem_add(stringpool_tree, str, GINT_TO_POINTER(1));
00054         assert(elem != NULL);
00055     }
00056 
00057     if (take)
00058         g_free(str);
00059     str = (gchar *)mowgli_patricia_elem_get_key(elem);
00060 
00061     g_static_mutex_unlock(&stringpool_mutex);
00062 
00063     return str;
00064 }
00065 
00066 void
00067 stringpool_unref(gchar *str)
00068 {
00069     if (str == NULL)
00070         return;
00071 
00072     if (strlen(str) > MAXLEN)
00073         return g_free(str);
00074 
00075     g_return_if_fail(stringpool_tree != NULL);
00076 
00077     g_static_mutex_lock(&stringpool_mutex);
00078 
00079     mowgli_patricia_elem_t *elem = mowgli_patricia_elem_find(stringpool_tree, str);
00080     assert(elem != NULL);
00081 
00082     gint refcount = GPOINTER_TO_INT(mowgli_patricia_elem_get_data(elem));
00083     if (refcount == 1)
00084         mowgli_patricia_elem_delete(stringpool_tree, elem);
00085     else
00086         mowgli_patricia_elem_set_data(elem, GINT_TO_POINTER(refcount - 1));
00087 
00088     g_static_mutex_unlock(&stringpool_mutex);
00089 }