Browse Source

Added support of "thread based cache"

master
Artyom Beilis 14 years ago
parent
commit
64c09510f8
20 changed files with 290 additions and 167 deletions
  1. +5
    -1
      CMakeLists.txt
  2. +5
    -1
      application.cpp
  3. +2
    -0
      application.h
  4. +0
    -38
      base_cache.cpp
  5. +11
    -9
      base_cache.h
  6. +42
    -19
      cache_interface.cpp
  7. +23
    -7
      cache_interface.h
  8. +40
    -0
      cache_pool.cpp
  9. +24
    -0
      cache_pool.h
  10. +6
    -0
      config.js
  11. +13
    -0
      hello_world.cpp
  12. +8
    -1
      http_context.cpp
  13. +2
    -0
      http_context.h
  14. +17
    -5
      http_response.cpp
  15. +9
    -4
      http_response.h
  16. +7
    -0
      service.cpp
  17. +4
    -1
      service.h
  18. +1
    -0
      service_impl.h
  19. +64
    -21
      thread_cache.cpp
  20. +7
    -60
      thread_cache.h

+ 5
- 1
CMakeLists.txt View File

@@ -214,7 +214,11 @@ set(CPPCMS_SOURCES
encoding.cpp
regex.cpp
form.cpp
filters.cpp)
filters.cpp
cache_pool.cpp
cache_interface.cpp
thread_cache.cpp
)





+ 5
- 1
application.cpp View File

@@ -185,11 +185,15 @@ void application::render(std::string skin,std::string template_name,std::ostream
service().views_pool().render(skin,template_name,out,content);
}

cache_interface &application::cache()
{
return context().cache();
}


