c326fd228e49c8f243103644a4c9d0f3fbb9ad36
[platform/upstream/aspell.git] / common / cache-t.hpp
1 #ifndef ACOMMON_CACHE_T__HPP
2 #define ACOMMON_CACHE_T__HPP
3
4 #include "lock.hpp"
5 #include "cache.hpp"
6
7 //#include "iostream.hpp"
8
9 namespace acommon {
10
11 class GlobalCacheBase
12 {
13 public:
14   mutable Mutex lock;
15 public: // but don't use
16   const char * name;
17   GlobalCacheBase * next;
18   GlobalCacheBase * * prev;
19 protected:
20   Cacheable * first;
21   void del(Cacheable * d);
22   void add(Cacheable * n);
23   GlobalCacheBase(const char * n);
24   ~GlobalCacheBase();
25 public:
26   void release(Cacheable * d);
27   void detach(Cacheable * d);
28   void detach_all();
29 };
30
31 template <class D>
32 class GlobalCache : public GlobalCacheBase
33 {
34 public:
35   typedef D Data;
36   typedef typename Data::CacheKey Key;
37 public:
38   GlobalCache(const char * n) : GlobalCacheBase(n) {}
39   // "find" and "add" will _not_ acquire a lock
40   Data * find(const Key & key) {
41     D * cur = static_cast<D *>(first);
42     while (cur && !cur->cache_key_eq(key))
43       cur = static_cast<D *>(cur->next);
44     return cur;
45   }
46   void add(Data * n) {GlobalCacheBase::add(n);}
47   // "release" and "detach" _will_ acquire a lock
48   void release(Data * d) {GlobalCacheBase::release(d);}
49   void detach(Data * d) {GlobalCacheBase::detach(d);}
50 };
51
52 template <class Data>
53 PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache, 
54                                 typename Data::CacheConfig * config, 
55                                 const typename Data::CacheKey & key)
56 {
57   LOCK(&cache->lock);
58   Data * n = cache->find(key);
59   //CERR << "Getting " << key << " for " << cache->name << "\n";
60   if (n) {
61     n->refcount++;
62     return n;
63   }
64   PosibErr<Data *> res = Data::get_new(key, config);
65   if (res.has_err()) {
66     //CERR << "ERROR\n"; 
67     return res;
68   }
69   n = res.data;
70   cache->add(n);
71   //CERR << "LOADED FROM DISK\n";
72   return n;
73 }
74
75 template <class Data>
76 PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache, 
77                                 typename Data::CacheConfig * config, 
78                                 typename Data::CacheConfig2 * config2,
79                                 const typename Data::CacheKey & key)
80 {
81   LOCK(&cache->lock);
82   Data * n = cache->find(key);
83   //CERR << "Getting " << key << "\n";
84   if (n) {
85     n->refcount++;
86     return n;
87   }
88   PosibErr<Data *> res = Data::get_new(key, config, config2);
89   if (res.has_err()) {
90     //CERR << "ERROR\n"; 
91     return res;
92   }
93   n = res.data;
94   cache->add(n);
95   //CERR << "LOADED FROM DISK\n";
96   return n;
97 }
98
99 }
100
101 #endif