1
+ @testset " Caching" begin
2
+ mutable struct CacheableParameter <: AbstractImageReconstructionParameters
3
+ factor:: Int64
4
+ cache_misses:: Ref{Int64}
5
+ end
6
+ mutable struct PureCacheableParameter <: AbstractImageReconstructionParameters
7
+ factor:: Int64
8
+ cache_misses:: Ref{Int64}
9
+ end
10
+ mutable struct CacheableAlgorithm{P} <: AbstractImageReconstructionAlgorithm
11
+ const parameter:: Union{P, ProcessResultCache{P}}
12
+ value:: Int64
13
+ output:: Channel{Int64}
14
+ CacheableAlgorithm (parameter:: ProcessResultCache{P} ) where P = new {P} (parameter, 1 , Channel {Int64} (Inf ))
15
+ CacheableAlgorithm (parameter:: P ) where P = new {P} (parameter, 1 , Channel {Int64} (Inf ))
16
+ end
17
+ AbstractImageReconstruction. parameter (algo:: CacheableAlgorithm ) = algo. parameter
18
+ Base. lock (algo:: CacheableAlgorithm ) = lock (algo. output)
19
+ Base. unlock (algo:: CacheableAlgorithm ) = unlock (algo. output)
20
+ Base. take! (algo:: CacheableAlgorithm ) = Base. take! (algo. output)
21
+ function Base. put! (algo:: CacheableAlgorithm , value)
22
+ lock (algo) do
23
+ put! (algo. output, process (algo, algo. parameter, value))
24
+ end
25
+ end
26
+ # Implement proper hashing for algorithm, otherwise hash will ignore changes to value
27
+ function Base. hash (algo:: CacheableAlgorithm , h:: UInt64 )
28
+ return hash (typeof (algo), hash (algo. output, hash (algo. value, hash (algo. parameter, h))))
29
+ end
30
+
31
+ function AbstractImageReconstruction. process (algo:: CacheableAlgorithm , parameter:: CacheableParameter , value)
32
+ parameter. cache_misses[] += 1
33
+ return algo. value + parameter. factor * value
34
+ end
35
+ function AbstractImageReconstruction. process (algo:: CacheableAlgorithm , parameter:: Union{PureCacheableParameter, ProcessResultCache{PureCacheableParameter}} , value)
36
+ return algo. value + process (typeof (algo), parameter, value)
37
+ end
38
+ function AbstractImageReconstruction. process (algo, parameter:: PureCacheableParameter , value)
39
+ parameter. cache_misses[] += 1
40
+ return parameter. factor * value
41
+ end
42
+
43
+ @testset " Constructor" begin
44
+ cached_parameter = PureCacheableParameter (3 , Ref (0 ))
45
+ cache = ProcessResultCache (; param = cached_parameter, maxsize = 42 )
46
+ cache2 = ProcessResultCache (cache. cache; param = cache. param)
47
+ cache3 = ProcessResultCache (42 ; param = cache. param)
48
+ @test cache. cache == cache2. cache
49
+ @test cache. maxsize == cache2. maxsize
50
+ @test cache. cache. maxsize == cache2. cache. maxsize
51
+ @test cache2. maxsize == cache3. maxsize
52
+ @test cache2. cache. maxsize == cache3. cache. maxsize
53
+ end
54
+
55
+ @testset " Stateful Process" begin
56
+ uncached_parameter = CacheableParameter (3 , Ref (0 ))
57
+ algo = CacheableAlgorithm (uncached_parameter)
58
+
59
+ cache_misses = Ref (0 )
60
+ cached_parameter = CacheableParameter (3 , cache_misses)
61
+ cache = ProcessResultCache (; param = cached_parameter, maxsize = 1 )
62
+ cached_algo = CacheableAlgorithm (cache)
63
+ # Inital reco misses cache
64
+ @test reconstruct (algo, 42 ) == reconstruct (cached_algo, 42 )
65
+ @test cache_misses[] == 1
66
+ cache_misses[] = 0
67
+ # Other value misses cache
68
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
69
+ @test cache_misses[] == 1
70
+ cache_misses[] = 0
71
+ # Repeated value hits cache
72
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
73
+ @test cache_misses[] == 0
74
+ cache_misses[] = 0
75
+ # Changing parameter results in cache miss
76
+ uncached_parameter. factor = 5
77
+ cached_parameter. factor = 5
78
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
79
+ @test cache_misses[] == 1
80
+ cache_misses[] = 0
81
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
82
+ @test cache_misses[] == 0
83
+ cache_misses[] = 0
84
+ # Changing algorithm results in cache miss
85
+ algo. value = 2
86
+ cached_algo. value = 2
87
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
88
+ @test cache_misses[] == 1
89
+ cache_misses[] = 0
90
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
91
+ @test cache_misses[] == 0
92
+ cache_misses[] = 0
93
+
94
+ @testset " Resize" begin
95
+ resize! (cache, 3 )
96
+ for i in 1 : 3
97
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
98
+ end
99
+ old_misses = cache_misses[]
100
+ for i in 1 : 3
101
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
102
+ @test cache_misses[] == old_misses
103
+ end
104
+ resize! (cache, 0 )
105
+ for i in 1 : 3
106
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
107
+ end
108
+ @test cache_misses[] == old_misses + 3
109
+ end
110
+
111
+
112
+ end
113
+
114
+ @testset " Pure Process" begin
115
+ uncached_parameter = CacheableParameter (3 , Ref (0 ))
116
+ algo = CacheableAlgorithm (uncached_parameter)
117
+
118
+ cache_misses = Ref (0 )
119
+ cached_parameter = PureCacheableParameter (3 , cache_misses)
120
+ cache = ProcessResultCache (; param = cached_parameter, maxsize = 1 )
121
+ cached_algo = CacheableAlgorithm (cache)
122
+ # Inital reco misses cache
123
+ @test reconstruct (algo, 42 ) == reconstruct (cached_algo, 42 )
124
+ @test cache_misses[] == 1
125
+ cache_misses[] = 0
126
+ # Other value misses cache
127
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
128
+ @test cache_misses[] == 1
129
+ cache_misses[] = 0
130
+ # Repeated value hits cache
131
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
132
+ @test cache_misses[] == 0
133
+ cache_misses[] = 0
134
+ # Changing parameter results in cache miss
135
+ uncached_parameter. factor = 5
136
+ cached_parameter. factor = 5
137
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
138
+ @test cache_misses[] == 1
139
+ cache_misses[] = 0
140
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
141
+ @test cache_misses[] == 0
142
+ cache_misses[] = 0
143
+ # Changing algorithm results in no cache miss
144
+ algo. value = 2
145
+ cached_algo. value = 2
146
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
147
+ @test cache_misses[] == 0
148
+ cache_misses[] = 0
149
+ @test reconstruct (algo, 3 ) == reconstruct (cached_algo, 3 )
150
+ @test cache_misses[] == 0
151
+ cache_misses[] = 0
152
+
153
+ @testset " Resize" begin
154
+ resize! (cache, 3 )
155
+ for i in 1 : 3
156
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
157
+ end
158
+ old_misses = cache_misses[]
159
+ for i in 1 : 3
160
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
161
+ @test cache_misses[] == old_misses
162
+ end
163
+ resize! (cache, 0 )
164
+ for i in 1 : 3
165
+ @test reconstruct (algo, i) == reconstruct (cached_algo, i)
166
+ end
167
+ @test cache_misses[] == old_misses + 3
168
+ end
169
+
170
+ end
171
+
172
+ @testset " RecoPlan" begin
173
+
174
+ end
175
+
176
+ end
0 commit comments