diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-04-08 17:06:41 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-04-08 17:06:41 +0000 |
commit | a627407fcba1d5b1671e5789f420e4b5f8b63f99 (patch) | |
tree | e15ea16047c2352de2100aaa816ead54232cb236 /src/common/container.h | |
parent | 0c9efd6a1e252c2d6f495d158fdc1ec6877e0f10 (diff) | |
download | tor-a627407fcba1d5b1671e5789f420e4b5f8b63f99.tar.gz tor-a627407fcba1d5b1671e5789f420e4b5f8b63f99.zip |
r19233@catbus: nickm | 2008-04-08 13:06:34 -0400
When we remove old routers, use Bloom filters rather than a digestmap-based set in order to tell which ones we absolutely need to keep. This will save us roughly a kazillion little short-lived allocations for hash table entries.
svn:r14318
Diffstat (limited to 'src/common/container.h')
-rw-r--r-- | src/common/container.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/common/container.h b/src/common/container.h index 866cb1b8a9..3746c30567 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -564,6 +564,49 @@ bitarray_is_set(bitarray_t *b, int bit) return b[bit >> BITARRAY_SHIFT] & (1u << (bit & BITARRAY_MASK)); } +/** A set of digests, implemented as a Bloom filter. */ +typedef struct { + int mask; /* One less than the number of bits in <b>ba</b>; always one less + * than a power of two. */ + bitarray_t *ba; /* A bit array to implement the Bloom filter. */ +} digestset_t; + +#define BIT(n) ((n) & set->mask) +/** Add the digest <b>digest</b> to <b>set</b>. */ +static INLINE void +digestset_add(digestset_t *set, const char *digest) +{ + const uint32_t *p = (const uint32_t *)digest; + const uint32_t d1 = p[0] + (p[1]>>16); + const uint32_t d2 = p[1] + (p[2]>>16); + const uint32_t d3 = p[2] + (p[3]>>16); + const uint32_t d4 = p[3] + (p[0]>>16); + bitarray_set(set->ba, BIT(d1)); + bitarray_set(set->ba, BIT(d2)); + bitarray_set(set->ba, BIT(d3)); + bitarray_set(set->ba, BIT(d4)); +} + +/** If <b>digest</b> is in <b>set</b>, return nonzero. Otherwise, + * <em>probably</em> return zero. */ +static INLINE int +digestset_isin(const digestset_t *set, const char *digest) +{ + const uint32_t *p = (const uint32_t *)digest; + const uint32_t d1 = p[0] + (p[1]>>16); + const uint32_t d2 = p[1] + (p[2]>>16); + const uint32_t d3 = p[2] + (p[3]>>16); + const uint32_t d4 = p[3] + (p[0]>>16); + return bitarray_is_set(set->ba, BIT(d1)) && + bitarray_is_set(set->ba, BIT(d2)) && + bitarray_is_set(set->ba, BIT(d3)) && + bitarray_is_set(set->ba, BIT(d4)); +} +#undef BIT + +digestset_t *digestset_new(int max_elements); +void digestset_free(digestset_t* set); + /* These functions, given an <b>array</b> of <b>n_elements</b>, return the * <b>nth</b> lowest element. <b>nth</b>=0 gives the lowest element; * <b>n_elements</b>-1 gives the highest; and (<b>n_elements</b>-1) / 2 gives |