Menu

[r2191]: / framework / trunk / src / session_memory_storage.cpp  Maximize  Restore  History

Download this file

134 lines (113 with data), 3.0 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 "session_memory_storage.h"
#include <cppcms/config.h>
#include "hash_map.h"
#include <booster/thread.h>
#include <time.h>
#include <map>
namespace cppcms {
namespace sessions {
class session_memory_storage : public session_storage {
struct _data;
typedef cppcms::impl::hash_map<
std::string,
_data,
cppcms::impl::string_hash
> map_type;
typedef map_type::iterator pointer;
typedef std::multimap<time_t,pointer> timeout_type;
struct _data {
time_t timeout;
std::string info;
timeout_type::iterator timeout_ptr;
};
map_type map_;
timeout_type timeout_;
booster::shared_mutex mutex_;
public:
void save(std::string const &key,time_t to,std::string const &value)
{
booster::unique_lock<booster::shared_mutex> lock(mutex_);
pointer p=map_.find(key);
if(p==map_.end()) {
std::pair<pointer,bool> pr = map_.insert(std::pair<std::string,_data>(key,_data()));
pointer p = pr.first;
p->second.timeout=to;
p->second.info=value;
p->second.timeout_ptr=timeout_.insert(std::pair<time_t,pointer>(to,p));
}
else {
timeout_.erase(p->second.timeout_ptr);
p->second.timeout=to;
p->second.info=value;
p->second.timeout_ptr=timeout_.insert(std::pair<time_t,pointer>(to,p));
}
short_gc();
}
void short_gc()
{
time_t now=::time(0);
timeout_type::iterator p=timeout_.begin(),tmp;
int count = 0;
while(p!=timeout_.end() && p->first < now && count < 5) {
tmp=p;
++p;
map_.erase(tmp->second);
timeout_.erase(tmp);
count++;
}
}
bool load(std::string const &key,time_t &to,std::string &value)
{
booster::shared_lock<booster::shared_mutex> lock(mutex_);
map_type::iterator p=map_.find(key);
if(p==map_.end())
return false;
if(p->second.timeout < ::time(0))
return false;
value=p->second.info;
to=p->second.timeout;
return true;
}
void remove(std::string const &key)
{
booster::unique_lock<booster::shared_mutex> lock(mutex_);
pointer p=map_.find(key);
if(p==map_.end())
return;
timeout_.erase(p->second.timeout_ptr);
map_.erase(p);
short_gc();
}
bool is_blocking()
{
return false;
}
};
session_memory_storage_factory::session_memory_storage_factory() :
storage_(new session_memory_storage())
{
}
session_memory_storage_factory::~session_memory_storage_factory()
{
}
booster::shared_ptr<session_storage> session_memory_storage_factory::get()
{
return storage_;
}
bool session_memory_storage_factory::requires_gc()
{
return false;
}
void session_memory_storage_factory::gc_job()
{
}
} // sessions
} // cppcms
MongoDB Logo MongoDB