• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 
8 #include "include/core/SkRefCnt.h"
9 #include "include/core/SkString.h"
10 #include "include/private/SkChecksum.h"
11 #include "include/private/SkTHash.h"
12 #include "src/core/SkOpts.h"
13 #include "tests/Test.h"
14 
15 #include <tuple>
16 
17 // Tests use of const foreach().  map.count() is of course the better way to do this.
count(const SkTHashMap<int,double> & map)18 static int count(const SkTHashMap<int, double>& map) {
19     int n = 0;
20     map.foreach([&n](int, double) { n++; });
21     return n;
22 }
23 
DEF_TEST(HashMap,r)24 DEF_TEST(HashMap, r) {
25     SkTHashMap<int, double> map;
26 
27     map.set(3, 4.0);
28     REPORTER_ASSERT(r, map.count() == 1);
29 
30     REPORTER_ASSERT(r, map.approxBytesUsed() > 0);
31 
32     double* found = map.find(3);
33     REPORTER_ASSERT(r, found);
34     REPORTER_ASSERT(r, *found == 4.0);
35 
36     map.foreach([](int key, double* d){ *d = -key; });
37     REPORTER_ASSERT(r, count(map) == 1);
38 
39     found = map.find(3);
40     REPORTER_ASSERT(r, found);
41     REPORTER_ASSERT(r, *found == -3.0);
42 
43     REPORTER_ASSERT(r, !map.find(2));
44 
45     const int N = 20;
46 
47     for (int i = 0; i < N; i++) {
48         map.set(i, 2.0*i);
49     }
50 
51     // Test walking the map with iterators, using preincrement (++iter).
52     for (SkTHashMap<int, double>::Iter iter = map.begin(); iter != map.end(); ++iter) {
53         REPORTER_ASSERT(r, iter->first * 2 == (*iter).second);
54     }
55 
56     // Test walking the map with range-based for.
57     for (auto& entry : map) {
58         REPORTER_ASSERT(r, entry.first * 2 == entry.second);
59     }
60 
61     // Ensure that iteration works equally well on a const map, using postincrement (iter++).
62     const auto& cmap = map;
63     for (SkTHashMap<int, double>::Iter iter = cmap.begin(); iter != cmap.end(); iter++) {
64         REPORTER_ASSERT(r, iter->first * 2 == (*iter).second);
65     }
66 
67     // Ensure that range-based for works equally well on a const map.
68     for (const auto& entry : cmap) {
69         REPORTER_ASSERT(r, entry.first * 2 == entry.second);
70     }
71 
72     // Ensure that structured bindings work.
73     for (const auto& [number, timesTwo] : cmap) {
74         REPORTER_ASSERT(r, number * 2 == timesTwo);
75     }
76 
77     SkTHashMap<int, double> clone = map;
78 
79     for (int i = 0; i < N; i++) {
80         found = map.find(i);
81         REPORTER_ASSERT(r, found);
82         REPORTER_ASSERT(r, *found == i*2.0);
83 
84         found = clone.find(i);
85         REPORTER_ASSERT(r, found);
86         REPORTER_ASSERT(r, *found == i*2.0);
87     }
88     for (int i = N; i < 2*N; i++) {
89         REPORTER_ASSERT(r, !map.find(i));
90         REPORTER_ASSERT(r, !clone.find(i));
91     }
92 
93     REPORTER_ASSERT(r, map.count() == N);
94     REPORTER_ASSERT(r, clone.count() == N);
95 
96     for (int i = 0; i < N/2; i++) {
97         map.remove(i);
98     }
99     for (int i = 0; i < N; i++) {
100         found = map.find(i);
101         REPORTER_ASSERT(r, (found == nullptr) == (i < N/2));
102 
103         found = clone.find(i);
104         REPORTER_ASSERT(r, *found == i*2.0);
105     }
106     REPORTER_ASSERT(r, map.count() == N/2);
107     REPORTER_ASSERT(r, clone.count() == N);
108 
109     map.reset();
110     REPORTER_ASSERT(r, map.count() == 0);
111     REPORTER_ASSERT(r, clone.count() == N);
112 
113     clone = map;
114     REPORTER_ASSERT(r, clone.count() == 0);
115 
116     {
117         // Test that we don't leave dangling values in empty slots.
118         SkTHashMap<int, sk_sp<SkRefCnt>> refMap;
119         auto ref = sk_make_sp<SkRefCnt>();
120         REPORTER_ASSERT(r, ref->unique());
121 
122         refMap.set(0, ref);
123         REPORTER_ASSERT(r, refMap.count() == 1);
124         REPORTER_ASSERT(r, !ref->unique());
125 
126         refMap.remove(0);
127         REPORTER_ASSERT(r, refMap.count() == 0);
128         REPORTER_ASSERT(r, ref->unique());
129     }
130 }
131 
DEF_TEST(HashSet,r)132 DEF_TEST(HashSet, r) {
133     SkTHashSet<SkString> set;
134 
135     set.add(SkString("Hello"));
136     set.add(SkString("World"));
137     REPORTER_ASSERT(r, set.count() == 2);
138     REPORTER_ASSERT(r, set.contains(SkString("Hello")));
139     REPORTER_ASSERT(r, set.contains(SkString("World")));
140     REPORTER_ASSERT(r, !set.contains(SkString("Goodbye")));
141     REPORTER_ASSERT(r, set.find(SkString("Hello")));
142     REPORTER_ASSERT(r, *set.find(SkString("Hello")) == SkString("Hello"));
143 
144     // Test walking the set with iterators, using preincrement (++iter).
145     for (SkTHashSet<SkString>::Iter iter = set.begin(); iter != set.end(); ++iter) {
146         REPORTER_ASSERT(r, iter->equals("Hello") || (*iter).equals("World"));
147     }
148 
149     // Test walking the set with iterators, using postincrement (iter++).
150     for (SkTHashSet<SkString>::Iter iter = set.begin(); iter != set.end(); iter++) {
151         REPORTER_ASSERT(r, iter->equals("Hello") || (*iter).equals("World"));
152     }
153 
154     // Test walking the set with range-based for.
155     for (auto& entry : set) {
156         REPORTER_ASSERT(r, entry.equals("Hello") || entry.equals("World"));
157     }
158 
159     // Ensure that iteration works equally well on a const set.
160     const auto& cset = set;
161     for (SkTHashSet<SkString>::Iter iter = cset.begin(); iter != cset.end(); iter++) {
162         REPORTER_ASSERT(r, iter->equals("Hello") || (*iter).equals("World"));
163     }
164 
165     // Ensure that range-based for works equally well on a const set.
166     for (auto& entry : cset) {
167         REPORTER_ASSERT(r, entry.equals("Hello") || entry.equals("World"));
168     }
169 
170     SkTHashSet<SkString> clone = set;
171     REPORTER_ASSERT(r, clone.count() == 2);
172     REPORTER_ASSERT(r, clone.contains(SkString("Hello")));
173     REPORTER_ASSERT(r, clone.contains(SkString("World")));
174     REPORTER_ASSERT(r, !clone.contains(SkString("Goodbye")));
175     REPORTER_ASSERT(r, clone.find(SkString("Hello")));
176     REPORTER_ASSERT(r, *clone.find(SkString("Hello")) == SkString("Hello"));
177 
178     set.remove(SkString("Hello"));
179     REPORTER_ASSERT(r, !set.contains(SkString("Hello")));
180     REPORTER_ASSERT(r, set.count() == 1);
181     REPORTER_ASSERT(r, clone.contains(SkString("Hello")));
182     REPORTER_ASSERT(r, clone.count() == 2);
183 
184     set.reset();
185     REPORTER_ASSERT(r, set.count() == 0);
186 
187     clone = set;
188     REPORTER_ASSERT(r, clone.count() == 0);
189 }
190 
191 namespace {
192 
193 class CopyCounter {
194 public:
CopyCounter()195     CopyCounter() : fID(0), fCounter(nullptr) {}
196 
CopyCounter(uint32_t id,uint32_t * counter)197     CopyCounter(uint32_t id, uint32_t* counter) : fID(id), fCounter(counter) {}
198 
CopyCounter(const CopyCounter & other)199     CopyCounter(const CopyCounter& other)
200         : fID(other.fID)
201         , fCounter(other.fCounter) {
202         SkASSERT(fCounter);
203         *fCounter += 1;
204     }
205 
operator =(const CopyCounter & other)206     void operator=(const CopyCounter& other) {
207         fID = other.fID;
208         fCounter = other.fCounter;
209         *fCounter += 1;
210     }
211 
CopyCounter(CopyCounter && other)212     CopyCounter(CopyCounter&& other) { *this = std::move(other); }
operator =(CopyCounter && other)213     void operator=(CopyCounter&& other) {
214         fID = other.fID;
215         fCounter = other.fCounter;
216     }
217 
218 
operator ==(const CopyCounter & other) const219     bool operator==(const CopyCounter& other) const {
220         return fID == other.fID;
221     }
222 
223 private:
224     uint32_t  fID;
225     uint32_t* fCounter;
226 };
227 
228 struct HashCopyCounter {
operator ()__anon0462fb500311::HashCopyCounter229     uint32_t operator()(const CopyCounter&) const {
230         return 0; // let them collide, what do we care?
231     }
232 };
233 
234 }  // namespace
235 
DEF_TEST(HashSetCopyCounter,r)236 DEF_TEST(HashSetCopyCounter, r) {
237     SkTHashSet<CopyCounter, HashCopyCounter> set;
238 
239     uint32_t globalCounter = 0;
240     CopyCounter copyCounter1(1, &globalCounter);
241     CopyCounter copyCounter2(2, &globalCounter);
242     REPORTER_ASSERT(r, globalCounter == 0);
243 
244     set.add(copyCounter1);
245     REPORTER_ASSERT(r, globalCounter == 1);
246     REPORTER_ASSERT(r, set.contains(copyCounter1));
247     REPORTER_ASSERT(r, globalCounter == 1);
248     set.add(copyCounter1);
249     // We allow copies for same-value adds for now.
250     REPORTER_ASSERT(r, globalCounter == 2);
251 
252     set.add(copyCounter2);
253     REPORTER_ASSERT(r, globalCounter == 3);
254     REPORTER_ASSERT(r, set.contains(copyCounter1));
255     REPORTER_ASSERT(r, set.contains(copyCounter2));
256     REPORTER_ASSERT(r, globalCounter == 3);
257     set.add(copyCounter1);
258     set.add(copyCounter2);
259     // We allow copies for same-value adds for now.
260     REPORTER_ASSERT(r, globalCounter == 5);
261 }
262 
263 
DEF_TEST(HashFindOrNull,r)264 DEF_TEST(HashFindOrNull, r) {
265     struct Entry {
266         int key = 0;
267         int val = 0;
268     };
269 
270     struct HashTraits {
271         static int GetKey(const Entry* e) { return e->key; }
272         static uint32_t Hash(int key) { return key; }
273     };
274 
275     SkTHashTable<Entry*, int, HashTraits> table;
276 
277     REPORTER_ASSERT(r, nullptr == table.findOrNull(7));
278 
279     Entry seven = { 7, 24 };
280     table.set(&seven);
281 
282     REPORTER_ASSERT(r, &seven == table.findOrNull(7));
283 }
284 
DEF_TEST(HashTableGrowsAndShrinks,r)285 DEF_TEST(HashTableGrowsAndShrinks, r) {
286     SkTHashSet<int> s;
287     auto check_count_cap = [&](int count, int cap) {
288         REPORTER_ASSERT(r, s.count() == count);
289         REPORTER_ASSERT(r, s.approxBytesUsed() == (sizeof(int) + sizeof(uint32_t)) * cap);
290     };
291 
292     // Add and remove some elements to test basic growth and shrink patterns.
293                  check_count_cap(0,0);
294     s.add(1);    check_count_cap(1,4);
295     s.add(2);    check_count_cap(2,4);
296     s.add(3);    check_count_cap(3,4);
297     s.add(4);    check_count_cap(4,8);
298 
299     s.remove(4); check_count_cap(3,8);
300     s.remove(3); check_count_cap(2,4);
301     s.remove(2); check_count_cap(1,4);
302     s.remove(1); check_count_cap(0,4);
303 
304     s.add(1);    check_count_cap(1,4);
305     s.add(2);    check_count_cap(2,4);
306     s.add(3);    check_count_cap(3,4);
307     s.add(4);    check_count_cap(4,8);
308 
309     // Add and remove single elements repeatedly to test hysteresis
310     // avoids reallocating these small tables all the time.
311     for (int i = 0; i < 10; i++) {
312         s.   add(5); check_count_cap(5,8);
313         s.remove(5); check_count_cap(4,8);
314     }
315 
316     s.remove(4);     check_count_cap(3,8);
317     for (int i = 0; i < 10; i++) {
318         s.   add(4); check_count_cap(4,8);
319         s.remove(4); check_count_cap(3,8);
320     }
321 
322     s.remove(3);     check_count_cap(2,4);
323     for (int i = 0; i < 10; i++) {
324         s.   add(4); check_count_cap(3,4);
325         s.remove(4); check_count_cap(2,4);
326     }
327 
328     s.remove(2);     check_count_cap(1,4);
329     for (int i = 0; i < 10; i++) {
330         s.   add(2); check_count_cap(2,4);
331         s.remove(2); check_count_cap(1,4);
332     }
333 }
334 
DEF_TEST(HashCollision,r)335 DEF_TEST(HashCollision, r) {
336 
337     // Two different sets of data. Same hash.
338     uint8_t data1[] = {
339         15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 16, 0, 0, 0, 21, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 31, 0, 0, 0, 27, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 32, 0, 0, 0, 27, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 33, 0, 0, 0, 23, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 33, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340     };
341     uint8_t data2[] = {
342         15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 16, 0, 0, 0, 21, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 31, 0, 0, 0, 27, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 32, 0, 0, 0, 27, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 33, 0, 0, 0, 23, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 33, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343     };
344 
345     REPORTER_ASSERT(r, sizeof(data1) == sizeof(data2));
346     REPORTER_ASSERT(r, memcmp(data1, data2, sizeof(data1)) != 0);
347 
348     uint32_t hash1 = SkOpts::hash(data1, sizeof(data1), 0);
349     uint32_t hash2 = SkOpts::hash(data2, sizeof(data2), 0);
350     REPORTER_ASSERT(r, hash1 != hash2);
351 }
352