File: ConcurrentBloomFilter.h

package info (click to toggle)
abyss 2.3.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,284 kB
  • sloc: cpp: 78,182; ansic: 6,512; makefile: 2,252; perl: 672; sh: 509; haskell: 412; python: 4
file content (98 lines) | stat: -rw-r--r-- 2,213 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef CONCURRENTBLOOMFILTER_H
#define CONCURRENTBLOOMFILTER_H

#ifndef _OPENMP
# error ConcurrentBloomFilter class requires a compiler that supports OpenMP
#endif

#include "config.h"
#include <vector>
#include <omp.h>

/**
 * A wrapper class that makes a Bloom filter
 * thread-safe.
 */
template <class BloomFilterType>
class ConcurrentBloomFilter
{

public:

	/** Constructor */
	ConcurrentBloomFilter(BloomFilterType& bloom, size_t numLocks,
		size_t hashSeed=0) : m_bloom(bloom), m_locks(numLocks),
		m_hashSeed(hashSeed)
	{
		m_windowSize = bloom.size() / numLocks;
		// round down to the nearest byte boundary,
		// because bytes that span locks will
		// cause concurrency issues
		m_windowSize -= m_windowSize % 8;
		assert(numLocks < bloom.size());
		for (size_t i = 0; i < m_locks.size(); i++)
			omp_init_lock(&(m_locks.at(i)));
	}

	/** Destructor */
	~ConcurrentBloomFilter()
	{
		for (size_t i = 0; i < m_locks.size(); i++)
			omp_destroy_lock(&(m_locks.at(i)));
	}

	/** Return whether the specified bit is set. */
	bool operator[](size_t i) const
	{
		assert(i < m_bloom.size());
		bool bit;
		getLock(i);
			bit = m_bloom[i];
		releaseLock(i);
		return bit;
	}

	/** Return whether the object is present in this set. */
	bool operator[](const Bloom::key_type& key) const
	{
		return *this[Bloom::hash(key, m_hashSeed) % m_bloom.size()];
	}

	/** Add the object with the specified index to this set. */
	void insert(size_t index)
	{
		assert(index < m_bloom.size());
		getLock(index);
			m_bloom.insert(index);
		releaseLock(index);
	}

	/** Add the object to this set. */
	void insert(const Bloom::key_type& key)
	{
		insert(Bloom::hash(key, m_hashSeed) % m_bloom.size());
	}

private:

	void getLock(size_t bitIndex)
	{
		assert(bitIndex < m_bloom.size());
		size_t lockIndex = std::min(bitIndex / m_windowSize, m_locks.size() - 1);
		omp_set_lock(&(m_locks.at(lockIndex)));
	}

	void releaseLock(size_t bitIndex)
	{
		assert(bitIndex < m_bloom.size());
		size_t lockIndex = std::min(bitIndex / m_windowSize, m_locks.size() - 1);
		omp_unset_lock(&(m_locks.at(lockIndex)));
	}

	BloomFilterType& m_bloom;
	std::vector<omp_lock_t> m_locks;
	size_t m_hashSeed;
	size_t m_windowSize;
};

#endif