File: cache.cpp

package info (click to toggle)
aspell 0.60.6-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 10,000 kB
  • ctags: 4,862
  • sloc: sh: 48,145; cpp: 22,153; perl: 1,546; ansic: 1,535; makefile: 684; sed: 16
file content (122 lines) | stat: -rw-r--r-- 2,321 bytes parent folder | download | duplicates (4)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <assert.h>

#include "stack_ptr.hpp"
#include "cache-t.hpp"

namespace acommon {

static StackPtr<Mutex> global_cache_lock(new Mutex);
static GlobalCacheBase * first_cache = 0;

void Cacheable::copy() const
{
  //CERR << "COPY\n";
  LOCK(&cache->lock);
  refcount++;
}

void GlobalCacheBase::del(Cacheable * n)
{
  *n->prev = n->next;
  if (n->next) n->next->prev = n->prev;
  n->next = 0;
  n->prev = 0;
}

void GlobalCacheBase::add(Cacheable * n) 
{
  assert(n->refcount > 0);
  n->next = first;
  n->prev = &first;
  if (first) first->prev = &n->next;
  first = n;
  n->cache = this;
}

void GlobalCacheBase::release(Cacheable * d) 
{
  //CERR << "RELEASE\n";
  LOCK(&lock);
  d->refcount--;
  assert(d->refcount >= 0);
  if (d->refcount != 0) return;
  //CERR << "DEL\n";
  if (d->attached()) del(d);
  delete d;
}

void GlobalCacheBase::detach(Cacheable * d)
{
  LOCK(&lock);
  if (d->attached()) del(d);
}

void GlobalCacheBase::detach_all()
{
  LOCK(&lock);
  Cacheable * p = first;
  while (p) {
    *p->prev = 0;
    p->prev = 0;
    p = p->next;
  }
}

void release_cache_data(GlobalCacheBase * cache, const Cacheable * d)
{
  cache->release(const_cast<Cacheable *>(d));
}

GlobalCacheBase::GlobalCacheBase(const char * n)
  : name (n)
{
  LOCK(global_cache_lock);
  next = first_cache;
  prev = &first_cache;
  if (first_cache) first_cache->prev = &next;
  first_cache = this;
}

GlobalCacheBase::~GlobalCacheBase()
{
  detach_all();
  LOCK(global_cache_lock);
  *prev = next;
  if (next) next->prev = prev;
}

bool reset_cache(const char * which)
{
  LOCK(global_cache_lock);
  bool any = false;
  for (GlobalCacheBase * i = first_cache; i; i = i->next)
  {
    if (which && strcmp(i->name, which) == 0) {i->detach_all(); any = true;}
  }
  return any;
}

extern "C"
int aspell_reset_cache(const char * which)
{
  return reset_cache(which);
}

#if 0

struct CacheableImpl : public Cacheable
{
  class CacheConfig;
  typedef String CacheKey;
  bool cache_key_eq(const CacheKey &);
  static PosibErr<CacheableImpl *> get_new(const CacheKey &, CacheConfig *);
};

template
PosibErr<CacheableImpl *> get_cache_data(GlobalCache<CacheableImpl> *, 
                                         CacheableImpl::CacheConfig *, 
                                         const CacheableImpl::CacheKey &);

#endif

}