49 #include <ndn-cxx/util/exception.hpp> 54 namespace be = boost::endian;
77 : m_compressionScheme(scheme)
80 size_t nEntries = expectedNumEntries + expectedNumEntries / 2;
82 size_t remainder = nEntries %
N_HASH;
84 nEntries += (
N_HASH - remainder);
87 m_hashTable.resize(nEntries);
95 if (3 * m_hashTable.size() != values.size()) {
96 NDN_THROW(
Error(
"Received IBF cannot be decoded!"));
99 for (
size_t i = 0; i < m_hashTable.size(); i++) {
101 if (values[i * 3] != 0) {
102 entry.
count = values[i * 3];
103 entry.
keySum = values[(i * 3) + 1];
104 entry.
keyCheck = values[(i * 3) + 2];
110 IBLT::update(
int plusOrMinus, uint32_t key)
112 size_t bucketsPerHash = m_hashTable.size() /
N_HASH;
114 for (
size_t i = 0; i <
N_HASH; i++) {
115 size_t startEntry = i * bucketsPerHash;
117 HashTableEntry& entry = m_hashTable.at(startEntry + (h % bucketsPerHash));
118 entry.
count += plusOrMinus;
144 for (
const auto& entry : peeled.m_hashTable) {
145 if (entry.isPure()) {
146 if (entry.count == 1) {
147 positive.insert(entry.keySum);
150 negative.insert(entry.keySum);
152 peeled.update(-entry.count, entry.keySum);
156 }
while (nErased > 0);
160 for (
const auto& entry : peeled.m_hashTable) {
161 if (entry.isEmpty() !=
true) {
172 BOOST_ASSERT(m_hashTable.size() == other.m_hashTable.size());
175 for (
size_t i = 0; i < m_hashTable.size(); i++) {
189 constexpr
size_t unitSize =
sizeof(m_hashTable[0].count) +
190 sizeof(m_hashTable[0].keySum) +
191 sizeof(m_hashTable[0].keyCheck);
193 size_t tableSize = unitSize * m_hashTable.size();
194 std::vector<uint8_t> table(tableSize);
196 for (
size_t i = 0; i < m_hashTable.size(); i++) {
197 uint32_t count = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].count));
198 uint32_t keySum = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].keySum));
199 uint32_t keyCheck = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].keyCheck));
201 std::memcpy(&table[i * unitSize], &count,
sizeof(count));
202 std::memcpy(&table[(i * unitSize) + 4], &keySum,
sizeof(keySum));
203 std::memcpy(&table[(i * unitSize) + 8], &keyCheck,
sizeof(keyCheck));
206 auto compressed =
compress(m_compressionScheme, table.data(), table.size());
207 name.append(ndn::name::Component(std::move(compressed)));
210 std::vector<uint32_t>
213 auto decompressedBuf =
decompress(m_compressionScheme, ibltName.value(), ibltName.value_size());
215 if (decompressedBuf->size() % 4 != 0) {
216 NDN_THROW(
Error(
"Received IBF cannot be decompressed correctly!"));
219 size_t n = decompressedBuf->size() / 4;
220 std::vector<uint32_t> values(n, 0);
222 for (
size_t i = 0; i < n; i++) {
224 std::memcpy(&t, &(*decompressedBuf)[i * 4],
sizeof(t));
225 values[i] = be::big_to_native(t);
236 if (iblt1HashTable.size() != iblt2HashTable.size()) {
240 size_t N = iblt1HashTable.size();
242 for (
size_t i = 0; i < N; i++) {
243 if (iblt1HashTable[i].count != iblt2HashTable[i].count ||
244 iblt1HashTable[i].keySum != iblt2HashTable[i].keySum ||
245 iblt1HashTable[i].keyCheck != iblt2HashTable[i].keyCheck)
255 return !(iblt1 == iblt2);
261 os <<
"count keySum keyCheckMatch\n";
263 os << entry.count <<
" " << entry.keySum <<
" " void appendToName(ndn::Name &name) const
Appends self to name.
std::ostream & operator<<(std::ostream &os, const IBLT &iblt)
Invertible Bloom Lookup Table (Invertible Bloom Filter)
IBLT(size_t expectedNumEntries, CompressionScheme scheme)
constructor
std::shared_ptr< ndn::Buffer > decompress(CompressionScheme scheme, const uint8_t *buffer, size_t bufferSize)
bool operator!=(const IBLT &iblt1, const IBLT &iblt2)
void insert(uint32_t key)
bool listEntries(std::set< uint32_t > &positive, std::set< uint32_t > &negative) const
List all the entries in the IBLT.
bool operator==(const IBLT &iblt1, const IBLT &iblt2)
std::shared_ptr< ndn::Buffer > compress(CompressionScheme scheme, const uint8_t *buffer, size_t bufferSize)
void initialize(const ndn::name::Component &ibltName)
Populate the hash table using the vector representation of IBLT.
std::vector< uint32_t > extractValueFromName(const ndn::name::Component &ibltName) const
Extracts IBLT from name component.
IBLT operator-(const IBLT &other) const
uint32_t murmurHash3(const void *key, size_t len, uint32_t seed)
const std::vector< HashTableEntry > & getHashTable() const