/* * e-poolv.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see <http://www.gnu.org/licenses/> * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "e-poolv.h" #include <string.h> #include <camel/camel.h> struct _EPoolv { guchar length; gchar *s[1]; }; static GHashTable *poolv_pool; static CamelMemPool *poolv_mempool; G_LOCK_DEFINE_STATIC (poolv); /** * e_poolv_new: * @size: The number of elements in the poolv, maximum of 254 elements. * * Create a new #EPoolv: a string vector which shares a global string * pool. An #EPoolv can be used to work with arrays of strings which * save memory by eliminating duplicated allocations of the same string. * * This is useful when you have a log of read-only strings that do not * go away and are duplicated a lot, such as email headers. * * Returns: a new #EPoolv **/ EPoolv * e_poolv_new (guint size) { EPoolv *poolv; g_return_val_if_fail (size < 255, NULL); poolv = g_malloc0 (sizeof (*poolv) + (size - 1) * sizeof (gchar *)); poolv->length = size; G_LOCK (poolv); if (!poolv_pool) poolv_pool = g_hash_table_new (g_str_hash, g_str_equal); if (!poolv_mempool) poolv_mempool = camel_mempool_new ( 32 * 1024, 512, CAMEL_MEMPOOL_ALIGN_BYTE); G_UNLOCK (poolv); return poolv; } /** * e_poolv_set: * @poolv: pooled string vector * @index: index in vector of string * @str: string to set * @freeit: whether the caller is releasing its reference to the * string * * Set a string vector reference. If the caller will no longer be * referencing the string, freeit should be TRUE. Otherwise, this * will duplicate the string if it is not found in the pool. * * Returns: @poolv **/ EPoolv * e_poolv_set (EPoolv *poolv, gint index, gchar *str, gint freeit) { g_return_val_if_fail (poolv != NULL, NULL); g_return_val_if_fail (index >= 0 && index < poolv->length, NULL); if (!str) { poolv->s[index] = NULL; return poolv; } G_LOCK (poolv); if ((poolv->s[index] = g_hash_table_lookup (poolv_pool, str)) != NULL) { } else { poolv->s[index] = camel_mempool_strdup (poolv_mempool, str); g_hash_table_insert (poolv_pool, poolv->s[index], poolv->s[index]); } G_UNLOCK (poolv); if (freeit) g_free (str); return poolv; } /** * e_poolv_get: * @poolv: pooled string vector * @index: index in vector of string * * Retrieve a string by index. This could possibly just be a macro. * * Since the pool is never freed, this string does not need to be * duplicated, but should not be modified. * * Returns: string at that index. **/ const gchar * e_poolv_get (EPoolv *poolv, gint index) { g_return_val_if_fail (poolv != NULL, NULL); g_return_val_if_fail (index >= 0 && index < poolv->length, NULL); return poolv->s[index] ? poolv->s[index] : ""; } /** * e_poolv_destroy: * @poolv: pooled string vector to free * * Free a pooled string vector. This doesn't free the strings from * the vector, however. **/ void e_poolv_destroy (EPoolv *poolv) { g_return_if_fail (poolv != NULL); g_free (poolv); } 2</option> <option value='branches/2016Q3'>branches/2016Q3</option> <option value='branches/2016Q4'>branches/2016Q4</option> <option value='branches/2017Q1'>branches/2017Q1</option> <option value='branches/2017Q2'>branches/2017Q2</option> <option value='branches/2017Q3'>branches/2017Q3</option> <option value='branches/2017Q4'>branches/2017Q4</option> <option value='branches/2018Q1'>branches/2018Q1</option> <option value='branches/2018Q2'>branches/2018Q2</option> <option value='branches/2018Q3'>branches/2018Q3</option> <option value='branches/2018Q4'>branches/2018Q4</option> <option value='branches/2019Q1'>branches/2019Q1</option> <option value='branches/2019Q2'>branches/2019Q2</option> <option value='branches/2019Q3'>branches/2019Q3</option> <option value='branches/2019Q4'>branches/2019Q4</option> <option value='branches/2020Q1'>branches/2020Q1</option> <option value='branches/2020Q2'>branches/2020Q2</option> <option value='branches/2020Q3'>branches/2020Q3</option> <option value='branches/2020Q4'>branches/2020Q4</option> <option value='branches/2021Q1'>branches/2021Q1</option> <option value='branches/RELEASE_8_4_0'>branches/RELEASE_8_4_0</option> <option value='branches/RELENG_2_1_0'>branches/RELENG_2_1_0</option> <option value='branches/RELENG_2_2'>branches/RELENG_2_2</option> <option value='branches/RELENG_9_1_0'>branches/RELENG_9_1_0</option> <option value='branches/RELENG_9_2_0'>branches/RELENG_9_2_0</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/eslint-utils-1.4.3'>dependabot/npm_and_yarn/devel/electron4/files/eslint-utils-1.4.3</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/lodash-4.17.15'>dependabot/npm_and_yarn/devel/electron4/files/lodash-4.17.15</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/lodash.merge-4.6.2'>dependabot/npm_and_yarn/devel/electron4/files/lodash.merge-4.6.2</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/lodash.template-4.5.0'>dependabot/npm_and_yarn/devel/electron4/files/lodash.template-4.5.0</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/minimist-1.2.2'>dependabot/npm_and_yarn/devel/electron4/files/minimist-1.2.2</option> <option value='dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2'>dependabot/npm_and_yarn/devel/electron4/files/mixin-deep-1.3.2</option> <option value='main' selected='selected'>main</option> <option value='master'>master</option> <option value='svn_head'>svn_head</option> </select> <input type='submit' value='switch'/></form></td></tr> <tr><td class='sub'>FreeBSD Ports (https://github.com/freebsd/freebsd-ports)</td><td class='sub right'></td></tr></table> <table class='tabs'><tr><td> <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/about/'>about</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/'>summary</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/refs/?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>refs</a><a class='active' href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/science/v_sim'>log</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/tree/science/v_sim?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>tree</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/commit/science/v_sim?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>commit</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/diff/science/v_sim?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>diff</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/stats/science/v_sim'>stats</a></td><td class='form'><form class='right' method='get' action='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/science/v_sim'> <input type='hidden' name='id' value='8d6597e0bb9591c40fc6d0c6e2159fca51178d56'/><select name='qt'> <option value='grep'>log msg</option> <option value='author'>author</option> <option value='committer'>committer</option> <option value='range'>range</option> </select> <input class='txt' type='search' size='10' name='q' value=''/> <input type='submit' value='search'/> </form> </td></tr></table> <div class='path'>path: <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>root</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/science?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>science</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/science/v_sim?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56'>v_sim</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th></th><th class='left'>Commit message (<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports/log/science/v_sim?id=8d6597e0bb9591c40fc6d0c6e2159fca51178d56&showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Age</th><th class='left'>Files</th><th class='left'>Lines</th></tr>