Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ChecksumTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
11#include "src/base/SkRandom.h"
12#include "src/core/SkChecksum.h"
13#include "tests/Test.h"
14
15#include <cstddef>
16#include <cstdint>
17#include <cstring>
18#include <string>
19#include <string_view>
20
21DEF_TEST(Checksum, r) {
22 // Put 128 random bytes into two identical buffers. Any multiple of 4 will do.
23 const size_t kBytes = SkAlign4(128);
24 SkRandom rand;
25 uint32_t data[kBytes/4], tweaked[kBytes/4];
26 for (size_t i = 0; i < std::size(tweaked); ++i) {
27 data[i] = tweaked[i] = rand.nextU();
28 }
29
30 const uint32_t hash = SkChecksum::Hash32(data, kBytes);
31 // Should be deterministic.
32 REPORTER_ASSERT(r, hash == SkChecksum::Hash32(data, kBytes));
33
34 // Changing any single element should change the hash.
35 for (size_t j = 0; j < std::size(tweaked); ++j) {
36 const uint32_t saved = tweaked[j];
37 tweaked[j] = rand.nextU();
38 const uint32_t tweakedHash = SkChecksum::Hash32(tweaked, kBytes);
39 REPORTER_ASSERT(r, tweakedHash != hash);
40 REPORTER_ASSERT(r, tweakedHash == SkChecksum::Hash32(tweaked, kBytes));
41 tweaked[j] = saved;
42 }
43}
44
45DEF_TEST(GoodHash, r) {
46 // 4 bytes --> hits SkChecksum::Mix fast path.
47 REPORTER_ASSERT(r, SkGoodHash()(( int32_t)4) == 614249093);
48 REPORTER_ASSERT(r, SkGoodHash()((uint32_t)4) == 614249093);
49}
50
51DEF_TEST(ChecksumCollisions, r) {
52 // We noticed a few workloads that would cause hash collisions due to the way
53 // our old optimized hashes split into three concurrent hashes and merged those hashes together.
54 //
55 // One of these two workloads ought to cause an unintentional hash collision on very similar
56 // data in those old algorithms, the float version on 32-bit x86 and double elsewhere.
57 {
58 float a[9] = { 0, 1, 2,
59 3, 4, 5,
60 6, 7, 8, };
61 float b[9] = { 1, 2, 0,
62 4, 5, 3,
63 7, 8, 6, };
64
65 REPORTER_ASSERT(r, SkChecksum::Hash32(a, sizeof(a)) != SkChecksum::Hash32(b, sizeof(b)));
66 }
67 {
68 double a[9] = { 0, 1, 2,
69 3, 4, 5,
70 6, 7, 8, };
71 double b[9] = { 1, 2, 0,
72 4, 5, 3,
73 7, 8, 6, };
74
75 REPORTER_ASSERT(r, SkChecksum::Hash32(a, sizeof(a)) != SkChecksum::Hash32(b, sizeof(b)));
76 }
77}
78
79DEF_TEST(ChecksumConsistent, r) {
80 // We don't guarantee that SkChecksum::Hash32 will return consistent results, but it does today.
81 // Spot check a few:
82 uint8_t bytes[256];
83 for (int i = 0; i < 256; i++) {
84 bytes[i] = i;
85 }
86 auto hash_bytes = [&](int n) { return SkChecksum::Hash32(bytes, n); };
87 REPORTER_ASSERT(r, hash_bytes( 0) == 0xe2bde459, "%08x", hash_bytes( 0));
88 REPORTER_ASSERT(r, hash_bytes( 1) == 0xe5f8bd85, "%08x", hash_bytes( 1));
89 REPORTER_ASSERT(r, hash_bytes( 2) == 0x77acd42a, "%08x", hash_bytes( 2));
90 REPORTER_ASSERT(r, hash_bytes( 7) == 0x78d0861f, "%08x", hash_bytes( 7));
91 REPORTER_ASSERT(r, hash_bytes( 32) == 0x4e73df6d, "%08x", hash_bytes( 32));
92 REPORTER_ASSERT(r, hash_bytes( 63) == 0x5e66a3f4, "%08x", hash_bytes( 63));
93 REPORTER_ASSERT(r, hash_bytes( 64) == 0x962d6746, "%08x", hash_bytes( 64));
94 REPORTER_ASSERT(r, hash_bytes( 99) == 0x79e09416, "%08x", hash_bytes( 99));
95 REPORTER_ASSERT(r, hash_bytes(255) == 0x85f837f0, "%08x", hash_bytes(255));
96}
97
98DEF_TEST(ChecksumStrings, r) {
99 constexpr char kMessage[] = "Checksums are supported for SkString, string, and string_view.";
100 const uint32_t expectedHash = SkChecksum::Hash32(kMessage, strlen(kMessage));
101
102 REPORTER_ASSERT(r, expectedHash == SkGoodHash()(SkString(kMessage)));
103 REPORTER_ASSERT(r, expectedHash == SkGoodHash()(std::string(kMessage)));
104 REPORTER_ASSERT(r, expectedHash == SkGoodHash()(std::string_view(kMessage)));
105}
static constexpr T SkAlign4(T x)
Definition SkAlign.h:16
static uint32_t hash(const SkShaderBase::GradientInfo &v)
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
uint32_t nextU()
Definition SkRandom.h:42
static bool b
struct MyStruct a[10]
uint32_t Hash32(const void *data, size_t bytes, uint32_t seed)