1 | // ========================================================= // |
---|
2 | // // |
---|
3 | // File : cache.cxx // |
---|
4 | // Purpose : test header-only class cache::Cache // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in Jan 22 // |
---|
7 | // http://www.arb-home.de/ // |
---|
8 | // // |
---|
9 | // ========================================================= // |
---|
10 | |
---|
11 | // -------------------------------------------------------------------------------- |
---|
12 | |
---|
13 | #ifdef UNIT_TESTS |
---|
14 | #ifndef TEST_UNIT_H |
---|
15 | #include <test_unit.h> |
---|
16 | #endif |
---|
17 | |
---|
18 | #include <cache.h> |
---|
19 | #include <arb_string.h> |
---|
20 | |
---|
21 | inline int *intcopy(int i) { int *ip = new int; *ip = i; return ip; } |
---|
22 | |
---|
23 | #define CACHED(p,t) that(p.is_cached()).is_equal_to(t) |
---|
24 | #define CACHED_p123(t1,t2,t3) all().of(CACHED(p1, t1), CACHED(p2, t2), CACHED(p3, t3)) |
---|
25 | |
---|
26 | void TEST_CachedPtr() { |
---|
27 | using namespace cache; |
---|
28 | { |
---|
29 | typedef SmartPtr<int> IntPtr; |
---|
30 | |
---|
31 | CacheHandle<IntPtr> p1; |
---|
32 | CacheHandle<IntPtr> p2; |
---|
33 | CacheHandle<IntPtr> p3; |
---|
34 | |
---|
35 | { |
---|
36 | Cache<IntPtr> cache(2); |
---|
37 | TEST_EXPECT_ZERO(cache.entries()); // nothing cached yet |
---|
38 | |
---|
39 | p1.assign(intcopy(1), cache); |
---|
40 | TEST_EXPECT_EQUAL(*p1.access(cache), 1); |
---|
41 | TEST_EXPECT_EQUAL(cache.entries(), 1); |
---|
42 | TEST_EXPECTATION(CACHED_p123(true, false, false)); |
---|
43 | |
---|
44 | p2.assign(intcopy(2), cache); |
---|
45 | TEST_EXPECT_EQUAL(*p2.access(cache), 2); |
---|
46 | TEST_EXPECT_EQUAL(cache.entries(), 2); |
---|
47 | TEST_EXPECTATION(CACHED_p123(true, true, false)); |
---|
48 | |
---|
49 | p3.assign(intcopy(3), cache); |
---|
50 | TEST_EXPECT_EQUAL(*p3.access(cache), 3); |
---|
51 | TEST_EXPECT_EQUAL(cache.entries(), 2); |
---|
52 | TEST_EXPECTATION(CACHED_p123(false, true, true)); // p1 has been invalidated by caching p3 |
---|
53 | |
---|
54 | p3.assign(intcopy(33), cache); // test re-assignment |
---|
55 | TEST_EXPECT_EQUAL(*p3.access(cache), 33); |
---|
56 | TEST_EXPECT_EQUAL(cache.entries(), 2); |
---|
57 | TEST_EXPECTATION(CACHED_p123(false, true, true)); // p2 still cached |
---|
58 | |
---|
59 | TEST_EXPECT_EQUAL(*p2.access(cache), 2); // should make p2 the LRU cache entry |
---|
60 | TEST_EXPECT_EQUAL(cache.entries(), 2); |
---|
61 | TEST_EXPECTATION(CACHED_p123(false, true, true)); // p2 still cached |
---|
62 | |
---|
63 | IntPtr s4; |
---|
64 | { |
---|
65 | CacheHandle<IntPtr> p4; |
---|
66 | p4.assign(intcopy(4), cache); |
---|
67 | TEST_EXPECT_EQUAL(*p4.access(cache), 4); |
---|
68 | TEST_EXPECT_EQUAL(cache.entries(), 2); |
---|
69 | |
---|
70 | s4 = p4.access(cache); // keep data of p4 in s4 |
---|
71 | TEST_EXPECT_EQUAL(s4.references(), 2); // ref'd by s4 and p4 |
---|
72 | |
---|
73 | p4.release(cache); // need to release p4 before destruction (otherwise assertion fails) |
---|
74 | } |
---|
75 | |
---|
76 | TEST_EXPECT_EQUAL(*s4, 4); // check kept value of deleted CacheHandle |
---|
77 | TEST_EXPECT_EQUAL(s4.references(), 1); // only ref'd by s4 |
---|
78 | |
---|
79 | TEST_EXPECT_EQUAL(cache.entries(), 1); // contains only p2 (p4 has been released) |
---|
80 | TEST_EXPECTATION(CACHED_p123(false, true, false)); // p3 has been invalidated by caching p4 |
---|
81 | } |
---|
82 | |
---|
83 | TEST_EXPECTATION(CACHED_p123(false, false, false)); // Cache was destroyed = > all CacheHandle will be invalid |
---|
84 | // no need to release p1..p3 (due cache was destroyed) |
---|
85 | } |
---|
86 | |
---|
87 | // test cache of SmartCharPtr |
---|
88 | { |
---|
89 | Cache<SmartCharPtr> cache(3); |
---|
90 | |
---|
91 | { |
---|
92 | const int P = 4; |
---|
93 | CacheHandle<SmartCharPtr> p[P]; |
---|
94 | const char *word[] = { "apple", "orange", "pie", "juice" }; |
---|
95 | |
---|
96 | for (int i = 0; i<P; ++i) p[i].assign(ARB_strdup(word[i]), cache); |
---|
97 | TEST_REJECT(p[0].is_cached()); |
---|
98 | for (int i = 1; i<P; ++i) TEST_EXPECT_EQUAL(&*p[i].access(cache), word[i]); |
---|
99 | |
---|
100 | TEST_REJECT(p[0].is_cached()); |
---|
101 | TEST_EXPECT(p[1].is_cached()); // oldest entry |
---|
102 | |
---|
103 | cache.resize(cache.size()-1); |
---|
104 | TEST_REJECT(p[1].is_cached()); // invalidated by resize |
---|
105 | |
---|
106 | for (int i = P-1; i >= 0; --i) p[i].assign(ARB_strdup(word[P-1-i]), cache); |
---|
107 | |
---|
108 | for (int i = 0; i<2; ++i) TEST_EXPECT_EQUAL(&*p[i].access(cache), word[P-1-i]); |
---|
109 | for (int i = 2; i<P; ++i) TEST_REJECT(p[i].is_cached()); |
---|
110 | |
---|
111 | cache.flush(); |
---|
112 | } |
---|
113 | } |
---|
114 | } |
---|
115 | |
---|
116 | #endif // UNIT_TESTS |
---|
117 | |
---|
118 | // -------------------------------------------------------------------------------- |
---|