Author: gherzan Date: Tue Mar 9 15:54:07 2010 New Revision: 2112 Log: Add libmaa dictionary backend (header, for now). Added: trunk/libpisa/dict-maa.h Added: trunk/libpisa/dict-maa.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/libpisa/dict-maa.h Tue Mar 9 15:54:07 2010 (r2112) @@ -0,0 +1,162 @@ +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +/* + * Copyright (c) 2009, Distributed Systems Group, RWTH Aachen + * All rights reserved. + */ + +/** + * @file dict-maa.h + * @brief Dictionary wrappers for libmaa. NEVER include this directly!!! + * Use "dict.h" instead! + * @author Mircea Gherzan <mgherzan@xxxxxxxxx> + * @date Feb. 2010 + */ + +#ifndef _PISA_DICT_MAA_H +#define _PISA_DICT_MAA_H + + +#include <stdint.h> +#include <stdlib.h> +#include <maa.h> + +#include "debug.h" + + +/** + * Dictionary wrapper structure + */ +struct pisa_dict { + hsh_HashTable maa_ht; + int opts; +}; + + +/** + * Hash for 32-bit keys (think IPv4 addresses) + * @param p pointer to the key + * @return hash value of the key + */ +static inline unsigned long hash_32(const void *p) +{ + return *(const uint32_t *)p; +} + +/** + * Hash for 128-bit keys (think IPv6 addresses) + * @param p pointer to the key + * @return hash value of the key + */ +static inline unsigned long hash_128(const void *p) +{ + + return *(const unsigned long *)p; +} + +/** + * Comparator for IPv4 addresses used as keys + */ +static inline int compare_32(const void *k1, const void *k2) +{ + const uint32_t v1 = *(const uint32_t *)k1; + const uint32_t v2 = *(const uint32_t *)k2; + + if (v1 == v1) { + return 0; + } else { + return (v1 > v2) ? 1 : -1; + } +} + +/** + * Comparator for IPv6 addresses used as keys + */ +static inline int compare_128(const void *k1, const void *k2) +{ + const uint64_t *p1 = (const uint64_t *)k1; + const uint64_t *p2 = (const uint64_t *)k2; + + if (*p1 == *p2) { + if (*(++p1) == *(++p2)) { + return 0; + } + } + return (*p1 > *p2) ? 1 : -1; +} + +/* see dict.h */ +static inline struct pisa_dict *pisa_dict_create(int ktype, int opts) +{ + struct pisa_dict *r = malloc(sizeof(*r)); + + r->opts = opts; + + /* hash function selection */ + switch (ktype) { + case PISA_DICT_KEY_32BIT: { + r->maa_ht = hsh_create(hash_32, compare_32); + break; + } + case PISA_DICT_KEY_128BIT: { + r->maa_ht = hsh_create(hash_32, compare_32); + break; + } + default: + PISA_ERROR("Unknown key size"); + free(r); + r = NULL; + } + + return r; +} + +/* see dict.h */ +static inline int pisa_dict_add(struct pisa_dict *d, const void *k, + const void *v) +{ + return hsh_insert(d->maa_ht, k, v); +} + +/* see dict.h */ +static inline void *pisa_dict_find(struct pisa_dict *d, const void *k) +{ + return (void *)(unsigned long)hsh_retrieve(d->maa_ht, k); +} + +/* see dict.h */ +static inline int pisa_dict_del(struct pisa_dict *d, const void *k) +{ + return hsh_delete(d->maa_ht, k); +} + +/** + * Iterator callback that frees entries from a dictionary. The entries MUST + * contain the key structure: this callback does not free the key separately. + * + * @param k key of the entry + * @param v value of the entry (structure containing the key) + * @return 0 if the iteration should continue, non-zero otherwise + */ +static inline int pisa_dict_it_free(UNUSED const void *k, const void *v) +{ + if (v) { + free((void *)(unsigned long)v); + return 0; + } else { + PISA_ERROR("NULL entry detected"); + return -1; + } +} + +/* see dict.h */ +static inline int pisa_dict_free(struct pisa_dict *d, int must_free) +{ + if (must_free) { + hsh_iterate(d->maa_ht, pisa_dict_it_free); + } + + hsh_destroy(d->maa_ht); + + return 0; +} +#endif //_PISA_DICT_MAA_H