Commit 85bc05e7 authored by Maximilien Colange's avatar Maximilien Colange
Browse files

Move the Fowler-Noll-Vo hash function to a header

* spot/misc/bitvect.cc, spot/misc/hashfunc.hh: move FNV hash function,
  use the new interface
parent 5b2ce273
Pipeline #769 passed with stages
in 134 minutes and 58 seconds
......@@ -43,48 +43,6 @@ namespace spot
return n;
}
// Fowler-Noll-Vo hash parameters.
// Add specializations as needed.
template<int numbytes>
struct fnv
{
};
// Do not define the following if ULONG_MAX cannot
// hold a 64-bit value, otherwise the parser will
// choke when parsing the constants.
#if ULONG_MAX >> 31 >> 31 >> 1 > 0
// Fowler-Noll-Vo hash parameters for 64bits
template<>
struct fnv<8>
{
static unsigned long init()
{
return 14695981039346656037UL;
}
static unsigned long prime()
{
return 1099511628211UL;
}
};
#endif
// Fowler-Noll-Vo hash parameters for 32bits
template<>
struct fnv<4>
{
static unsigned long init()
{
return 2166136261UL;
}
static unsigned long prime()
{
return 16777619UL;
}
};
}
bitvect::bitvect(size_t size, size_t block_count):
......@@ -117,23 +75,17 @@ namespace spot
size_t bitvect::hash() const noexcept
{
block_t res = fnv<sizeof(block_t)>::init();
size_t i;
size_t m = used_blocks();
const size_t m = used_blocks();
if (m == 0)
return res;
for (i = 0; i < m - 1; ++i)
{
res ^= storage_[i];
res *= fnv<sizeof(block_t)>::prime();
}
return fnv_hash(storage_, storage_ + m);
size_t res = fnv_hash(storage_, storage_ + m - 1);
// Deal with the last block, that might not be fully used.
// Compute the number n of bits used in the last block.
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t n = size() % bpb;
// Use only the least n bits from storage_[i].
res ^= storage_[i] & ((1UL << n) - 1);
res ^= storage_[m-1] & ((1UL << n) - 1);
return res;
}
......
// -*- coding: utf-8 -*-
// Copyright (C) 2015 Laboratoire de Recherche et Développement
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
// de l'Epita (LRDE)
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
......@@ -23,6 +23,7 @@
#pragma once
#include <cstddef>
#include <cstdint>
namespace spot
{
......@@ -62,5 +63,44 @@ namespace spot
// bits assumes that all objects are aligned on a 8 byte boundary.
return (key >> 3) * 2654435761U;
}
/// Struct for Fowler-Noll-Vo parameters
template<class T>
struct fnv
{};
/// Fowler-Noll-Vo hash parameters for 32 bits
template<>
struct fnv<uint32_t>
{
static constexpr uint32_t init = 2166136261UL;
static constexpr uint32_t prime = 16777619UL;
};
/// Fowler-Noll-Vo hash parameters for 64 bits
template<>
struct fnv<uint64_t>
{
static constexpr uint64_t init = 14695981039346656037UL;
static constexpr uint64_t prime = 1099511628211UL;
};
/// \brief Fowler-Noll-Vo hash function
///
/// This function is a non-cryptographic fast hash function.
/// The magic constants depend on the size of a size_t.
template<class It>
size_t
fnv_hash(It begin, It end)
{
size_t res = fnv<size_t>::init;
for (; begin != end; ++begin)
{
res ^= *begin;
res *= fnv<size_t>::prime;
}
return res;
}
/// @}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment