]> git.ozlabs.org Git - ccan/blob - ccan/invbloom/invbloom.h
d30223d2fe3e4d6f53e92c26217e3c47123bc114
[ccan] / ccan / invbloom / invbloom.h
1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #ifndef CCAN_INVBLOOM_H
3 #define CCAN_INVBLOOM_H
4 #include <ccan/short_types/short_types.h>
5 #include <ccan/typesafe_cb/typesafe_cb.h>
6 #include <ccan/tal/tal.h>
7
8 struct invbloom {
9         size_t n_elems;
10         size_t id_size;
11         u32 salt;
12         s32 *count; /* [n_elems] */
13         u8 *idsum; /* [n_elems][id_size] */
14         void (*singleton)(struct invbloom *ib, size_t elem, void *);
15         void *singleton_data;
16 };
17
18 /**
19  * invbloom_new - create a new invertable bloom lookup table
20  * @ctx: context to tal() from, or NULL.
21  * @type: type to place into the buckets (must not contain padding)
22  * @n_elems: number of entries in table
23  * @salt: 32 bit seed for table
24  *
25  * Returns a new table, which can be freed with tal_free().
26  */
27 #define invbloom_new(ctx, type, n_elems, salt)  \
28         invbloom_new_((ctx), sizeof(type), (n_elems), (salt))
29 struct invbloom *invbloom_new_(const tal_t *ctx,
30                                size_t id_size,
31                                size_t n_elems, u32 salt);
32
33 /**
34  * invbloom_singleton_cb - set callback for when a singleton is found.
35  * @ib: the invertable bloom lookup table.
36  * @cb: the function to call (or NULL for none)
37  * @data: the data to hand to the function.
38  *
39  * This may be called by any function which mutates the table,
40  * possibly multiple times for a single call.  The particular
41  * @ib bucket will be consistent, but the rest of the table may
42  * not be.
43  */
44 #define invbloom_singleton_cb(ib, cb, data)                     \
45         invbloom_singleton_cb_((ib),                            \
46                typesafe_cb_preargs(void, void *, (cb), (data),  \
47                                    struct invbloom *, size_t), (data))
48
49 void invbloom_singleton_cb_(struct invbloom *ib,
50                             void (*cb)(struct invbloom *,
51                                        size_t bucket, void *),
52                             void *data);
53
54 /**
55  * invbloom_insert - add a new element
56  * @ib: the invertable bloom lookup table.
57  * @elem: the element
58  *
59  * This is guaranteed to be the inverse of invbloom_delete.
60  */
61 void invbloom_insert(struct invbloom *ib, const void *elem);
62
63 /**
64  * invbloom_delete - remove an element
65  * @ib: the invertable bloom lookup table.
66  * @elem: the element
67  *
68  * Note that this doesn't check the element was previously added (as
69  * that can not be done in general anyway).
70  *
71  * This is guaranteed to be the inverse of invbloom_delete.
72  */
73 void invbloom_delete(struct invbloom *ib, const void *elem);
74
75 /**
76  * invbloom_get - check if an element is (probably) in the table.
77  * @ib: the invertable bloom lookup table.
78  * @elem: the element
79  *
80  * This may return a false negative if the table is too full.
81  *
82  * It will only return a false positive if deletions and insertions
83  * don't match, and have managed to produce a result which matches the
84  * element.  This is much less likely.
85  */
86 bool invbloom_get(const struct invbloom *ib, const void *elem);
87
88 /**
89  * invbloom_extract - try to recover an entry added to a bloom lookup table.
90  * @ctx: the context to tal() the return value from.
91  * @ib: the invertable bloom lookup table.
92  *
93  * This may be able to recover (and delete) an element which was
94  * invbloom_insert()ed into the table (and not deleted).  This will
95  * not work if the table is too full.
96  *
97  * It may return a bogus element if deletions and insertions don't
98  * match.
99  */
100 void *invbloom_extract(const tal_t *ctx, struct invbloom *ib);
101
102 /**
103  * invbloom_extract_negative - try to recover an entry deleted from a bloom lookup table.
104  * @ctx: the context to tal() the return value from.
105  * @ib: the invertable bloom lookup table.
106  *
107  * This may be able to recover (and insert/undo) an element which was
108  * invbloom_delete()ed from the table (and not inserted).  This will
109  * not work if the table is too full.
110  *
111  * It may return a bogus element if deletions and insertions don't
112  * match.
113  */
114 void *invbloom_extract_negative(const tal_t *ctx, struct invbloom *ib);
115
116 /**
117  * invbloom_subtract - return the differences of two IBLTs.
118  * @ib1: the invertable bloom lookup table to alter
119  * @ib2: the invertable bloom lookup table to subtract.
120  *
121  * This produces exactly the same result as if a new table had all the
122  * elements only in @ib1 inserted, then all the elements onlt in @ib2
123  * deleted.
124  *
125  * ie. if @ib1 and @ib2 are similar, the result may be a usable by
126  * invbloom_extract and invbloom_extract_negative.
127  */
128 void invbloom_subtract(struct invbloom *ib1, const struct invbloom *ib2);
129
130 /**
131  * invbloom_empty - is an invertable bloom lookup table completely clean?
132  * @ib: the invertable bloom lookup table
133  *
134  * This is always true if @ib has had the same elements inserted and
135  * deleted.  It is far less likely to be true if different ones were
136  * deleted than inserted.
137  */
138 bool invbloom_empty(const struct invbloom *ib);
139 #endif /* CCAN_INVBLOOM_H */