| Index: sdch/open_vcdiff/depot/opensource/open-vcdiff/src/rolling_hash_test.cc
|
| ===================================================================
|
| --- sdch/open_vcdiff/depot/opensource/open-vcdiff/src/rolling_hash_test.cc (revision 2678)
|
| +++ sdch/open_vcdiff/depot/opensource/open-vcdiff/src/rolling_hash_test.cc (working copy)
|
| @@ -1,231 +0,0 @@
|
| -// Copyright 2007 Google Inc.
|
| -// Authors: Jeff Dean, Lincoln Smith
|
| -//
|
| -// Licensed under the Apache License, Version 2.0 (the "License");
|
| -// you may not use this file except in compliance with the License.
|
| -// You may obtain a copy of the License at
|
| -//
|
| -// http://www.apache.org/licenses/LICENSE-2.0
|
| -//
|
| -// Unless required by applicable law or agreed to in writing, software
|
| -// distributed under the License is distributed on an "AS IS" BASIS,
|
| -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| -// See the License for the specific language governing permissions and
|
| -// limitations under the License.
|
| -
|
| -#include <config.h>
|
| -#include "rolling_hash.h"
|
| -#include <stdint.h> // uint32_t
|
| -#include <cstdlib> // rand, srand
|
| -#include <vector>
|
| -#include "testing.h"
|
| -
|
| -namespace open_vcdiff {
|
| -namespace {
|
| -
|
| -static const uint32_t kBase = RollingHashUtil::kBase;
|
| -
|
| -class RollingHashSimpleTest : public testing::Test {
|
| - protected:
|
| - RollingHashSimpleTest() { }
|
| - virtual ~RollingHashSimpleTest() { }
|
| -
|
| - void TestModBase(uint32_t operand) {
|
| - EXPECT_EQ(operand % kBase, RollingHashUtil::ModBase(operand));
|
| - EXPECT_EQ(static_cast<uint32_t>((-static_cast<int32_t>(operand)) % kBase),
|
| - RollingHashUtil::FindModBaseInverse(operand));
|
| - EXPECT_EQ(0U, RollingHashUtil::ModBase(
|
| - operand + RollingHashUtil::FindModBaseInverse(operand)));
|
| - }
|
| -
|
| - void TestHashFirstTwoBytes(char first_value, char second_value) {
|
| - char buf[2];
|
| - buf[0] = first_value;
|
| - buf[1] = second_value;
|
| - EXPECT_EQ(RollingHashUtil::HashFirstTwoBytes(buf),
|
| - RollingHashUtil::HashStep(RollingHashUtil::HashStep(0,
|
| - first_value),
|
| - second_value));
|
| - EXPECT_EQ(RollingHashUtil::HashFirstTwoBytes(buf),
|
| - RollingHashUtil::HashStep(static_cast<unsigned char>(first_value),
|
| - second_value));
|
| - }
|
| -};
|
| -
|
| -#ifdef GTEST_HAS_DEATH_TEST
|
| -typedef RollingHashSimpleTest RollingHashDeathTest;
|
| -#endif // GTEST_HAS_DEATH_TEST
|
| -
|
| -TEST_F(RollingHashSimpleTest, KBaseIsAPowerOfTwo) {
|
| - EXPECT_EQ(0U, kBase & (kBase - 1));
|
| -}
|
| -
|
| -TEST_F(RollingHashSimpleTest, TestModBaseForValues) {
|
| - TestModBase(0);
|
| - TestModBase(10);
|
| - TestModBase(static_cast<uint32_t>(-10));
|
| - TestModBase(kBase - 1);
|
| - TestModBase(kBase);
|
| - TestModBase(kBase + 1);
|
| - TestModBase(0x7FFFFFFF);
|
| - TestModBase(0x80000000);
|
| - TestModBase(0xFFFFFFFE);
|
| - TestModBase(0xFFFFFFFF);
|
| -}
|
| -
|
| -TEST_F(RollingHashSimpleTest, VerifyHashFirstTwoBytes) {
|
| - TestHashFirstTwoBytes(0x00, 0x00);
|
| - TestHashFirstTwoBytes(0x00, 0xFF);
|
| - TestHashFirstTwoBytes(0xFF, 0x00);
|
| - TestHashFirstTwoBytes(0xFF, 0xFF);
|
| - TestHashFirstTwoBytes(0x00, 0x80);
|
| - TestHashFirstTwoBytes(0x7F, 0xFF);
|
| - TestHashFirstTwoBytes(0x7F, 0x80);
|
| - TestHashFirstTwoBytes(0x01, 0x8F);
|
| -}
|
| -
|
| -#ifdef GTEST_HAS_DEATH_TEST
|
| -TEST_F(RollingHashDeathTest, InstantiateBlockHashWithoutCallingInit) {
|
| - EXPECT_DEBUG_DEATH(RollingHash<16> bad_hash, "Init");
|
| -}
|
| -#endif // GTEST_HAS_DEATH_TEST
|
| -
|
| -class RollingHashTest : public testing::Test {
|
| - public:
|
| - static const int kUpdateHashBlocks = 1000;
|
| - static const int kLargestBlockSize = 128;
|
| -
|
| - static void MakeRandomBuffer(char* buffer, int buffer_size) {
|
| - for (int i = 0; i < buffer_size; ++i) {
|
| - buffer[i] = PortableRandomInRange<unsigned char>(0xFF);
|
| - }
|
| - }
|
| -
|
| - template<int kBlockSize> static void BM_DefaultHash(int iterations,
|
| - const char *buffer) {
|
| - RollingHash<kBlockSize> hasher;
|
| - static uint32_t result_array[kUpdateHashBlocks];
|
| - for (int iter = 0; iter < iterations; ++iter) {
|
| - for (int i = 0; i < kUpdateHashBlocks; ++i) {
|
| - result_array[i] = hasher.Hash(&buffer[i]);
|
| - }
|
| - }
|
| - }
|
| -
|
| - template<int kBlockSize> static void BM_UpdateHash(int iterations,
|
| - const char *buffer) {
|
| - RollingHash<kBlockSize> hasher;
|
| - static uint32_t result_array[kUpdateHashBlocks];
|
| - for (int iter = 0; iter < iterations; ++iter) {
|
| - uint32_t running_hash = hasher.Hash(buffer);
|
| - for (int i = 0; i < kUpdateHashBlocks; ++i) {
|
| - running_hash = hasher.UpdateHash(running_hash,
|
| - buffer[i],
|
| - buffer[i + kBlockSize]);
|
| - result_array[i] = running_hash;
|
| - }
|
| - }
|
| - }
|
| -
|
| - protected:
|
| - static const int kUpdateHashTestIterations = 400;
|
| - static const int kTimingTestSize = 1 << 14; // 16K iterations
|
| -
|
| - RollingHashTest() { }
|
| - virtual ~RollingHashTest() { }
|
| -
|
| - template<int kBlockSize> void UpdateHashMatchesHashForBlockSize() {
|
| - RollingHash<kBlockSize>::Init();
|
| - RollingHash<kBlockSize> hasher;
|
| - for (int x = 0; x < kUpdateHashTestIterations; ++x) {
|
| - int random_buffer_size =
|
| - PortableRandomInRange(kUpdateHashBlocks - 1) + kBlockSize;
|
| - MakeRandomBuffer(buffer_, random_buffer_size);
|
| - uint32_t running_hash = hasher.Hash(buffer_);
|
| - for (int i = kBlockSize; i < random_buffer_size; ++i) {
|
| - // UpdateHash() calculates the hash value incrementally.
|
| - running_hash = hasher.UpdateHash(running_hash,
|
| - buffer_[i - kBlockSize],
|
| - buffer_[i]);
|
| - // Hash() calculates the hash value from scratch. Verify that both
|
| - // methods return the same hash value.
|
| - EXPECT_EQ(running_hash, hasher.Hash(&buffer_[i + 1 - kBlockSize]));
|
| - }
|
| - }
|
| - }
|
| -
|
| - template<int kBlockSize> double DefaultHashTimingTest() {
|
| - // Execution time is expected to be O(kBlockSize) per hash operation,
|
| - // so scale the number of iterations accordingly
|
| - const int kTimingTestIterations = kTimingTestSize / kBlockSize;
|
| - CycleTimer timer;
|
| - timer.Start();
|
| - BM_DefaultHash<kBlockSize>(kTimingTestIterations, buffer_);
|
| - timer.Stop();
|
| - return static_cast<double>(timer.GetInUsec())
|
| - / (kTimingTestIterations * kUpdateHashBlocks);
|
| - }
|
| -
|
| - template<int kBlockSize> double RollingTimingTest() {
|
| - // Execution time is expected to be O(1) per hash operation,
|
| - // so leave the number of iterations constant
|
| - const int kTimingTestIterations = kTimingTestSize;
|
| - CycleTimer timer;
|
| - timer.Start();
|
| - BM_UpdateHash<kBlockSize>(kTimingTestIterations, buffer_);
|
| - timer.Stop();
|
| - return static_cast<double>(timer.GetInUsec())
|
| - / (kTimingTestIterations * kUpdateHashBlocks);
|
| - }
|
| -
|
| - double FindPercentage(double original, double modified) {
|
| - if (original < 0.0001) {
|
| - return 0.0;
|
| - } else {
|
| - return ((modified - original) / original) * 100.0;
|
| - }
|
| - }
|
| -
|
| - template<int kBlockSize> void RunTimingTestForBlockSize() {
|
| - RollingHash<kBlockSize>::Init();
|
| - MakeRandomBuffer(buffer_, sizeof(buffer_));
|
| - const double time_for_default_hash = DefaultHashTimingTest<kBlockSize>();
|
| - const double time_for_rolling_hash = RollingTimingTest<kBlockSize>();
|
| - printf("%d\t%f\t%f (%f%%)\n",
|
| - kBlockSize,
|
| - time_for_default_hash,
|
| - time_for_rolling_hash,
|
| - FindPercentage(time_for_default_hash, time_for_rolling_hash));
|
| - CHECK_GT(time_for_default_hash, 0.0);
|
| - CHECK_GT(time_for_rolling_hash, 0.0);
|
| - if (kBlockSize > 16) {
|
| - EXPECT_GT(time_for_default_hash, time_for_rolling_hash);
|
| - }
|
| - }
|
| -
|
| - char buffer_[kUpdateHashBlocks + kLargestBlockSize];
|
| -};
|
| -
|
| -TEST_F(RollingHashTest, UpdateHashMatchesHashFromScratch) {
|
| - srand(1); // test should be deterministic, including calls to rand()
|
| - UpdateHashMatchesHashForBlockSize<4>();
|
| - UpdateHashMatchesHashForBlockSize<8>();
|
| - UpdateHashMatchesHashForBlockSize<16>();
|
| - UpdateHashMatchesHashForBlockSize<32>();
|
| - UpdateHashMatchesHashForBlockSize<64>();
|
| - UpdateHashMatchesHashForBlockSize<128>();
|
| -}
|
| -
|
| -TEST_F(RollingHashTest, TimingTests) {
|
| - srand(1); // test should be deterministic, including calls to rand()
|
| - printf("BlkSize\tHash (us)\tUpdateHash (us)\n");
|
| - RunTimingTestForBlockSize<4>();
|
| - RunTimingTestForBlockSize<8>();
|
| - RunTimingTestForBlockSize<16>();
|
| - RunTimingTestForBlockSize<32>();
|
| - RunTimingTestForBlockSize<64>();
|
| - RunTimingTestForBlockSize<128>();
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -} // namespace open_vcdiff
|
|
|