1*134e1779SJakub Wojciech Klama /*
2*134e1779SJakub Wojciech Klama * Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
3*134e1779SJakub Wojciech Klama * All rights reserved
4*134e1779SJakub Wojciech Klama *
5*134e1779SJakub Wojciech Klama * Redistribution and use in source and binary forms, with or without
6*134e1779SJakub Wojciech Klama * modification, are permitted providing that the following conditions
7*134e1779SJakub Wojciech Klama * are met:
8*134e1779SJakub Wojciech Klama * 1. Redistributions of source code must retain the above copyright
9*134e1779SJakub Wojciech Klama * notice, this list of conditions and the following disclaimer.
10*134e1779SJakub Wojciech Klama * 2. Redistributions in binary form must reproduce the above copyright
11*134e1779SJakub Wojciech Klama * notice, this list of conditions and the following disclaimer in the
12*134e1779SJakub Wojciech Klama * documentation and/or other materials provided with the distribution.
13*134e1779SJakub Wojciech Klama *
14*134e1779SJakub Wojciech Klama * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15*134e1779SJakub Wojciech Klama * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16*134e1779SJakub Wojciech Klama * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*134e1779SJakub Wojciech Klama * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18*134e1779SJakub Wojciech Klama * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*134e1779SJakub Wojciech Klama * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*134e1779SJakub Wojciech Klama * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*134e1779SJakub Wojciech Klama * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22*134e1779SJakub Wojciech Klama * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23*134e1779SJakub Wojciech Klama * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24*134e1779SJakub Wojciech Klama * POSSIBILITY OF SUCH DAMAGE.
25*134e1779SJakub Wojciech Klama *
26*134e1779SJakub Wojciech Klama */
27*134e1779SJakub Wojciech Klama
28*134e1779SJakub Wojciech Klama #ifndef LIB9P_HASHTABLE_H
29*134e1779SJakub Wojciech Klama #define LIB9P_HASHTABLE_H
30*134e1779SJakub Wojciech Klama
31*134e1779SJakub Wojciech Klama #include <pthread.h>
32*134e1779SJakub Wojciech Klama #include <sys/queue.h>
33*134e1779SJakub Wojciech Klama
34*134e1779SJakub Wojciech Klama struct ht {
35*134e1779SJakub Wojciech Klama struct ht_entry * ht_entries;
36*134e1779SJakub Wojciech Klama ssize_t ht_nentries;
37*134e1779SJakub Wojciech Klama pthread_rwlock_t ht_rwlock;
38*134e1779SJakub Wojciech Klama };
39*134e1779SJakub Wojciech Klama
40*134e1779SJakub Wojciech Klama struct ht_entry {
41*134e1779SJakub Wojciech Klama TAILQ_HEAD(, ht_item) hte_items;
42*134e1779SJakub Wojciech Klama };
43*134e1779SJakub Wojciech Klama
44*134e1779SJakub Wojciech Klama struct ht_item {
45*134e1779SJakub Wojciech Klama uint32_t hti_hash;
46*134e1779SJakub Wojciech Klama void * hti_data;
47*134e1779SJakub Wojciech Klama TAILQ_ENTRY(ht_item) hti_link;
48*134e1779SJakub Wojciech Klama };
49*134e1779SJakub Wojciech Klama
50*134e1779SJakub Wojciech Klama struct ht_iter {
51*134e1779SJakub Wojciech Klama struct ht * htit_parent;
52*134e1779SJakub Wojciech Klama struct ht_item * htit_curr;
53*134e1779SJakub Wojciech Klama struct ht_item * htit_next;
54*134e1779SJakub Wojciech Klama ssize_t htit_slot;
55*134e1779SJakub Wojciech Klama };
56*134e1779SJakub Wojciech Klama
57*134e1779SJakub Wojciech Klama #ifdef __clang__
58*134e1779SJakub Wojciech Klama #pragma clang diagnostic push
59*134e1779SJakub Wojciech Klama #pragma clang diagnostic ignored "-Wthread-safety-analysis"
60*134e1779SJakub Wojciech Klama #endif
61*134e1779SJakub Wojciech Klama
62*134e1779SJakub Wojciech Klama /*
63*134e1779SJakub Wojciech Klama * Obtain read-lock on hash table.
64*134e1779SJakub Wojciech Klama */
65*134e1779SJakub Wojciech Klama static inline int
ht_rdlock(struct ht * h)66*134e1779SJakub Wojciech Klama ht_rdlock(struct ht *h)
67*134e1779SJakub Wojciech Klama {
68*134e1779SJakub Wojciech Klama
69*134e1779SJakub Wojciech Klama return (pthread_rwlock_rdlock(&h->ht_rwlock));
70*134e1779SJakub Wojciech Klama }
71*134e1779SJakub Wojciech Klama
72*134e1779SJakub Wojciech Klama /*
73*134e1779SJakub Wojciech Klama * Obtain write-lock on hash table.
74*134e1779SJakub Wojciech Klama */
75*134e1779SJakub Wojciech Klama static inline int
ht_wrlock(struct ht * h)76*134e1779SJakub Wojciech Klama ht_wrlock(struct ht *h)
77*134e1779SJakub Wojciech Klama {
78*134e1779SJakub Wojciech Klama
79*134e1779SJakub Wojciech Klama return (pthread_rwlock_wrlock(&h->ht_rwlock));
80*134e1779SJakub Wojciech Klama }
81*134e1779SJakub Wojciech Klama
82*134e1779SJakub Wojciech Klama /*
83*134e1779SJakub Wojciech Klama * Release lock on hash table.
84*134e1779SJakub Wojciech Klama */
85*134e1779SJakub Wojciech Klama static inline int
ht_unlock(struct ht * h)86*134e1779SJakub Wojciech Klama ht_unlock(struct ht *h)
87*134e1779SJakub Wojciech Klama {
88*134e1779SJakub Wojciech Klama
89*134e1779SJakub Wojciech Klama return (pthread_rwlock_unlock(&h->ht_rwlock));
90*134e1779SJakub Wojciech Klama }
91*134e1779SJakub Wojciech Klama
92*134e1779SJakub Wojciech Klama #ifdef __clang__
93*134e1779SJakub Wojciech Klama #pragma clang diagnostic pop
94*134e1779SJakub Wojciech Klama #endif
95*134e1779SJakub Wojciech Klama
96*134e1779SJakub Wojciech Klama void ht_init(struct ht *h, ssize_t size);
97*134e1779SJakub Wojciech Klama void ht_destroy(struct ht *h);
98*134e1779SJakub Wojciech Klama void *ht_find(struct ht *h, uint32_t hash);
99*134e1779SJakub Wojciech Klama void *ht_find_locked(struct ht *h, uint32_t hash);
100*134e1779SJakub Wojciech Klama int ht_add(struct ht *h, uint32_t hash, void *value);
101*134e1779SJakub Wojciech Klama int ht_remove(struct ht *h, uint32_t hash);
102*134e1779SJakub Wojciech Klama int ht_remove_locked(struct ht *h, uint32_t hash);
103*134e1779SJakub Wojciech Klama int ht_remove_at_iter(struct ht_iter *iter);
104*134e1779SJakub Wojciech Klama void ht_iter(struct ht *h, struct ht_iter *iter);
105*134e1779SJakub Wojciech Klama void *ht_next(struct ht_iter *iter);
106*134e1779SJakub Wojciech Klama
107*134e1779SJakub Wojciech Klama #endif /* LIB9P_HASHTABLE_H */
108