ib->n_elems = n_elems;
ib->id_size = id_size;
ib->salt = salt;
+ ib->singleton = NULL;
ib->count = tal_arrz(ib, s32, n_elems);
ib->idsum = tal_arrz(ib, u8, id_size * n_elems);
if (!ib->count || !ib->idsum)
return ib;
}
+void invbloom_singleton_cb_(struct invbloom *ib,
+ void (*cb)(struct invbloom *,
+ size_t bucket, void *),
+ void *data)
+{
+ ib->singleton = cb;
+ ib->singleton_data = data;
+}
+
static size_t hash_bucket(const struct invbloom *ib, const void *id, size_t i)
{
return hash((const char *)id, ib->id_size, ib->salt+i*7) % ib->n_elems;
return (u8 *)ib->idsum + bucket * ib->id_size;
}
+static void check_for_singleton(struct invbloom *ib, size_t bucket)
+{
+ if (!ib->singleton)
+ return;
+
+ if (ib->count[bucket] != 1 && ib->count[bucket] != -1)
+ return;
+
+ ib->singleton(ib, bucket, ib->singleton_data);
+}
+
static void add_to_bucket(struct invbloom *ib, size_t n, const u8 *id)
{
size_t i;
for (i = 0; i < ib->id_size; i++)
idsum[i] ^= id[i];
+
+ check_for_singleton(ib, n);
}
static void remove_from_bucket(struct invbloom *ib, size_t n, const u8 *id)
ib->count[n]--;
for (i = 0; i < ib->id_size; i++)
idsum[i] ^= id[i];
+
+ check_for_singleton(ib, n);
}
void invbloom_insert(struct invbloom *ib, const void *id)
assert(ib1->id_size == ib2->id_size);
assert(ib1->salt == ib2->salt);
- for (i = 0; i < ib1->n_elems; i++)
- ib1->count[i] -= ib2->count[i];
-
for (i = 0; i < ib1->n_elems * ib1->id_size; i++)
ib1->idsum[i] ^= ib2->idsum[i];
+
+ for (i = 0; i < ib1->n_elems; i++) {
+ ib1->count[i] -= ib2->count[i];
+ check_for_singleton(ib1, i);
+ }
}
bool invbloom_empty(const struct invbloom *ib)