From d0429e1c8845cdd1852598f6dbe3203b4fbd9c8e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 23 Mar 2016 14:01:16 -0700 Subject: [PATCH] Add minimal bloom filter helpers mkfs just needs to initialize bloom filter blocks with the bits for the single root inode key. We can get away with these skeletal functions for now. Signed-off-by: Zach Brown --- utils/src/bloom.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ utils/src/bloom.h | 13 ++++++++++ 2 files changed, 79 insertions(+) create mode 100644 utils/src/bloom.c create mode 100644 utils/src/bloom.h diff --git a/utils/src/bloom.c b/utils/src/bloom.c new file mode 100644 index 00000000..22fa62a1 --- /dev/null +++ b/utils/src/bloom.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016 Versity Software, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include "sparse.h" +#include "util.h" +#include "format.h" +#include "bloom.h" +#include "crc.h" +#include "bitops.h" + +/* XXX garbage hack until we have siphash */ +static u32 bloom_hash(struct scoutfs_key *key, __le32 salt) +{ + return crc32c(le32_to_cpu(salt), key, sizeof(struct scoutfs_key)); +} + +/* + * Find the bits in the bloom filter for the given key. The caller calculates + * these once and uses them to test all the blocks. + */ +void scoutfs_calc_bloom_bits(struct scoutfs_bloom_bits *bits, + struct scoutfs_key *key, __le32 *salts) +{ + unsigned h_bits = 0; + unsigned s = 0; + u64 h = 0; + int i; + + for (i = 0; i < SCOUTFS_BLOOM_BITS; i++) { + if (h_bits < SCOUTFS_BLOOM_BIT_WIDTH) { + h = (h << 32) | bloom_hash(key, salts[s++]); + h += 32; + } + + bits->nr[i] = h & SCOUTFS_BLOOM_BIT_MASK; + h >>= SCOUTFS_BLOOM_BIT_WIDTH; + h_bits -= SCOUTFS_BLOOM_BIT_WIDTH; + } +} + +/* + * This interface is different than in the kernel because we don't + * have a block IO interface here yet. The caller gives us each + * bloom block and we set each bit that falls in the block. + */ +void scoutfs_set_bloom_bits(struct scoutfs_bloom_block *blm, unsigned int nr, + struct scoutfs_bloom_bits *bits) +{ + int i; + + for (i = 0; i < SCOUTFS_BLOOM_BITS; i++) { + if (nr == (bits->nr[i] / SCOUTFS_BLOOM_BITS_PER_BLOCK)) { + set_bit_le(bits->nr[i] % SCOUTFS_BLOOM_BITS_PER_BLOCK, + blm->bits); + } + } +} diff --git a/utils/src/bloom.h b/utils/src/bloom.h new file mode 100644 index 00000000..cad1639f --- /dev/null +++ b/utils/src/bloom.h @@ -0,0 +1,13 @@ +#ifndef _BLOOM_H_ +#define _BLOOM_H_ + +struct scoutfs_bloom_bits { + u32 nr[SCOUTFS_BLOOM_BITS]; +}; + +void scoutfs_calc_bloom_bits(struct scoutfs_bloom_bits *bits, + struct scoutfs_key *key, __le32 *salts); +void scoutfs_set_bloom_bits(struct scoutfs_bloom_block *blm, unsigned int nr, + struct scoutfs_bloom_bits *bits); + +#endif