dovecot-2.2: lib: Added str-table API for keeping reference coun...

dovecot at dovecot.org dovecot at dovecot.org
Thu Nov 13 00:26:05 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/4c956747c36f
changeset: 18069:4c956747c36f
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Nov 13 02:24:46 2014 +0200
description:
lib: Added str-table API for keeping reference counted strings in a hash table.

diffstat:

 src/lib/Makefile.am      |   3 +
 src/lib/str-table.c      |  77 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/str-table.h      |  19 +++++++++++
 src/lib/test-lib.c       |   1 +
 src/lib/test-lib.h       |   1 +
 src/lib/test-str-table.c |  33 ++++++++++++++++++++
 6 files changed, 134 insertions(+), 0 deletions(-)

diffs (190 lines):

diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/Makefile.am
--- a/src/lib/Makefile.am	Thu Nov 13 01:41:07 2014 +0200
+++ b/src/lib/Makefile.am	Thu Nov 13 02:24:46 2014 +0200
@@ -126,6 +126,7 @@
 	str.c \
 	str-find.c \
 	str-sanitize.c \
+	str-table.c \
 	strescape.c \
 	strfuncs.c \
 	strnum.c \
@@ -247,6 +248,7 @@
 	str.h \
 	str-find.h \
 	str-sanitize.h \
+	str-table.h \
 	strescape.h \
 	strfuncs.h \
 	strnum.h \
@@ -311,6 +313,7 @@
 	test-strnum.c \
 	test-str-find.c \
 	test-str-sanitize.c \
+	test-str-table.c \
 	test-time-util.c \
 	test-unichar.c \
 	test-utc-mktime.c \
diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/str-table.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/str-table.c	Thu Nov 13 02:24:46 2014 +0200
@@ -0,0 +1,77 @@
+/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "hash.h"
+#include "str-table.h"
+
+struct str_table {
+	HASH_TABLE(char *, void *) hash;
+};
+
+struct str_table *str_table_init(void)
+{
+	struct str_table *table;
+
+	table = i_new(struct str_table, 1);
+	hash_table_create(&table->hash, default_pool, 0, str_hash, strcmp);
+	return table;
+}
+
+void str_table_deinit(struct str_table **_table)
+{
+	struct str_table *table = *_table;
+	struct hash_iterate_context *iter;
+	char *key;
+	void *value;
+
+	*_table = NULL;
+
+	iter = hash_table_iterate_init(table->hash);
+	while (hash_table_iterate(iter, table->hash, &key, &value))
+		i_free(key);
+	hash_table_destroy(&table->hash);
+	i_free(table);
+}
+
+bool str_table_is_empty(struct str_table *table)
+{
+	return hash_table_count(table->hash) == 0;
+}
+
+const char *str_table_ref(struct str_table *table, const char *str)
+{
+	char *key;
+	void *value;
+	unsigned int ref;
+
+	if (!hash_table_lookup_full(table->hash, str, &key, &value)) {
+		key = i_strdup(str);
+		ref = 1;
+	} else {
+		ref = POINTER_CAST_TO(value, unsigned int);
+		i_assert(ref > 0);
+		ref++;
+	}
+	hash_table_update(table->hash, key, POINTER_CAST(ref));
+	return key;
+}
+
+void str_table_unref(struct str_table *table, const char **str)
+{
+	char *key;
+	void *value;
+	unsigned int ref;
+
+	if (!hash_table_lookup_full(table->hash, *str, &key, &value))
+		i_unreached();
+
+	ref = POINTER_CAST_TO(value, unsigned int);
+	i_assert(ref > 0);
+	if (--ref > 0)
+		hash_table_update(table->hash, key, POINTER_CAST(ref));
+	else {
+		hash_table_remove(table->hash, key);
+		i_free(key);
+	}
+	*str = NULL;
+}
diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/str-table.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/str-table.h	Thu Nov 13 02:24:46 2014 +0200
@@ -0,0 +1,19 @@
+#ifndef STR_TABLE_H
+#define STR_TABLE_H
+
+/* Hash table containing string -> refcount. */
+
+struct str_table *str_table_init(void);
+void str_table_deinit(struct str_table **table);
+
+/* Returns TRUE if there are no referenced strings in the table. */
+bool str_table_is_empty(struct str_table *table);
+
+/* Return string allocated from the strtable and increase its reference
+   count. */
+const char *str_table_ref(struct str_table *table, const char *str);
+/* Decrease string's reference count, freeing it if it reaches zero.
+   The str pointer must have been returned by the str_table_ref(). */
+void str_table_unref(struct str_table *table, const char **str);
+
+#endif
diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/test-lib.c
--- a/src/lib/test-lib.c	Thu Nov 13 01:41:07 2014 +0200
+++ b/src/lib/test-lib.c	Thu Nov 13 02:24:46 2014 +0200
@@ -42,6 +42,7 @@
 		test_strnum,
 		test_str_find,
 		test_str_sanitize,
+		test_str_table,
 		test_time_util,
 		test_unichar,
 		test_utc_mktime,
diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/test-lib.h
--- a/src/lib/test-lib.h	Thu Nov 13 01:41:07 2014 +0200
+++ b/src/lib/test-lib.h	Thu Nov 13 02:24:46 2014 +0200
@@ -44,6 +44,7 @@
 void test_strnum(void);
 void test_str_find(void);
 void test_str_sanitize(void);
+void test_str_table(void);
 void test_time_util(void);
 void test_unichar(void);
 void test_utc_mktime(void);
diff -r 9c2bcafcf121 -r 4c956747c36f src/lib/test-str-table.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/test-str-table.c	Thu Nov 13 02:24:46 2014 +0200
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str-table.h"
+
+void test_str_table(void)
+{
+	struct str_table *table;
+	const char *key1, *key2, *key1_copy, *key2_copy;
+
+	test_begin("str_table");
+	table = str_table_init();
+
+	key1 = str_table_ref(table, "str1");
+	key2 = str_table_ref(table, "str2");
+	test_assert(key1 != key2);
+	key1_copy = str_table_ref(table, "str1");
+	test_assert(key1_copy == key1);
+	key2_copy = str_table_ref(table, "str2");
+	test_assert(key2_copy == key2);
+
+	str_table_unref(table, &key1);
+	test_assert(key1 == NULL);
+	str_table_unref(table, &key1_copy);
+
+	str_table_unref(table, &key2);
+	str_table_unref(table, &key2_copy);
+	test_assert(str_table_is_empty(table));
+
+	str_table_deinit(&table);
+	test_assert(table == NULL);
+	test_end();
+}


More information about the dovecot-cvs mailing list