/* * Copyright (C) 2008 Philippe Gerum . * * This library 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) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef _BOILERPLATE_HASH_H #define _BOILERPLATE_HASH_H #include #include #define HASHSLOTS (1<<8) struct hashobj { dref_type(const void *) key; #ifdef CONFIG_XENO_PSHARED char static_key[16]; #endif size_t len; struct holder link; }; struct hash_bucket { struct listobj obj_list; }; struct hash_table { struct hash_bucket table[HASHSLOTS]; pthread_mutex_t lock; }; struct hash_operations { int (*compare)(const void *l, const void *r, size_t len); #ifdef CONFIG_XENO_PSHARED int (*probe)(struct hashobj *oldobj); void *(*alloc)(size_t len); void (*free)(void *key); #endif }; typedef int (*hash_walk_op)(struct hash_table *t, struct hashobj *obj, void *arg); #ifdef CONFIG_XENO_PSHARED /* Private version - h-table is not shareable between processes. */ struct pvhashobj { const void *key; size_t len; struct pvholder link; }; struct pvhash_bucket { struct pvlistobj obj_list; }; struct pvhash_table { struct pvhash_bucket table[HASHSLOTS]; pthread_mutex_t lock; }; struct pvhash_operations { int (*compare)(const void *l, const void *r, size_t len); }; typedef int (*pvhash_walk_op)(struct pvhash_table *t, struct pvhashobj *obj, void *arg); #else /* !CONFIG_XENO_PSHARED */ #define pvhashobj hashobj #define pvhash_bucket hash_bucket #define pvhash_table hash_table #define pvhash_walk_op hash_walk_op #endif /* !CONFIG_XENO_PSHARED */ #ifdef __cplusplus extern "C" { #endif unsigned int __hash_key(const void *key, size_t length, unsigned int c); void __hash_init(void *heap, struct hash_table *t); int __hash_enter(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops, int nodup); static inline void hash_init(struct hash_table *t) { __hash_init(__main_heap, t); } void hash_destroy(struct hash_table *t); static inline int hash_enter(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops) { return __hash_enter(t, key, len, newobj, hops, 1); } static inline int hash_enter_dup(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops) { return __hash_enter(t, key, len, newobj, hops, 0); } int hash_remove(struct hash_table *t, struct hashobj *delobj, const struct hash_operations *hops); struct hashobj *hash_search(struct hash_table *t, const void *key, size_t len, const struct hash_operations *hops); int hash_walk(struct hash_table *t, hash_walk_op walk, void *arg); #ifdef CONFIG_XENO_PSHARED int __hash_enter_probe(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops, int nodup); int __pvhash_enter(struct pvhash_table *t, const void *key, size_t len, struct pvhashobj *newobj, const struct pvhash_operations *hops, int nodup); static inline int hash_enter_probe(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops) { return __hash_enter_probe(t, key, len, newobj, hops, 1); } static inline int hash_enter_probe_dup(struct hash_table *t, const void *key, size_t len, struct hashobj *newobj, const struct hash_operations *hops) { return __hash_enter_probe(t, key, len, newobj, hops, 0); } struct hashobj *hash_search_probe(struct hash_table *t, const void *key, size_t len, const struct hash_operations *hops); void pvhash_init(struct pvhash_table *t); static inline int pvhash_enter(struct pvhash_table *t, const void *key, size_t len, struct pvhashobj *newobj, const struct pvhash_operations *hops) { return __pvhash_enter(t, key, len, newobj, hops, 1); } static inline int pvhash_enter_dup(struct pvhash_table *t, const void *key, size_t len, struct pvhashobj *newobj, const struct pvhash_operations *hops) { return __pvhash_enter(t, key, len, newobj, hops, 0); } int pvhash_remove(struct pvhash_table *t, struct pvhashobj *delobj, const struct pvhash_operations *hops); struct pvhashobj *pvhash_search(struct pvhash_table *t, const void *key, size_t len, const struct pvhash_operations *hops); int pvhash_walk(struct pvhash_table *t, pvhash_walk_op walk, void *arg); #else /* !CONFIG_XENO_PSHARED */ #define pvhash_init hash_init #define pvhash_enter hash_enter #define pvhash_enter_dup hash_enter_dup #define pvhash_remove hash_remove #define pvhash_search hash_search #define pvhash_walk hash_walk #define pvhash_operations hash_operations #endif /* !CONFIG_XENO_PSHARED */ #ifdef __cplusplus } #endif #endif /* _BOILERPLATE_HASH_H */