void application::recycle()
{
if(root()->d->conn) {
response().out() << std::flush;
response().finalize();
context().async_complete_response();
}


+ 2
- 0
application.h View File

@@ -15,6 +15,7 @@ namespace cppcms {
class applications_pool;
class application;
class base_content;
class cache_interface;

namespace locale {
class environment;
@@ -42,6 +43,7 @@ namespace cppcms {
http::request &request();
http::response &response();
url_dispatcher &dispatcher();
cache_interface &cache();

void render(std::string template_name,base_content &content);
void render(std::string skin,std::string template_name,base_content &content);


+ 0
- 38
base_cache.cpp View File

@@ -1,38 +0,0 @@
#include "base_cache.h"
namespace cppcms {

using namespace std;


bool base_cache::fetch(string const &key,string &a,set<string> &tags)
{
return false;
};

void base_cache::clear()
{
// Nothing
}
void base_cache::rise(string const &trigger)
{
// Nothing
}

void base_cache::store(string const &key,set<string> const &triggers,time_t timeout,string const &a)
{
// Nothing
}

base_cache::~base_cache()
{
// Nothing
}

void base_cache::stats(unsigned &keys,unsigned &triggers)
{
keys=0;
triggers=0;
}

}


+ 11
- 9
base_cache.h View File

@@ -7,17 +7,19 @@
#include "refcounted.h"

namespace cppcms {
namespace impl {
class base_cache : public refcounted {
public:
virtual bool fetch(std::string const &key,std::string &a,std::set<std::string> &tags);
virtual void store(std::string const &key,std::set<std::string> const &triggers,time_t timeout,std::string const &value);
virtual void rise(std::string const &trigger);
virtual void clear();
virtual void stats(unsigned &keys,unsigned &triggers);
virtual ~base_cache();
virtual bool fetch(std::string const &key,std::string &a,std::set<std::string> *tags) = 0;
virtual void store(std::string const &key,std::string const &b,std::set<std::string> const &triggers,time_t timeout) = 0;
virtual void rise(std::string const &trigger) = 0;
virtual void clear() = 0;
virtual void stats(unsigned &keys,unsigned &triggers) = 0;
virtual ~base_cache()
{
}
};

}
} // impl
} // cppcms
#endif

+ 42
- 19
cache_interface.cpp View File

@@ -1,6 +1,12 @@
#define CPPCMS_SOURCE
#include "cache_interface.h"
#include "config.h"
#include "base_cache.h"
#include "cache_pool.h"
#include "http_context.h"
#include "http_response.h"
#include "json.h"
#include "service.h"
#include "cppcms_error.h"
#include <sstream>
#include <iostream>

@@ -29,7 +35,13 @@ namespace {
struct cache_interface::data {};

cache_interface::cache_interface(http::context &context) :
context_(context)
context_(&context),
page_compression_used_(0)
{
cache_module_ = context_->service().cache_pool().get();
}

cache_interface::~cache_interface()
{
}

@@ -38,14 +50,17 @@ bool cache_interface::fetch_page(string const &key)
{
if(nocache()) return false;

bool zip = context_->response().need_gzip();
bool gzip = context_->response().need_gzip();
page_compression_used_ = gzip;

std::string r_key = (gzip ? "_Z:" : "_U:") + key;

std::string tmp;
if(caching_module->fetch_page(key,tmp,zip)) {
if(cache_module_->fetch(r_key,tmp,0)) {
if(gzip)
context_->response().context_encoding("gzip");
context_->out().write(tmp.c_str(),tmp.size());
context_->response().content_encoding("gzip");
context_->response().out().write(tmp.c_str(),tmp.size());
return true;
}
else {
@@ -59,38 +74,45 @@ void cache_interface::store_page(string const &key,int timeout)
if(nocache()) return;

context_->response().finalize();
bool zip = context_->response().need_gzip();
cms->caching_module->store_page(key,context->response().copied_data(),triggers_,deadtime(timeout),zip)

std::string r_key = (page_compression_used_ ? "_Z:" : "_U:") + key;
triggers_.insert(key);
cache_module_->store(r_key,context_->response().copied_data(),triggers_,deadtime(timeout));
}

void cache_interface::store_frame(std::string const &key,std::string const &frame,std::set<std::string> const &triggers,int timeout,bool notriggers)
{
store(key,frame,triggers,timeout,notriggers);
}

void cache_interface::store_frame(std::string const &key,
std::string const &frame,
int timeout,
bool notriggers=false)
bool notriggers)
{
store_frame(key,frame,set<std::string>(),timeout,notriggers);
}

void cache_interface::nocache()
bool cache_interface::nocache()
{
return caching_module_.get()!=0;
return cache_module_.get()==0;
}

void cache_interface::has_cache()
bool cache_interface::has_cache()
{
return !nocache();
}

void cache_interface::add_trigger(string const &t)
{
if(nocache()) return false;
if(nocache()) return;
triggers_.insert(t);
}

void cache_interface::rise(string const &t)
{
if(nocache()) return;
caching_module_->rise(t);
cache_module_->rise(t);
}

bool cache_interface::fetch_frame(string const &key,string &result,bool notriggers)
@@ -102,7 +124,8 @@ bool cache_interface::fetch(string const &key,string &result,bool notriggers)
{
if(nocache()) return false;
set<string> new_trig;
if(caching_module_->fetch(key,result,new_trig)) {

if(cache_module_->fetch(key,result, (notriggers ? 0 : &new_trig))) {
if(!notriggers)
triggers_.insert(new_trig.begin(),new_trig.end());
return true;
@@ -120,19 +143,19 @@ void cache_interface::store(string const &key,string const &data,
this->triggers_.insert(triggers.begin(),triggers.end());
this->triggers_.insert(key);
}
cache_module_->store(key,triggers,deadtime(timeout),data);
cache_module_->store(key,data,triggers,deadtime(timeout));
}

void cache_interface::clear()
{
if(nocache()) return;
caching_module_->clear();
cache_module_->clear();
}

bool cache_interface::stats(unsigned &k,unsigned &t)
{
if(nocache()) return false;
caching_module_->stats(k,t);
cache_module_->stats(k,t);
return true;
}



+ 23
- 7
cache_interface.h View File

@@ -7,10 +7,19 @@
#include "defs.h"
#include "noncopyable.h"
#include "intrusive_ptr.h"
#include "hold_ptr.h"

namespace cppcms {

class base_cache;
namespace impl {
class base_cache;
}
namespace http {
class context;
};

template<typename Object>
struct serialization_traits;

class CPPCMS_API cache_interface : public util::noncopyable {
public:
@@ -21,8 +30,11 @@ namespace cppcms {
void rise(std::string const &trigger);
void add_trigger(std::string const &trigger);
void clear();
void reset();
bool stats(unsigned &keys,unsigned &triggers);
bool has_cache();
bool nocache();


bool fetch_page(std::string const &key);
@@ -37,7 +49,7 @@ namespace cppcms {
bool notriggers=false);

void store_frame(std::string const &key,
string const &frame,
std::string const &frame,
int timeout,
bool notriggers=false);

@@ -64,26 +76,30 @@ namespace cppcms {
template<typename Serializable>
void store_data(std::string const &key,Serializable const &data,int timeout,bool notriggers=false)
{
store_data<Serializable>(key,data,set<std::string>(),timeout,notriggers);
store_data<Serializable>(key,data,std::set<std::string>(),timeout,notriggers);
}

private:


void store( std::string const &key,
char const *buffer,
size_t size,
std::string const &data,
std::set<std::string> const &triggers,
int timeout,
bool notriggers);

bool fetch( std::string const &key,
std::string &buffer,
bool notriggers)
bool notriggers);

struct data;
util::hold_ptr<data> d;
http::context *context_;
std::set<std::string> triggers_;
intrusive_ptr<base_cache> cache_module_;
intrusive_ptr<impl::base_cache> cache_module_;

uint32_t page_compression_used_ : 1;
uint32_t reserved : 31;
};




+ 40
- 0
cache_pool.cpp View File

@@ -0,0 +1,40 @@
#define CPPCMS_SOURCE
#include "cache_pool.h"
#include "thread_cache.h"
#include "base_cache.h"
#include "cppcms_error.h"
#include "json.h"

namespace cppcms {

struct cache_pool::data {
intrusive_ptr<impl::base_cache> module;
};

cache_pool::cache_pool(json::value const &settings) :
d(new data())
{
std::string type = settings.get("cache.backend","none");
if(type == "none" )
return;
if(type=="threaded") {
if(settings.get("service.procs",0)>1)
throw cppcms_error("Can't use `threaded' backend with more then one process");
unsigned items = settings.get("cache.limit",64);
d->module=impl::thread_cache_factory(items);
}
else {
throw cppcms_error("Unsupported cache backend `" + type + "'");
}
}

cache_pool::~cache_pool()
{
}

intrusive_ptr<impl::base_cache> cache_pool::get()
{
return d->module;
}

} // cppcms

+ 24
- 0
cache_pool.h View File

@@ -0,0 +1,24 @@
#ifndef CPPCMS_CACHE_POOL_H
#define CPPCMS_CACHE_POOL_H

#include "defs.h"
#include "noncopyable.h"
#include "intrusive_ptr.h"
#include "hold_ptr.h"

namespace cppcms {
namespace json { class value; }
namespace impl { class base_cache; }
class CPPCMS_API cache_pool {
public:
cache_pool(json::value const &settings);
~cache_pool();
intrusive_ptr<impl::base_cache> get();
private:
struct data;
util::hold_ptr<data> d;
};
}

#endif

+ 6
- 0
config.js View File

@@ -26,6 +26,7 @@
},
"gzip" : {
"enable" : true, // Default true
//"enable" : false, // Default true
// "level" : 1,
// "buffer" : 4096
},
@@ -52,6 +53,11 @@
// "skins" : [ "skin3" ],
"auto_reload" : true
},
"cache" : {
"backend" : "threaded",
"limit" : 100, // items
"memsize" : 64, // KBs
},
"file_server" : {
"enable" : true,
"doument_root" : "."


+ 13
- 0
hello_world.cpp View File

@@ -11,6 +11,7 @@
#include "aio_timer.h"
#include "intrusive_ptr.h"
#include "form.h"
#include "cache_interface.h"
#include <sstream>
#include <stdexcept>
#include <stdlib.h>
@@ -209,12 +210,24 @@ public:
dispatcher().assign("^/err$",&hello::err,this);
dispatcher().assign("^/forward$",&hello::forward,this);
dispatcher().assign("^/form$",&hello::form,this);
dispatcher().assign("^/cache/?$",&hello::cached,this);
dispatcher().assign(".*",&hello::hello_world,this);
}
~hello()
{
}

void cached()
{
if(cache().fetch_page("test"))
return;

response().out() <<
"<html><body>Time :" << cppcms::locale::format("{1,time=f}") % time(0) << "</body></html>\n";

cache().store_page("test",10);
}

void view_test(std::string skin)
{
view::hello c;


+ 8
- 1
http_context.cpp View File

@@ -1,5 +1,4 @@
#define CPPCMS_SOURCE

#include "cgi_api.h"
#include "service.h"
#include "http_context.h"
@@ -10,6 +9,7 @@
#include "thread_pool.h"
#include "url_dispatcher.h"
#include "views_pool.h"
#include "cache_interface.h"
#include "cppcms_error.h"

#include "config.h"
@@ -29,6 +29,7 @@ namespace http {
std::string skin;
http::request request;
std::auto_ptr<http::response> response;
std::auto_ptr<cache_interface> cache;
data(context &cntx) :
locale(cntx.connection().service().locale()),
request(cntx.connection())
@@ -42,6 +43,7 @@ context::context(intrusive_ptr<impl::cgi::connection> conn) :
d.reset(new data(*this));
d->response.reset(new http::response(*this));
skin(service().views_pool().default_skin());
d->cache.reset(new cache_interface(*this));
}

std::string context::skin()
@@ -49,6 +51,11 @@ std::string context::skin()
return d->skin;
}

cache_interface &context::cache()
{
return *d->cache;
}

void context::skin(std::string const &skin)
{
d->skin=skin;


+ 2
- 0
http_context.h View File

@@ -14,6 +14,7 @@ namespace cppcms {

class service;
class application;
class cache_interface;
namespace json { class value; }
namespace impl { namespace cgi { class connection; } }

@@ -31,6 +32,7 @@ namespace cppcms {
http::request &request();
http::response &response();
json::value const &settings();
cache_interface &cache();
std::locale locale();
void locale(std::locale const &new_locale);
void locale(std::string const &name);


+ 17
- 5
http_response.cpp View File

@@ -91,7 +91,8 @@ response::response(context &context) :
io_mode_(normal),
disable_compression_(0),
ostream_requested_(0),
copy_to_cache_(0)
copy_to_cache_(0),
finalized_(0)
{
set_content_header("text/html");
if(context_.settings().get("server.disable_xpowered_by",false)==0) {
@@ -145,8 +146,11 @@ void response::set_header(std::string const &name,std::string const &value)

void response::finalize()
{
d->filter.reset();
d->output<<std::flush;
if(!finalized_) {
out()<<std::flush;
d->filter.reset();
finalized_=1;
}
}

std::string response::get_header(std::string const &name)
@@ -207,10 +211,16 @@ void response::write_http_headers(std::ostream &out)
}


void response::copy_to_cache(std::string const &key)
void response::copy_to_cache()
{
copy_to_cache_=1;
cache_key_=key;
}

std::string response::copied_data()
{
if(!copy_to_cache_ || !ostream_requested_)
return std::string();
return d->cached.str();
}

std::ostream &response::out()
@@ -219,6 +229,8 @@ std::ostream &response::out()

if(ostream_requested_)
return *stream_;
if(finalized_)
throw cppcms_error("Request for output stream for finalized request is illegal");
ostream_requested_=1;



+ 9
- 4
http_response.h View File

@@ -10,11 +10,13 @@
#include "cstdint.h"

namespace cppcms {
class cache_interface;
namespace impl { namespace cgi { class connection; }}
namespace http {

class context;
class cookie;

class CPPCMS_API response : public util::noncopyable {
public:
// RFC 2616 sec. 6.1.1
@@ -120,7 +122,6 @@ namespace http {
io_mode_type io_mode();
void io_mode(io_mode_type);
std::ostream &out();
void copy_to_cache(std::string const &key);

static std::string make_http_time(time_t);
static char const *status_to_string(int status);
@@ -132,10 +133,14 @@ namespace http {
~response();
private:
friend class impl::cgi::connection;
friend class ::cppcms::cache_interface;

void copy_to_cache();
std::string copied_data();
bool need_gzip();

std::pair<char const *,size_t> output();

bool need_gzip();
void write_http_headers(std::ostream &);
std::string get_async_chunk();

@@ -145,12 +150,12 @@ namespace http {
context &context_;
std::ostream *stream_;
io_mode_type io_mode_;
std::string cache_key_;

uint32_t disable_compression_ : 1;
uint32_t ostream_requested_ : 1;
uint32_t copy_to_cache_ : 1;
uint32_t reserved_ : 29;
uint32_t finalized_ : 1;
uint32_t reserved_ : 28;
};

} /* http */


+ 7
- 0
service.cpp View File

@@ -9,6 +9,7 @@
#include "cgi_api.h"
#include "scgi_api.h"
#include "http_api.h"
#include "cache_pool.h"
#include "fastcgi_api.h"
#include "internal_file_server.h"
#include "json.h"
@@ -149,6 +150,12 @@ void service::setup()
int apps=settings().get("service.applications_pool_size",threads_no()*2);
impl_->applications_pool_.reset(new cppcms::applications_pool(*this,apps));
impl_->views_pool_.reset(new cppcms::views_pool(settings()));
impl_->cache_pool_.reset(new cppcms::cache_pool(settings()));
}

cppcms::cache_pool &service::cache_pool()
{
return *impl_->cache_pool_;
}

cppcms::views_pool &service::views_pool()


+ 4
- 1
service.h View File

@@ -16,6 +16,7 @@ namespace cppcms {

class applications_pool;
class thread_pool;
class cache_pool;
class views_pool;
namespace json {
class value;
@@ -31,10 +32,12 @@ namespace cppcms {
void run();
void shutdown();

json::value const &settings();
cppcms::applications_pool &applications_pool();
cppcms::thread_pool &thread_pool();
json::value const &settings();
cppcms::views_pool &views_pool();
cppcms::cache_pool &cache_pool();

locale::generator const &generator();
std::locale locale();


+ 1
- 0
service_impl.h View File

@@ -36,6 +36,7 @@ namespace impl {
std::auto_ptr<thread_pool> thread_pool_;
std::auto_ptr<locale::generator> locale_generator_;
std::auto_ptr<views_pool> views_pool_;
std::auto_ptr<cache_pool> cache_pool_;
std::locale default_locale_;

#ifdef CPPCMS_WIN32


+ 64
- 21
thread_cache.cpp View File

@@ -1,26 +1,63 @@
#define CPPCMS_SOURCE
#include "config.h"

#if !defined(CPPCMS_EMBEDDED) || defined(CPPCMS_EMBEDDED_THREAD)

#include "thread_cache.h"
#ifdef CPPCMS_USE_EXTERNAL_BOOST
# include <boost/thread.hpp>
# include <boost/format.hpp>
#else // Internal Boost
# include <cppcms_boost/thread.hpp>
# include <cppcms_boost/format.hpp>
namespace boost = cppcms_boost;
#endif
#include <unistd.h>
#include "posix_mutex.h"

using boost::format;
using boost::str;
using namespace std;

namespace cppcms {
namespace impl {

class thread_cache : public base_cache {
boost::mutex lru_mutex;
boost::shared_mutex access_lock;
struct container {
string data;
typedef std::map<string,container>::iterator pointer;
list<pointer>::iterator lru;
list<multimap<string,pointer>::iterator> triggers;
multimap<time_t,pointer>::iterator timeout;
};
typedef container::pointer pointer;
std::map<string,container> primary;
multimap<string,pointer> triggers;
typedef multimap<string,pointer>::iterator triggers_ptr;
multimap<time_t,pointer> timeout;
typedef multimap<time_t,pointer>::iterator timeout_ptr;
list<pointer> lru;
typedef list<pointer>::iterator lru_ptr;
unsigned limit;

string const *get(string const &key,set<string> *triggers);
void delete_node(pointer p);
void print_all();
bool debug_mode;
int fd;

public:
void set_debug_mode(int fd) { debug_mode=true; this->fd=fd; };
thread_cache(unsigned pages=0) : limit(pages) {
debug_mode=false;
};
void set_size(unsigned l) { limit=l; };
virtual bool fetch(string const &key,string &a,std::set<std::string> *tags);
virtual void rise(string const &trigger);
virtual void clear();
virtual void stats(unsigned &keys,unsigned &triggers);
virtual void store(string const &key,std::string const &a,set<string> const &triggers,time_t timeout);
virtual ~thread_cache();
}; // thread cache


thread_cache::~thread_cache()
{
pthread_mutex_destroy(&lru_mutex);
pthread_rwlock_destroy(&access_lock);
}

std::string const *thread_cache::get(string const &key,set<string> *triggers)
@@ -50,13 +87,13 @@ std::string const *thread_cache::get(string const &key,set<string> *triggers)
}
}
{
mutex_lock lock(lru_mutex);
boost::unique_lock<boost::mutex> lock(lru_mutex);
lru.erase(p->second.lru);
lru.push_front(p);
p->second.lru=lru.begin();
}
if(debug_mode){
string res=str(boost::format("Fetched [%1%] triggers:") % key);
string res=(boost::format("Fetched [%1%] triggers:") % key).str();
list<triggers_ptr>::iterator tp;
for(tp=p->second.triggers.begin();
tp!=p->second.triggers.end();tp++)
@@ -71,10 +108,10 @@ std::string const *thread_cache::get(string const &key,set<string> *triggers)
}


bool thread_cache::fetch(string const &key,std::string &a,set<string> &tags)
bool thread_cache::fetch(string const &key,std::string &a,set<string> *tags)
{
rwlock_rdlock lock(access_lock);
string const *r=get(key,&tags);
boost::shared_lock<boost::shared_mutex> lock(access_lock);
string const *r=get(key,tags);
if(!r) return false;
a = *r;
return true;
@@ -82,7 +119,7 @@ bool thread_cache::fetch(string const &key,std::string &a,set<string> &tags)

void thread_cache::clear()
{
rwlock_wrlock lock(access_lock);
boost::unique_lock<boost::shared_mutex> lock(access_lock);
timeout.clear();
lru.clear();
primary.clear();
@@ -90,14 +127,14 @@ void thread_cache::clear()
}
void thread_cache::stats(unsigned &keys,unsigned &triggers)
{
rwlock_rdlock lock(access_lock);
boost::shared_lock<boost::shared_mutex> lock(access_lock);
keys=primary.size();
triggers=this->triggers.size();
}

void thread_cache::rise(string const &trigger)
{
rwlock_wrlock lock(access_lock);
boost::unique_lock<boost::shared_mutex> lock(access_lock);
if(debug_mode) print_all();
pair<triggers_ptr,triggers_ptr> range=triggers.equal_range(trigger);
triggers_ptr p;
@@ -122,9 +159,9 @@ void thread_cache::rise(string const &trigger)
write(fd,"\n",1);
}

void thread_cache::store(string const &key,set<string> const &triggers_in,time_t timeout_in,std::string const &a)
void thread_cache::store(string const &key,std::string const &a,set<string> const &triggers_in,time_t timeout_in)
{
rwlock_wrlock lock(access_lock);
boost::unique_lock<boost::shared_mutex> lock(access_lock);
if(debug_mode) print_all();
pointer main;
if(debug_mode) {
@@ -232,8 +269,14 @@ void thread_cache::print_all()
write(fd,res.c_str(),res.size());
}

};
intrusive_ptr<base_cache> thread_cache_factory(unsigned items)
{
return new thread_cache(items);
}


} // impl
} // cppcms

#endif



+ 7
- 60
thread_cache.h View File

@@ -1,70 +1,17 @@
#ifndef THREAD_CHACHE_H
#define THREAD_CHACHE_H
#include "config.h"
#include "base_cache.h"
#include "cache_interface.h"
#include "pthread.h"
#include "intrusive_ptr.h"
#include <map>
#include <list>
namespace cppcms {

using namespace std;

#if !defined(CPPCMS_EMBEDDED) || defined(CPPCMS_EMBEDDED_THREAD)

class thread_cache : public base_cache {
pthread_mutex_t lru_mutex;
pthread_rwlock_t access_lock;
struct container {
string data;
typedef std::map<string,container>::iterator pointer;
list<pointer>::iterator lru;
list<multimap<string,pointer>::iterator> triggers;
multimap<time_t,pointer>::iterator timeout;
};
typedef container::pointer pointer;
std::map<string,container> primary;
multimap<string,pointer> triggers;
typedef multimap<string,pointer>::iterator triggers_ptr;
multimap<time_t,pointer> timeout;
typedef multimap<time_t,pointer>::iterator timeout_ptr;
list<pointer> lru;
typedef list<pointer>::iterator lru_ptr;
unsigned limit;

string const *get(string const &key,set<string> *triggers);
void delete_node(pointer p);
void print_all();
bool debug_mode;
int fd;

public:
void set_debug_mode(int fd) { debug_mode=true; this->fd=fd; };
thread_cache(unsigned pages=0) : limit(pages) {
pthread_mutex_init(&lru_mutex,NULL);
pthread_rwlock_init(&access_lock,NULL);
debug_mode=false;
};
void set_size(unsigned l) { limit=l; };
virtual bool fetch(string const &key,string &a,std::set<std::string> &tags);
virtual void rise(string const &trigger);
virtual void clear();
virtual void stats(unsigned &keys,unsigned &triggers);
virtual void store(string const &key,set<string> const &triggers,time_t timeout,std::string const &a);
virtual ~thread_cache();
};

class thread_cache_factory : public cache_factory{
thread_cache *cache;
public:
thread_cache_factory(unsigned n) : cache(new thread_cache(n)) {};
virtual base_cache *get() const { return cache; };
virtual void del(base_cache *p) const { };
virtual ~thread_cache_factory() { delete cache; };
};

#endif

}
namespace cppcms {
namespace impl {
intrusive_ptr<base_cache> thread_cache_factory(unsigned items);
} // impl
} // cppcms

#endif

Loading…
Cancel
Save