xref: /freebsd/sys/contrib/ck/include/ck_hs.h (revision 74e9b5f2)
11fb62fb0SOlivier Houchard /*
21fb62fb0SOlivier Houchard  * Copyright 2012-2015 Samy Al Bahra.
31fb62fb0SOlivier Houchard  * All rights reserved.
41fb62fb0SOlivier Houchard  *
51fb62fb0SOlivier Houchard  * Redistribution and use in source and binary forms, with or without
61fb62fb0SOlivier Houchard  * modification, are permitted provided that the following conditions
71fb62fb0SOlivier Houchard  * are met:
81fb62fb0SOlivier Houchard  * 1. Redistributions of source code must retain the above copyright
91fb62fb0SOlivier Houchard  *    notice, this list of conditions and the following disclaimer.
101fb62fb0SOlivier Houchard  * 2. Redistributions in binary form must reproduce the above copyright
111fb62fb0SOlivier Houchard  *    notice, this list of conditions and the following disclaimer in the
121fb62fb0SOlivier Houchard  *    documentation and/or other materials provided with the distribution.
131fb62fb0SOlivier Houchard  *
141fb62fb0SOlivier Houchard  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
151fb62fb0SOlivier Houchard  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161fb62fb0SOlivier Houchard  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171fb62fb0SOlivier Houchard  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
181fb62fb0SOlivier Houchard  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191fb62fb0SOlivier Houchard  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201fb62fb0SOlivier Houchard  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211fb62fb0SOlivier Houchard  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221fb62fb0SOlivier Houchard  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231fb62fb0SOlivier Houchard  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241fb62fb0SOlivier Houchard  * SUCH DAMAGE.
251fb62fb0SOlivier Houchard  */
261fb62fb0SOlivier Houchard 
271fb62fb0SOlivier Houchard #ifndef CK_HS_H
281fb62fb0SOlivier Houchard #define CK_HS_H
291fb62fb0SOlivier Houchard 
301fb62fb0SOlivier Houchard #include <ck_cc.h>
311fb62fb0SOlivier Houchard #include <ck_malloc.h>
321fb62fb0SOlivier Houchard #include <ck_md.h>
331fb62fb0SOlivier Houchard #include <ck_pr.h>
341fb62fb0SOlivier Houchard #include <ck_stdint.h>
351fb62fb0SOlivier Houchard #include <ck_stdbool.h>
361fb62fb0SOlivier Houchard #include <ck_stddef.h>
371fb62fb0SOlivier Houchard 
381fb62fb0SOlivier Houchard /*
391fb62fb0SOlivier Houchard  * Indicates a single-writer many-reader workload. Mutually
401fb62fb0SOlivier Houchard  * exclusive with CK_HS_MODE_MPMC
411fb62fb0SOlivier Houchard  */
421fb62fb0SOlivier Houchard #define CK_HS_MODE_SPMC		1
431fb62fb0SOlivier Houchard 
441fb62fb0SOlivier Houchard /*
451fb62fb0SOlivier Houchard  * Indicates that values to be stored are not pointers but
461fb62fb0SOlivier Houchard  * values. Allows for full precision. Mutually exclusive
471fb62fb0SOlivier Houchard  * with CK_HS_MODE_OBJECT.
481fb62fb0SOlivier Houchard  */
491fb62fb0SOlivier Houchard #define CK_HS_MODE_DIRECT	2
501fb62fb0SOlivier Houchard 
511fb62fb0SOlivier Houchard /*
521fb62fb0SOlivier Houchard  * Indicates that the values to be stored are pointers.
531fb62fb0SOlivier Houchard  * Allows for space optimizations in the presence of pointer
541fb62fb0SOlivier Houchard  * packing. Mutually exclusive with CK_HS_MODE_DIRECT.
551fb62fb0SOlivier Houchard  */
561fb62fb0SOlivier Houchard #define CK_HS_MODE_OBJECT	8
571fb62fb0SOlivier Houchard 
581fb62fb0SOlivier Houchard /*
591fb62fb0SOlivier Houchard  * Indicates a delete-heavy workload. This will reduce the
601fb62fb0SOlivier Houchard  * need for garbage collection at the cost of approximately
611fb62fb0SOlivier Houchard  * 12% to 20% increased memory usage.
621fb62fb0SOlivier Houchard  */
631fb62fb0SOlivier Houchard #define CK_HS_MODE_DELETE	16
641fb62fb0SOlivier Houchard 
651fb62fb0SOlivier Houchard /* Currently unsupported. */
661fb62fb0SOlivier Houchard #define CK_HS_MODE_MPMC    (void)
671fb62fb0SOlivier Houchard 
681fb62fb0SOlivier Houchard /*
691fb62fb0SOlivier Houchard  * Hash callback function.
701fb62fb0SOlivier Houchard  */
711fb62fb0SOlivier Houchard typedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);
721fb62fb0SOlivier Houchard 
731fb62fb0SOlivier Houchard /*
741fb62fb0SOlivier Houchard  * Returns pointer to object if objects are equivalent.
751fb62fb0SOlivier Houchard  */
761fb62fb0SOlivier Houchard typedef bool ck_hs_compare_cb_t(const void *, const void *);
771fb62fb0SOlivier Houchard 
781fb62fb0SOlivier Houchard #if defined(CK_MD_POINTER_PACK_ENABLE) && defined(CK_MD_VMA_BITS)
791fb62fb0SOlivier Houchard #define CK_HS_PP
801fb62fb0SOlivier Houchard #define CK_HS_KEY_MASK ((1U << ((sizeof(void *) * 8) - CK_MD_VMA_BITS)) - 1)
811fb62fb0SOlivier Houchard #endif
821fb62fb0SOlivier Houchard 
831fb62fb0SOlivier Houchard struct ck_hs_map;
841fb62fb0SOlivier Houchard struct ck_hs {
851fb62fb0SOlivier Houchard 	struct ck_malloc *m;
861fb62fb0SOlivier Houchard 	struct ck_hs_map *map;
871fb62fb0SOlivier Houchard 	unsigned int mode;
881fb62fb0SOlivier Houchard 	unsigned long seed;
891fb62fb0SOlivier Houchard 	ck_hs_hash_cb_t *hf;
901fb62fb0SOlivier Houchard 	ck_hs_compare_cb_t *compare;
911fb62fb0SOlivier Houchard };
921fb62fb0SOlivier Houchard typedef struct ck_hs ck_hs_t;
931fb62fb0SOlivier Houchard 
941fb62fb0SOlivier Houchard struct ck_hs_stat {
951fb62fb0SOlivier Houchard 	unsigned long tombstones;
961fb62fb0SOlivier Houchard 	unsigned long n_entries;
971fb62fb0SOlivier Houchard 	unsigned int probe_maximum;
981fb62fb0SOlivier Houchard };
991fb62fb0SOlivier Houchard 
1001fb62fb0SOlivier Houchard struct ck_hs_iterator {
1011fb62fb0SOlivier Houchard 	void **cursor;
1021fb62fb0SOlivier Houchard 	unsigned long offset;
103271ce402SOlivier Houchard 	struct ck_hs_map *map;
1041fb62fb0SOlivier Houchard };
1051fb62fb0SOlivier Houchard typedef struct ck_hs_iterator ck_hs_iterator_t;
1061fb62fb0SOlivier Houchard 
107271ce402SOlivier Houchard #define CK_HS_ITERATOR_INITIALIZER { NULL, 0, NULL }
1081fb62fb0SOlivier Houchard 
1091fb62fb0SOlivier Houchard /* Convenience wrapper to table hash function. */
1101fb62fb0SOlivier Houchard #define CK_HS_HASH(T, F, K) F((K), (T)->seed)
1111fb62fb0SOlivier Houchard 
112*74e9b5f2SOlivier Houchard /* Computes the hash of n bytes of k for the specified hash map. */
113*74e9b5f2SOlivier Houchard static inline unsigned long
ck_hs_hash(const struct ck_hs * hs,const void * k)114*74e9b5f2SOlivier Houchard ck_hs_hash(const struct ck_hs *hs, const void *k)
115*74e9b5f2SOlivier Houchard {
116*74e9b5f2SOlivier Houchard 
117*74e9b5f2SOlivier Houchard 	return hs->hf(k, hs->seed);
118*74e9b5f2SOlivier Houchard }
119*74e9b5f2SOlivier Houchard 
1201fb62fb0SOlivier Houchard typedef void *ck_hs_apply_fn_t(void *, void *);
1211fb62fb0SOlivier Houchard bool ck_hs_apply(ck_hs_t *, unsigned long, const void *, ck_hs_apply_fn_t *, void *);
1221fb62fb0SOlivier Houchard void ck_hs_iterator_init(ck_hs_iterator_t *);
1231fb62fb0SOlivier Houchard bool ck_hs_next(ck_hs_t *, ck_hs_iterator_t *, void **);
124271ce402SOlivier Houchard bool ck_hs_next_spmc(ck_hs_t *, ck_hs_iterator_t *, void **);
1251fb62fb0SOlivier Houchard bool ck_hs_move(ck_hs_t *, ck_hs_t *, ck_hs_hash_cb_t *,
1261fb62fb0SOlivier Houchard     ck_hs_compare_cb_t *, struct ck_malloc *);
1271fb62fb0SOlivier Houchard bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *,
1281fb62fb0SOlivier Houchard     ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);
1291fb62fb0SOlivier Houchard void ck_hs_destroy(ck_hs_t *);
1301fb62fb0SOlivier Houchard void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
1311fb62fb0SOlivier Houchard bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
1321fb62fb0SOlivier Houchard bool ck_hs_put_unique(ck_hs_t *, unsigned long, const void *);
1331fb62fb0SOlivier Houchard bool ck_hs_set(ck_hs_t *, unsigned long, const void *, void **);
1341fb62fb0SOlivier Houchard bool ck_hs_fas(ck_hs_t *, unsigned long, const void *, void **);
1351fb62fb0SOlivier Houchard void *ck_hs_remove(ck_hs_t *, unsigned long, const void *);
1361fb62fb0SOlivier Houchard bool ck_hs_grow(ck_hs_t *, unsigned long);
1371fb62fb0SOlivier Houchard bool ck_hs_rebuild(ck_hs_t *);
1381fb62fb0SOlivier Houchard bool ck_hs_gc(ck_hs_t *, unsigned long, unsigned long);
1391fb62fb0SOlivier Houchard unsigned long ck_hs_count(ck_hs_t *);
1401fb62fb0SOlivier Houchard bool ck_hs_reset(ck_hs_t *);
1411fb62fb0SOlivier Houchard bool ck_hs_reset_size(ck_hs_t *, unsigned long);
1421fb62fb0SOlivier Houchard void ck_hs_stat(ck_hs_t *, struct ck_hs_stat *);
1431fb62fb0SOlivier Houchard 
1441fb62fb0SOlivier Houchard #endif /* CK_HS_H */
145