forked from artyom-beilis/cppcms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache_over_ip.cpp
More file actions
133 lines (120 loc) · 3.13 KB
/
cache_over_ip.cpp
File metadata and controls
133 lines (120 loc) · 3.13 KB
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
123
124
125
126
127
128
129
130
131
132
133
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// See accompanying file COPYING.TXT file for licensing details.
//
///////////////////////////////////////////////////////////////////////////////
#define CPPCMS_SOURCE
#include "tcp_cache_client.h"
#include <booster/atomic_counter.h>
#include <booster/thread.h>
namespace cppcms {
namespace impl {
class cache_over_ip : public base_cache {
public:
cache_over_ip(std::vector<std::string> ips,std::vector<int> ports,booster::intrusive_ptr<base_cache> l1) :
ips_(ips),
ports_(ports),
l1_(l1),
refs_(0)
{
}
bool fetch( std::string const &key,
std::string *a,std::set<std::string> *tags,
time_t *timeout_out,
uint64_t *gen)
{
std::string buffer;
if(!a) a=&buffer;
time_t tmp_timeout;
if(!timeout_out) timeout_out=&tmp_timeout;
uint64_t generation;
if(!gen) gen=&generation;
if(!l1_.get()) {
if(tcp()->fetch(key,*a,tags,*timeout_out,*gen,false)==tcp_cache::found)
return true;
return false;
}
std::set<std::string> tmp_triggers;
if(!tags) tags=&tmp_triggers;
if(l1_->fetch(key,a,tags,timeout_out,gen)) {
int res = tcp()->fetch(key,*a,tags,*timeout_out,*gen,true);
if(res==tcp_cache::up_to_date)
return true;
if(res==tcp_cache::not_found) {
l1_->remove(key);
return false;
}
l1_->store(key,*a,*tags,*timeout_out,gen);
return true;
}
else {
if(tcp()->fetch(key,*a,tags,*timeout_out,*gen,false)==tcp_cache::found) {
l1_->store(key,*a,*tags,*timeout_out,gen);
return true;
}
return false;
}
}
virtual void store(std::string const &key,std::string const &b,std::set<std::string> const &triggers,time_t timeout,uint64_t const * /*gen*/)
{
if(l1_.get())
l1_->remove(key);
tcp()->store(key,b,triggers,timeout);
}
virtual void rise(std::string const &trigger)
{
if(l1_.get())
l1_->rise(trigger);
tcp()->rise(trigger);
}
virtual void remove(std::string const &/*key*/)
{
// NA
}
virtual void clear()
{
if(l1_.get())
l1_->clear();
tcp()->clear();
}
virtual void stats(unsigned &keys,unsigned &triggers)
{
tcp()->stats(keys,triggers);
}
virtual void add_ref()
{
++refs_;
}
virtual bool del_ref()
{
if(--refs_ == 0)
return true;
return false;
}
virtual ~cache_over_ip()
{
}
private:
tcp_cache *tcp()
{
if(!tcp_.get())
tcp_.reset(new tcp_cache(ips_,ports_));
return tcp_.get();
}
booster::thread_specific_ptr<tcp_cache> tcp_;
std::vector<std::string> ips_;
std::vector<int> ports_;
booster::intrusive_ptr<base_cache> l1_;
booster::atomic_counter refs_;
};
booster::intrusive_ptr<base_cache> CPPCMS_API
tcp_cache_factory( std::vector<std::string> const &ips,
std::vector<int> const &ports,
booster::intrusive_ptr<base_cache> l1)
{
return new cache_over_ip(ips,ports,l1);
}
} // impl
} // cppcms