This source file includes following definitions.
- select
- id
- id
- process
- process
- statistics_
- internal_cache
- insert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "thread_pool_sequential.hpp"
22 #include "thread_pool_master.hpp"
23 #include "thread_pool_workers.hpp"
24
25 #include <limits>
26 #include <map>
27 #include <time.h>
28
29
30
31
32
33 namespace jmmcg { namespace cache {
34
35 namespace private_ {
36 template<typename Mdl> struct multi_or_sequential {
37 static constexpr enum ppd::pool_traits::size_mode_t infinite_size_type=ppd::pool_traits::size_mode_t::infinite;
38 static constexpr enum ppd::pool_traits::size_mode_t fixed_size_type=ppd::pool_traits::size_mode_t::fixed_size;
39 };
40 template<> struct multi_or_sequential<ppd::sequential_mode> {
41 static constexpr enum ppd::pool_traits::size_mode_t infinite_size_type=ppd::pool_traits::size_mode_t::sequential;
42 static constexpr enum ppd::pool_traits::size_mode_t fixed_size_type=ppd::pool_traits::size_mode_t::sequential;
43 };
44 }
45
46
47 template<typename Key, typename Val, class Comp=std::less<Key>, class Alloc=std::allocator<Val> >
48 struct threading {
49
50 template<ppd::generic_traits::api_type API>
51 struct single {
52
53 typedef std::map<Key, Val, Comp, Alloc> assoc_colln_t;
54 typedef typename assoc_colln_t::value_type::second_type mapped_type;
55
56
57
58
59
60 typedef ppd::thread_pool<
61 ppd::pool_traits::work_distribution_mode_t::one_thread_distributes<>,
62 ppd::pool_traits::size_mode_t::sequential,
63 ppd::pool_aspects<
64 ppd::generic_traits::return_data::joinable,
65 API,
66 ppd::sequential_mode,
67 ppd::pool_traits::normal_fifo
68 >
69 > flusher_pool_t;
70
71
72
73
74
75 typedef ppd::thread_pool<
76 ppd::pool_traits::work_distribution_mode_t::worker_threads_get_work<ppd::pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>,
77 ppd::pool_traits::size_mode_t::sequential,
78 ppd::pool_aspects<
79 ppd::generic_traits::return_data::joinable,
80 API,
81 ppd::sequential_mode,
82 ppd::pool_traits::normal_fifo
83 >
84 > populate_pool_t;
85 };
86
87
88 template<ppd::generic_traits::api_type API, typename Mdl>
89 struct multi {
90
91
92
93
94 typedef std::map<Key,Val,Comp,Alloc> assoc_colln_t;
95 typedef typename assoc_colln_t::value_type::second_type mapped_type;
96 typedef private_::multi_or_sequential<Mdl> multi_or_sequential_chooser;
97
98
99 typedef typename ppd::thread_pool<
100 ppd::pool_traits::work_distribution_mode_t::one_thread_distributes<>,
101 multi_or_sequential_chooser::infinite_size_type,
102 ppd::pool_aspects<
103 ppd::generic_traits::return_data::joinable,
104 API,
105 Mdl,
106 ppd::pool_traits::normal_fifo,
107 std::less
108 >
109 > flusher_pool_t;
110
111
112
113
114
115 typedef typename ppd::thread_pool<
116 ppd::pool_traits::work_distribution_mode_t::worker_threads_get_work<ppd::pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>,
117 multi_or_sequential_chooser::fixed_size_type,
118 ppd::pool_aspects<
119 ppd::generic_traits::return_data::joinable,
120 API,
121 Mdl,
122 ppd::pool_traits::normal_fifo
123 >
124 > populate_pool_t;
125 };
126 };
127
128
129 template<typename Key, typename Data>
130 struct factory_base {
131 typedef Key key_type;
132 typedef Data value_type;
133
134 virtual value_type __fastcall make(const key_type &) const=0;
135 virtual ~factory_base() {}
136 };
137
138
139 template<typename Val>
140 class lru {
141 public:
142 typedef Val value_type;
143
144 class criterion_t {
145 public:
146 explicit constexpr __stdcall criterion_t(const clock_t c) noexcept(true)
147 : oldest(c) {
148 }
149
150 void operator=(criterion_t const &)=delete;
151
152 template<class MapT_> bool __fastcall
153 operator()(const MapT_ &val) const noexcept(true) {
154 return val.second.accessed()<=oldest;
155 }
156
157 private:
158 const clock_t oldest;
159 };
160
161 constexpr __stdcall lru(void);
162 explicit constexpr __stdcall lru(const value_type &);
163 __stdcall lru(const lru &);
164 __stdcall ~lru(void);
165 lru & __fastcall operator=(const lru &);
166
167 const value_type & __fastcall value(void) const noexcept(true);
168 value_type & __fastcall value(void) noexcept(true);
169
170 clock_t __fastcall accessed(void) const noexcept(true);
171
172 template<typename Iter> static const criterion_t __fastcall
173 select(Iter beg,const Iter &end) {
174 clock_t oldest=std::numeric_limits<clock_t>::max();
175 while (beg!=end) {
176 oldest=std::min(oldest,beg++->second.accessed());
177 }
178 return criterion_t(oldest);
179 }
180
181 private:
182 mutable clock_t age;
183 value_type range_value;
184 };
185
186
187 struct no_statistics {
188 typedef unsigned long accesses_type;
189 typedef unsigned long hits_type;
190 typedef unsigned long flushes_type;
191 typedef unsigned long creations_type;
192
193 static constexpr accesses_type __fastcall accesses() noexcept(true) {
194 return 0;
195 }
196 static constexpr hits_type __fastcall hits() noexcept(true) {
197 return 0;
198 }
199 static constexpr flushes_type __fastcall flushes() noexcept(true) {
200 return 0;
201 }
202 static constexpr creations_type __fastcall outstanding_fills() noexcept(true) {
203 return 0;
204 }
205 friend constexpr jmmcg::tostream &operator<<(jmmcg::tostream &os, const no_statistics &) noexcept(true) {
206 return os;
207 }
208
209 static void __fastcall accessed(void) noexcept(true) {}
210 static void __fastcall hit(void) noexcept(true) {}
211 static void __fastcall reset(void) noexcept(true) {}
212 static void __fastcall flushed(void) noexcept(true) {}
213 };
214
215
216 class basic_statistics {
217 public:
218 typedef unsigned long accesses_type;
219 typedef unsigned long hits_type;
220 typedef unsigned long flushes_type;
221 typedef unsigned long creations_type;
222
223 constexpr __stdcall basic_statistics(void) noexcept(true);
224 __stdcall basic_statistics(const basic_statistics &) noexcept(true);
225 virtual __stdcall ~basic_statistics(void) noexcept(true);
226 basic_statistics & __fastcall operator=(const basic_statistics &) noexcept(true);
227
228
229 accesses_type __fastcall accesses(void) const noexcept(true);
230
231 hits_type __fastcall hits(void) const noexcept(true);
232
233 flushes_type __fastcall flushes(void) const noexcept(true);
234
235
236
237
238
239 creations_type __fastcall outstanding_fills(void) const noexcept(true);
240
241
242
243
244
245
246
247 friend jmmcg::tostream &operator<<(jmmcg::tostream &os, const basic_statistics &stats);
248
249
250 void __fastcall accessed(void) noexcept(true);
251
252 void __fastcall hit(void) noexcept(true);
253
254 void __fastcall flushed(void) noexcept(true);
255
256 void __fastcall reset(void) noexcept(true);
257
258 private:
259 accesses_type total_accesses_;
260 hits_type total_hits_;
261 flushes_type total_flushes_;
262 };
263
264
265
266
267
268
269
270
271
272 template<
273 class Factory
274 >
275 class base {
276 public:
277 typedef Factory factory_type;
278 typedef typename factory_type::key_type key_type;
279 typedef typename factory_type::value_type value_type;
280
281 __stdcall base(const base &);
282 virtual __stdcall ~base(void) noexcept(true);
283
284 base & __fastcall operator=(const base &);
285
286
287 virtual bool __fastcall empty() const noexcept(true)=0;
288
289 virtual void __fastcall clear()=0;
290
291
292
293
294
295 virtual void __fastcall flush()=0;
296
297 protected:
298 struct range_data {
299 typename factory_type::value_type data;
300 };
301
302 class find_range_data : virtual protected non_assignable {
303 public:
304 typedef range_data result_type;
305
306 explicit __stdcall find_range_data(const factory_type &f,const key_type &i)
307 : data_factory_(f),id(i) {
308 }
309 __stdcall find_range_data(const find_range_data &gw) noexcept(true)
310 : data_factory_(gw.data_factory_),id(gw.id) {
311 }
312 ~find_range_data() {
313 }
314
315 void __fastcall process(range_data &res) {
316 res.data=data_factory_.make(id);
317 }
318
319 constexpr bool __fastcall operator<(find_range_data const &) const noexcept(true) {
320 return true;
321 }
322
323 private:
324 const factory_type &data_factory_;
325 const key_type id;
326 };
327
328
329 class flush_cache : virtual protected non_assignable {
330 public:
331 typedef void result_type;
332
333 explicit __stdcall flush_cache(base<Factory> &r) noexcept(true)
334 : the_cache(r) {
335 }
336 __stdcall flush_cache(const flush_cache &r) noexcept(true)
337 : the_cache(r.the_cache) {
338 }
339 ~flush_cache() {
340 }
341
342 void __fastcall process() {
343 the_cache.flush();
344 }
345
346 constexpr bool __fastcall operator<(flush_cache const &) const noexcept(true) {
347 return true;
348 }
349
350 private:
351 base<Factory> &the_cache;
352 };
353
354 explicit __stdcall base(const factory_type &f)
355 : data_factory_(f) {
356 }
357
358 const factory_type & __fastcall data_factory() const noexcept(true);
359
360 private:
361 factory_type data_factory_;
362 };
363
364
365
366
367
368 template<
369 class Factory,
370 class FP=lru<typename Factory::value_type>,
371 class ThrT=typename threading<typename Factory::key_type,FP>::template single<ppd::platform_api>,
372 class Stats=no_statistics
373 >
374 class ro : public base<Factory> {
375 public:
376 typedef base<Factory>base_t;
377 typedef typename base_t::factory_type factory_type;
378 typedef typename base_t::key_type key_type;
379 typedef ThrT thread_traits;
380 typedef Stats statistics_type;
381 typedef typename thread_traits::assoc_colln_t colln_t;
382 typedef typename colln_t::size_type size_type;
383 typedef const typename thread_traits::mapped_type mapped_type;
384 typedef typename thread_traits::flusher_pool_t::exception_type exception_type;
385 typedef typename thread_traits::flusher_pool_t::pool_traits_type::os_traits os_traits;
386 typedef typename os_traits::lock_traits lock_traits;
387
388
389
390
391
392
393
394 const size_type low_water_mark;
395
396
397
398
399
400
401 const size_type high_water_mark;
402
403
404
405
406
407
408
409
410
411 explicit constexpr __stdcall ro(const size_type low_water, const size_type high_water, const typename thread_traits::populate_pool_t::pool_type::size_type num_threads, const factory_type &f)
412 : base<Factory>(f), low_water_mark(low_water), high_water_mark(high_water), serialize(), flusher_pool(), populate_pool(num_threads), internal_cache(), statistics_() {
413 }
414
415
416
417
418
419
420
421
422
423
424
425
426
427 template<typename Iter> constexpr __stdcall
428 ro(const size_type low_water, const size_type high_water, const typename thread_traits::populate_pool_t::pool_type::size_type num_threads, const factory_type &f, const Iter &beg, const Iter &end)
429 : base<Factory>(f), low_water_mark(low_water), high_water_mark(high_water), serialize(), flusher_pool(), populate_pool(num_threads), internal_cache(beg, end) {
430 }
431 __stdcall ro(const ro &);
432 virtual __stdcall ~ro(void) noexcept(true);
433
434 ro & __fastcall operator=(const ro &);
435
436
437
438
439
440
441
442
443 bool __fastcall empty(void) const noexcept(true);
444
445
446
447
448
449 const size_type __fastcall size(void) const noexcept(true);
450
451
452
453
454
455
456
457
458 void __fastcall clear(void);
459
460
461
462
463
464
465
466
467
468 template<typename Iter> void __fastcall
469 insert(const Iter &beg, const Iter &end) {
470 internal_cache.insert(beg, end);
471 flusher_pool<<flush_nonjoinable()<<flush_cache(*this);
472 }
473
474
475
476
477
478
479
480
481
482
483 const mapped_type __fastcall operator[](const key_type &key);
484
485
486
487
488
489 void __fastcall flush(void);
490
491 const statistics_type & __fastcall statistics(void) const noexcept(true);
492
493 private:
494 typedef FP victimization_traits;
495 typedef typename lock_traits::critical_section_type atomic_t;
496 typedef typename atomic_t::write_unlockable_type lock_t;
497 typedef typename thread_traits::flusher_pool_t::nonjoinable flush_nonjoinable;
498
499 mutable atomic_t serialize;
500 mutable typename thread_traits::flusher_pool_t flusher_pool;
501 mutable typename thread_traits::populate_pool_t populate_pool;
502 mutable colln_t internal_cache;
503 mutable statistics_type statistics_;
504 };
505
506
507
508
509 template<class F_,class P_,class TT_,class S_> jmmcg::tostream & __fastcall
510 operator<<(jmmcg::tostream &os, const ro<F_,P_,TT_,S_> &r) {
511 os<<_T("Low water-mark=")<<r.low_water_mark
512 <<_T(", high water-mark=")<<r.high_water_mark
513 <<_T(", current number of elements=")<<r.size();
514 return os;
515 }
516
517 } }
518
519 #include "cache_impl.hpp"