str-table.c revision 087272dde587c41c2605fe59340d7fa7021b6892
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2014-2015 Dovecot authors, see the included COPYING file */
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen#include "lib.h"
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen#include "hash.h"
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen#include "str-table.h"
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainenstruct str_table {
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen HASH_TABLE(char *, void *) hash;
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen};
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainenstruct str_table *str_table_init(void)
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen{
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen struct str_table *table;
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen table = i_new(struct str_table, 1);
6daca8888bbf2b5bf26903cf397d5219ea752241Timo Sirainen hash_table_create(&table->hash, default_pool, 0, str_hash, strcmp);
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen return table;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen}
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainenvoid str_table_deinit(struct str_table **_table)
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen{
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen struct str_table *table = *_table;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen struct hash_iterate_context *iter;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen char *key;
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen void *value;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen *_table = NULL;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
e02846284483d9d3c4b72835cd3dd6cc7f7e6740Timo Sirainen iter = hash_table_iterate_init(table->hash);
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen while (hash_table_iterate(iter, table->hash, &key, &value))
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen i_free(key);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen hash_table_iterate_deinit(&iter);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen hash_table_destroy(&table->hash);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen i_free(table);
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen}
d8eedfaad386a8776e4931086b039b72e1ad38c4Timo Sirainen
acc8c0647873b1c847bfa362ddefd0d219d0aa91Timo Sirainenbool str_table_is_empty(struct str_table *table)
acc8c0647873b1c847bfa362ddefd0d219d0aa91Timo Sirainen{
acc8c0647873b1c847bfa362ddefd0d219d0aa91Timo Sirainen return hash_table_count(table->hash) == 0;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen}
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainenconst char *str_table_ref(struct str_table *table, const char *str)
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen{
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen char *key;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen void *value;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen unsigned int ref;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen if (!hash_table_lookup_full(table->hash, str, &key, &value)) {
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen key = i_strdup(str);
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen ref = 1;
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen } else {
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen ref = POINTER_CAST_TO(value, unsigned int);
2978aafcf8c306adc2e012aed00546a63c677784Timo Sirainen i_assert(ref > 0);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen ref++;
26bedc1f8aace67ff8f19f625a403a097017845aTimo Sirainen }
26bedc1f8aace67ff8f19f625a403a097017845aTimo Sirainen hash_table_update(table->hash, key, POINTER_CAST(ref));
26bedc1f8aace67ff8f19f625a403a097017845aTimo Sirainen return key;
26bedc1f8aace67ff8f19f625a403a097017845aTimo Sirainen}
26bedc1f8aace67ff8f19f625a403a097017845aTimo Sirainen
2dc6cf8bad599bfe9129bb496539a08ee3631cc0Timo Sirainenvoid str_table_unref(struct str_table *table, const char **str)
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen{
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen char *key;
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen void *value;
7c7d2244502af05f77c74736dc1aec0123fdba80Timo Sirainen unsigned int ref;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen if (!hash_table_lookup_full(table->hash, *str, &key, &value))
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen i_unreached();
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen ref = POINTER_CAST_TO(value, unsigned int);
9446c7a5d400cba60d097c528bd08312552438e3Timo Sirainen i_assert(ref > 0);
9446c7a5d400cba60d097c528bd08312552438e3Timo Sirainen if (--ref > 0)
9446c7a5d400cba60d097c528bd08312552438e3Timo Sirainen hash_table_update(table->hash, key, POINTER_CAST(ref));
f3e1593a7d9b02090575fb20db90a235e10145a5Timo Sirainen else {
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen hash_table_remove(table->hash, key);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen i_free(key);
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen }
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen *str = NULL;
b494ffed8ded8d170d9ace3dc607b1d278048241Timo Sirainen}
aff1e150e13980354cfd794c74dac76a791a641eTimo Sirainen