/src/aspell/common/cache.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include <assert.h> |
2 | | |
3 | | #include "stack_ptr.hpp" |
4 | | #include "cache-t.hpp" |
5 | | |
6 | | namespace acommon { |
7 | | |
8 | | static GlobalCacheBase * first_cache = 0; |
9 | | Mutex GlobalCacheBase::global_cache_lock; |
10 | | |
11 | | void Cacheable::copy() const |
12 | 408 | { |
13 | | //CERR << "COPY\n"; |
14 | 408 | LOCK(&cache->lock); |
15 | 408 | copy_no_lock(); |
16 | 408 | } |
17 | | |
18 | | void GlobalCacheBase::del(Cacheable * n) |
19 | 4.98k | { |
20 | 4.98k | *n->prev = n->next; |
21 | 4.98k | if (n->next) n->next->prev = n->prev; |
22 | 4.98k | n->next = 0; |
23 | 4.98k | n->prev = 0; |
24 | 4.98k | } |
25 | | |
26 | | void GlobalCacheBase::add(Cacheable * n) |
27 | 4.98k | { |
28 | 4.98k | assert(n->refcount > 0); |
29 | 4.98k | n->next = first; |
30 | 4.98k | n->prev = &first; |
31 | 4.98k | if (first) first->prev = &n->next; |
32 | 4.98k | first = n; |
33 | 4.98k | n->cache = this; |
34 | 4.98k | } |
35 | | |
36 | | void GlobalCacheBase::release(Cacheable * d) |
37 | 18.3k | { |
38 | | //CERR << "RELEASE\n"; |
39 | 18.3k | LOCK(&lock); |
40 | 18.3k | d->refcount--; |
41 | 18.3k | assert(d->refcount >= 0); |
42 | 18.3k | if (d->refcount != 0) return; |
43 | | //CERR << "DEL\n"; |
44 | 7.00k | if (d->attached()) del(d); |
45 | 7.00k | delete d; |
46 | 7.00k | } |
47 | | |
48 | | void GlobalCacheBase::detach(Cacheable * d) |
49 | 0 | { |
50 | 0 | LOCK(&lock); |
51 | 0 | if (d->attached()) del(d); |
52 | 0 | } |
53 | | |
54 | | void GlobalCacheBase::detach_all() |
55 | 0 | { |
56 | 0 | LOCK(&lock); |
57 | 0 | Cacheable * p = first; |
58 | 0 | while (p) { |
59 | 0 | *p->prev = 0; |
60 | 0 | p->prev = 0; |
61 | 0 | p = p->next; |
62 | 0 | } |
63 | 0 | } |
64 | | |
65 | | void release_cache_data(GlobalCacheBase * cache, const Cacheable * d) |
66 | 18.3k | { |
67 | 18.3k | cache->release(const_cast<Cacheable *>(d)); |
68 | 18.3k | } |
69 | | |
70 | | GlobalCacheBase::GlobalCacheBase(const char * n) |
71 | 16 | : name (n) |
72 | 16 | { |
73 | 16 | LOCK(&global_cache_lock); |
74 | 16 | next = first_cache; |
75 | 16 | prev = &first_cache; |
76 | 16 | if (first_cache) first_cache->prev = &next; |
77 | 16 | first_cache = this; |
78 | 16 | } |
79 | | |
80 | | GlobalCacheBase::~GlobalCacheBase() |
81 | 0 | { |
82 | 0 | detach_all(); |
83 | 0 | LOCK(&global_cache_lock); |
84 | 0 | *prev = next; |
85 | 0 | if (next) next->prev = prev; |
86 | 0 | } |
87 | | |
88 | | bool reset_cache(const char * which) |
89 | 0 | { |
90 | 0 | LOCK(&GlobalCacheBase::global_cache_lock); |
91 | 0 | bool any = false; |
92 | 0 | for (GlobalCacheBase * i = first_cache; i; i = i->next) |
93 | 0 | { |
94 | 0 | if (which && strcmp(i->name, which) == 0) {i->detach_all(); any = true;} |
95 | 0 | } |
96 | 0 | return any; |
97 | 0 | } |
98 | | |
99 | | extern "C" |
100 | | int aspell_reset_cache(const char * which) |
101 | 0 | { |
102 | 0 | return reset_cache(which); |
103 | 0 | } |
104 | | |
105 | | #if 0 |
106 | | |
107 | | struct CacheableImpl : public Cacheable |
108 | | { |
109 | | class CacheConfig; |
110 | | typedef String CacheKey; |
111 | | bool cache_key_eq(const CacheKey &); |
112 | | static PosibErr<CacheableImpl *> get_new(const CacheKey &, CacheConfig *); |
113 | | }; |
114 | | |
115 | | template |
116 | | PosibErr<CacheableImpl *> get_cache_data(GlobalCache<CacheableImpl> *, |
117 | | CacheableImpl::CacheConfig *, |
118 | | const CacheableImpl::CacheKey &); |
119 | | |
120 | | #endif |
121 | | |
122 | | } |