File: cache-t.hpp

package info (click to toggle)
aspell 0.60.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,336 kB
  • sloc: cpp: 24,378; sh: 12,340; perl: 1,924; ansic: 1,661; makefile: 852; sed: 16
file content (103 lines) | stat: -rw-r--r-- 2,524 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef ACOMMON_CACHE_T__HPP
#define ACOMMON_CACHE_T__HPP

#include "lock.hpp"
#include "cache.hpp"

//#include "iostream.hpp"

namespace acommon {

class GlobalCacheBase
{
public:
  mutable Mutex lock;
public: // but don't use
  const char * name;
  GlobalCacheBase * next;
  GlobalCacheBase * * prev;
  // The global cache lock must exist while any cache instance is active
  static Mutex global_cache_lock;
protected:
  Cacheable * first;
  void del(Cacheable * d);
  void add(Cacheable * n);
  GlobalCacheBase(const char * n);
  ~GlobalCacheBase();
public:
  void release(Cacheable * d);
  void detach(Cacheable * d);
  void detach_all();
};

template <class D>
class GlobalCache : public GlobalCacheBase
{
public:
  typedef D Data;
  typedef typename Data::CacheKey Key;
public:
  GlobalCache(const char * n) : GlobalCacheBase(n) {}
  // "find" and "add" will _not_ acquire a lock
  Data * find(const Key & key) {
    D * cur = static_cast<D *>(first);
    while (cur && !cur->cache_key_eq(key))
      cur = static_cast<D *>(cur->next);
    return cur;
  }
  void add(Data * n) {GlobalCacheBase::add(n);}
  // "release" and "detach" _will_ acquire a lock
  void release(Data * d) {GlobalCacheBase::release(d);}
  void detach(Data * d) {GlobalCacheBase::detach(d);}
};

template <class Data>
PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache, 
                                typename Data::CacheConfig * config, 
                                const typename Data::CacheKey & key)
{
  LOCK(&cache->lock);
  Data * n = cache->find(key);
  //CERR << "Getting " << key << " for " << cache->name << "\n";
  if (n) {
    n->refcount++;
    return n;
  }
  PosibErr<Data *> res = Data::get_new(key, config);
  if (res.has_err()) {
    //CERR << "ERROR\n"; 
    return res;
  }
  n = res.data;
  cache->add(n);
  //CERR << "LOADED FROM DISK\n";
  return n;
}

template <class Data>
PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache, 
                                typename Data::CacheConfig * config, 
                                typename Data::CacheConfig2 * config2,
                                const typename Data::CacheKey & key)
{
  LOCK(&cache->lock);
  Data * n = cache->find(key);
  //CERR << "Getting " << key << "\n";
  if (n) {
    n->refcount++;
    return n;
  }
  PosibErr<Data *> res = Data::get_new(key, config, config2);
  if (res.has_err()) {
    //CERR << "ERROR\n"; 
    return res;
  }
  n = res.data;
  cache->add(n);
  //CERR << "LOADED FROM DISK\n";
  return n;
}

}

#endif