bloomfilt.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #ifndef TOR_BLOOMFILT_H
  6. #define TOR_BLOOMFILT_H
  7. #include "orconfig.h"
  8. #include "lib/cc/torint.h"
  9. #include "lib/container/bitarray.h"
  10. #include "siphash.h"
  11. /** A set of digests, implemented as a Bloom filter. */
  12. typedef struct {
  13. int mask; /**< One less than the number of bits in <b>ba</b>; always one less
  14. * than a power of two. */
  15. bitarray_t *ba; /**< A bit array to implement the Bloom filter. */
  16. } digestset_t;
  17. #define BIT(n) ((n) & set->mask)
  18. /** Add the digest <b>digest</b> to <b>set</b>. */
  19. static inline void
  20. digestset_add(digestset_t *set, const char *digest)
  21. {
  22. const uint64_t x = siphash24g(digest, 20);
  23. const uint32_t d1 = (uint32_t) x;
  24. const uint32_t d2 = (uint32_t)( (x>>16) + x);
  25. const uint32_t d3 = (uint32_t)( (x>>32) + x);
  26. const uint32_t d4 = (uint32_t)( (x>>48) + x);
  27. bitarray_set(set->ba, BIT(d1));
  28. bitarray_set(set->ba, BIT(d2));
  29. bitarray_set(set->ba, BIT(d3));
  30. bitarray_set(set->ba, BIT(d4));
  31. }
  32. /** If <b>digest</b> is in <b>set</b>, return nonzero. Otherwise,
  33. * <em>probably</em> return zero. */
  34. static inline int
  35. digestset_contains(const digestset_t *set, const char *digest)
  36. {
  37. const uint64_t x = siphash24g(digest, 20);
  38. const uint32_t d1 = (uint32_t) x;
  39. const uint32_t d2 = (uint32_t)( (x>>16) + x);
  40. const uint32_t d3 = (uint32_t)( (x>>32) + x);
  41. const uint32_t d4 = (uint32_t)( (x>>48) + x);
  42. return bitarray_is_set(set->ba, BIT(d1)) &&
  43. bitarray_is_set(set->ba, BIT(d2)) &&
  44. bitarray_is_set(set->ba, BIT(d3)) &&
  45. bitarray_is_set(set->ba, BIT(d4));
  46. }
  47. #undef BIT
  48. digestset_t *digestset_new(int max_elements);
  49. void digestset_free_(digestset_t* set);
  50. #define digestset_free(set) FREE_AND_NULL(digestset_t, digestset_free_, (set))
  51. #endif /* !defined(TOR_CONTAINER_H) */