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
8#include "Test.h"
9
10// This is a GR test
11#if SK_SUPPORT_GPU
12#include "GrTHashTable.h"
13
14struct HashElement {
15    int     fKey;
16    int     fValue;
17};
18
19class GrFindPositivesFunctor {
20public:
21    // only return elements with positive values
22    bool operator()(const HashElement* elem) const {
23        return elem->fValue > 0;
24    }
25};
26
27class GrFindNegativesFunctor {
28public:
29    // only return elements with negative values
30    bool operator()(const HashElement* elem) const {
31        return elem->fValue < 0;
32    }
33};
34
35class HashKey {
36public:
37    HashKey(int key) : fKey(key) {}
38
39    uint32_t getHash() const { return fKey; }
40
41    static bool LessThan(const HashElement& entry, const HashKey& key) {
42        return entry.fKey < key.fKey;
43    }
44    static bool Equals(const HashElement& entry, const HashKey& key) {
45        return entry.fKey == key.fKey;
46    }
47
48#ifdef SK_DEBUG
49    static bool LessThan(const HashElement& a, const HashElement& b) {
50        return a.fKey < b.fKey;
51    }
52    static bool Equals(const HashElement& a, const HashElement& b) {
53        return a.fKey == b.fKey;
54    }
55#endif
56
57protected:
58    int fKey;
59};
60
61DEF_TEST(HashCache, reporter) {
62    GrTHashTable<HashElement, HashKey, 4> cache;
63
64    HashElement negHashElements[10] = {
65        { 0,  0 },
66        { 1, -1 },
67        { 2, -2 },
68        { 3, -3 },
69        { 4, -4 },
70        { 5, -5 },
71        { 6, -6 },
72        { 7, -7 },
73        { 8, -8 },
74        { 9, -9 }
75    };
76    HashElement posHashElements[10] = {
77        { 0, 0 },
78        { 1, 1 },
79        { 2, 2 },
80        { 3, 3 },
81        { 4, 4 },
82        { 5, 5 },
83        { 6, 6 },
84        { 7, 7 },
85        { 8, 8 },
86        { 9, 9 }
87    };
88
89    // add i: -i pairs
90    for (int i = 0; i < 10; ++i) {
91        cache.insert(HashKey(i), &negHashElements[i]);
92    }
93
94    REPORTER_ASSERT(reporter, 10 == cache.count());
95
96    // look for all i's and assert we found the -i's
97    for (int i = 0; i < 10; ++i) {
98        HashElement* found = cache.find(i);
99        REPORTER_ASSERT(reporter, NULL != found && -i == found->fValue);
100    }
101
102    // look for something not in the cache
103    {
104        HashElement* found = cache.find(10);
105        REPORTER_ASSERT(reporter, NULL == found);
106    }
107
108    // add i:i duplicates (so each i will have a positive & negative entry)
109    for (int i = 0; i < 10; ++i) {
110        cache.insert(i, &posHashElements[i]);
111    }
112
113    REPORTER_ASSERT(reporter, 20 == cache.count());
114
115    // test out the find functor to find all the positive values
116    {
117        GrFindPositivesFunctor findPos;
118
119        HashElement* found = cache.find(0, findPos);
120        REPORTER_ASSERT(reporter, NULL == found);
121
122        for (int i = 1; i < 10; ++i) {
123            found = cache.find(i, findPos);
124
125            REPORTER_ASSERT(reporter, NULL != found && found->fValue > 0);
126        }
127    }
128
129    // make sure finding the positives wasn't a fluke - find the negatives
130    {
131        GrFindNegativesFunctor findNeg;
132
133        HashElement* found = cache.find(0, findNeg);
134        REPORTER_ASSERT(reporter, NULL == found);
135
136        for (int i = 1; i < 10; ++i) {
137            found = cache.find(i, findNeg);
138
139            REPORTER_ASSERT(reporter, NULL != found && found->fValue < 0);
140        }
141    }
142
143    // remove the 0:0 entries
144    {
145        cache.remove(0, &negHashElements[0]);
146        cache.remove(0, &posHashElements[0]);
147        REPORTER_ASSERT(reporter, 18 == cache.count());
148
149        HashElement* found = cache.find(0);
150        REPORTER_ASSERT(reporter, NULL == found);
151    }
152}
153
154#endif
155