Menu

[r126]: / framework / branches / cache_support / cache.cpp  Maximize  Restore  History

Download this file

129 lines (113 with data), 2.7 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
#include "cache.h"
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <sstream>
#include <iostream>
#include <boost/format.hpp>
class RWLock {
protected:
pthread_rwlock_t *rwlock;
RWLock(pthread_rwlock_t *p) : rwlock(p) { };
public:
~RWLock() { pthread_rwlock_unlock(rwlock); };
};
class Write_Lock : public RWLock {
public:
Write_Lock(pthread_rwlock_t *p) : RWLock(p) {pthread_rwlock_wrlock(p);};
};
class Read_Lock : public RWLock {
public:
Read_Lock(pthread_rwlock_t *p) : RWLock(p) {pthread_rwlock_rdlock(p);};
};
class Mutex {
protected:
pthread_mutex_t *lock;
public:
Mutex(pthread_mutex_t *p) : lock(p) { pthread_mutex_lock(p); };
~Mutex() { pthread_mutex_unlock(lock); };
};
string Memory_Cache::insert(string const &key,string const &input)
{
string result=deflate(input);
Write_Lock L(&lock);
map_iterator_t it=data.find(key);
if(it==data.end() && data.size()>limit) {
data.erase(*(lru.rbegin()));
lru.pop_back();
}
if(it==data.end()) {
data.insert(pair<string,Container>(key,Container(result,input)));
it=data.find(key);
lru.push_front(it);
it->second.lru_ptr=lru.begin();
}
else {
lru.erase(it->second.lru_ptr);
lru.push_front(it);
it->second.text=input;
it->second.compressed=result;
}
return result;
}
Memory_Cache::map_iterator_t Memory_Cache::fetch( string const &key)
{
map_iterator_t it=data.find(key);
if(it==data.end()) {
return it;
}
Mutex L(&lru_lock);
lru.erase(it->second.lru_ptr);
lru.push_front(it);
return it;
}
bool Memory_Cache::fetch_string(string const &key,string &output)
{
Read_Lock L(&lock);
map_iterator_t it=fetch(key);
if(it!=data.end()) {
output=it->second.text;
return true;
}
return false;
}
bool Memory_Cache::fetch_gzip(string const &key,string &output)
{
Read_Lock L(&lock);
map_iterator_t it=fetch(key);
if(it!=data.end()) {
output=it->second.compressed;
return true;
}
return false;
}
void Memory_Cache::drop( string const &key)
{
Write_Lock L(&lock);
map_iterator_t it=data.find(key);
if(it!=data.end()){
lru.erase(it->second.lru_ptr);
data.erase(it);
}
}
void Memory_Cache::drop_prefix( string const &prefix)
{
Write_Lock L(&lock);
map_iterator_t it=data.find(prefix);
while(it!=data.end() && it->first.find(prefix)==0){
lru.erase(it->second.lru_ptr);
map_iterator_t tmp=it;
it++;
data.erase(tmp);
}
}
string Base_Cache::deflate(string const &text)
{
using namespace boost::iostreams;
ostringstream sstream;
filtering_ostream zstream;
zstream.push(gzip_compressor());
zstream.push(sstream);
zstream << text;
zstream.pop();
return sstream.str();
}
MongoDB Logo MongoDB