Skip to content

Commit

Permalink
Removed Jenkins 64bit hash.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwellbelove committed Jan 18, 2017
1 parent d3c9cd3 commit 9848bba
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 187 deletions.
81 changes: 7 additions & 74 deletions src/jenkins.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ SOFTWARE.
#pragma diag_suppress 1300
#endif

///\defgroup jenkins Jenkins 32 & 64 bit hash calculations
///\defgroup jenkins Jenkins 32 hash calculation
///\ingroup maths

namespace etl
{
//***************************************************************************
/// Jenkins32 policy.
/// Jenkins policy.
/// Calculates 32 bit Jenkins hash.
//***************************************************************************
struct jenkins32_policy
struct jenkins_policy
{
typedef uint32_t value_type;

Expand Down Expand Up @@ -89,84 +89,17 @@ namespace etl
bool is_finalised;
};

//***************************************************************************
/// Jenkins64 policy.
/// Calculates 32 bit Jenkins hash.
//***************************************************************************
struct jenkins64_policy
{
typedef uint64_t value_type;

inline uint64_t initial()
{
is_finalised = false;

return 0;
}

inline uint64_t add(value_type hash, uint8_t value) const
{
ETL_ASSERT(!is_finalised, ETL_ERROR(hash_finalised));

hash += value;
hash += (hash << 10);
hash ^= (hash >> 6);

return hash;
}

inline uint64_t final(value_type hash)
{
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
is_finalised = true;

return hash;
}

bool is_finalised;
};

//*************************************************************************
/// Jenkins32
//*************************************************************************
class jenkins32 : public etl::frame_check_sequence<etl::jenkins32_policy>
{
public:

//*************************************************************************
/// Default constructor.
//*************************************************************************
jenkins32()
{
this->reset();
}

//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
jenkins32(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};

//*************************************************************************
/// Jenkins64
/// jenkins
//*************************************************************************
class jenkins64 : public etl::frame_check_sequence<etl::jenkins64_policy>
class jenkins : public etl::frame_check_sequence<etl::jenkins_policy>
{
public:

//*************************************************************************
/// Default constructor.
//*************************************************************************
jenkins64()
jenkins()
{
this->reset();
}
Expand All @@ -177,7 +110,7 @@ namespace etl
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
jenkins64(TIterator begin, const TIterator end)
jenkins(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
Expand Down
137 changes: 24 additions & 113 deletions test/test_jenkins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ SOFTWARE.

#include <UnitTest++/UnitTest++.h>

#include "murmurhash3.h" // The 'C' reference implementation.

#include <iterator>
#include <string>
#include <vector>
Expand All @@ -39,7 +37,7 @@ SOFTWARE.
#include "../src/endian.h"

template <typename TIterator>
uint32_t jenkins32(TIterator begin, TIterator end)
uint32_t jenkins(TIterator begin, TIterator end)
{
uint32_t hash = 0;

Expand All @@ -57,178 +55,91 @@ uint32_t jenkins32(TIterator begin, TIterator end)
return hash;
}

template <typename TIterator>
uint64_t jenkins64(TIterator begin, TIterator end)
{
uint64_t hash = 0;

while (begin != end)
{
hash += *begin++;
hash += (hash << 10);
hash ^= (hash >> 6);
}

hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);

return hash;
}

namespace
{
{
SUITE(test_jenkins)
{
//*************************************************************************
TEST(test_jenkins_32_constructor)
TEST(test_jenkins_constructor)
{
std::string data("123456789");

uint32_t hash = etl::jenkins32(data.begin(), data.end());
uint32_t compare = jenkins32(data.begin(), data.end());
uint32_t hash = etl::jenkins(data.begin(), data.end());
uint32_t compare = jenkins(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_32_add_values)
TEST(test_jenkins_add_values)
{
std::string data("123456789");

etl::jenkins32 jenkins_32_calculator;
etl::jenkins jenkins_calculator;

for (size_t i = 0; i < data.size(); ++i)
{
jenkins_32_calculator.add(data[i]);
jenkins_calculator.add(data[i]);
}

uint32_t hash = jenkins_32_calculator;
uint32_t compare = jenkins32(data.begin(), data.end());
uint32_t hash = jenkins_calculator;
uint32_t compare = jenkins(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_32_add_range)
TEST(test_jenkins_add_range)
{
std::string data("123456789");

etl::jenkins32 jenkins_32_calculator;
etl::jenkins jenkins_calculator;

jenkins_32_calculator.add(data.begin(), data.end());
jenkins_calculator.add(data.begin(), data.end());

uint32_t hash = jenkins_32_calculator.value();
uint32_t hash = jenkins_calculator.value();

uint32_t compare = jenkins32(data.begin(), data.end());
uint32_t compare = jenkins(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_32_add_range_endian)
TEST(test_jenkins_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };

uint32_t hash1 = etl::jenkins32(data1.begin(), data1.end());
uint32_t hash2 = etl::jenkins32((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint32_t hash3 = etl::jenkins32(data3.rbegin(), data3.rend());
uint32_t hash1 = etl::jenkins(data1.begin(), data1.end());
uint32_t hash2 = etl::jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint32_t hash3 = etl::jenkins(data3.rbegin(), data3.rend());

CHECK_EQUAL(hash1, hash2);
CHECK_EQUAL(hash1, hash3);

uint64_t compare1 = jenkins32(data1.begin(), data1.end());
uint64_t compare1 = jenkins(data1.begin(), data1.end());
CHECK_EQUAL(compare1, hash1);

uint64_t compare2 = jenkins32((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint64_t compare2 = jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
CHECK_EQUAL(compare2, hash2);

uint64_t compare3 = jenkins32(data3.rbegin(), data3.rend());
uint64_t compare3 = jenkins(data3.rbegin(), data3.rend());
CHECK_EQUAL(compare3, hash3);
}

//*************************************************************************
TEST(test_jenkins_32_finalised_exception)
TEST(test_jenkins_finalised_exception)
{
std::string data("123456789");

etl::jenkins32 j32;
etl::jenkins j32;
j32.add(data.begin(), data.end());

j32.value();

CHECK_THROW(j32.add(0), etl::hash_finalised);
}

//*************************************************************************
TEST(test_jenkins_64_constructor)
{
std::string data("123456789");

uint64_t hash = etl::jenkins64(data.begin(), data.end());
uint64_t compare = jenkins64(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_64_add_values)
{
std::string data("123456789");

etl::jenkins64 jenkins_64_calculator;

for (size_t i = 0; i < data.size(); ++i)
{
jenkins_64_calculator.add(data[i]);
}

uint64_t hash = jenkins_64_calculator;
uint64_t compare = jenkins64(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_64_add_range)
{
std::string data("123456789");

etl::jenkins64 jenkins_64_calculator;

jenkins_64_calculator.add(data.begin(), data.end());

uint64_t hash = jenkins_64_calculator.value();

uint64_t compare = jenkins64(data.begin(), data.end());

CHECK_EQUAL(compare, hash);
}

//*************************************************************************
TEST(test_jenkins_64_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };

uint64_t hash1 = etl::jenkins64(data1.begin(), data1.end());
uint64_t hash2 = etl::jenkins64((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint64_t hash3 = etl::jenkins64(data3.rbegin(), data3.rend());
CHECK_EQUAL(hash1, hash2);
CHECK_EQUAL(hash1, hash3);

uint64_t compare1 = jenkins64(data1.begin(), data1.end());
CHECK_EQUAL(compare1, hash1);

uint64_t compare2 = jenkins64((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
CHECK_EQUAL(compare2, hash2);

uint64_t compare3 = jenkins64(data3.rbegin(), data3.rend());
CHECK_EQUAL(compare3, hash3);
}
};
}

0 comments on commit 9848bba

Please sign in to comment.