835c6c | 2001-06-17 | Martin Nilsson | |
|
bfb3d6 | 2001-07-20 | Martin Stjernholm | |
|
aa5a89 | 2000-03-07 | Martin Nilsson | |
#pragma strict_types
|
a56589 | 1999-12-27 | Martin Nilsson | |
|
b796b5 | 1998-11-18 | Per Hedbor | | #include <roxen.h>
|
b1fca0 | 1996-11-12 | Per Hedbor | | #include <config.h>
|
cfb98d | 2000-04-30 | Martin Nilsson | |
#define ENTRY_SIZE 4
|
b1fca0 | 1996-11-12 | Per Hedbor | | #define TIMESTAMP 0
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #define DATA 1
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
33e325 | 1998-05-07 | Johan Schön | | #define TIMEOUT 2
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
b1be43 | 2000-02-15 | Martin Nilsson | | #define SIZE 3
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
14ccc6 | 1999-12-28 | Martin Nilsson | | #undef CACHE_WERR
|
a56589 | 1999-12-27 | Martin Nilsson | | #ifdef CACHE_DEBUG
|
9b4402 | 2001-03-11 | Martin Nilsson | | # define CACHE_WERR(X) report_debug("CACHE: "+X+"\n");
|
a56589 | 1999-12-27 | Martin Nilsson | | #else
# define CACHE_WERR(X)
#endif
|
f7a34a | 1998-06-24 | Johan Schön | |
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | #undef MORE_CACHE_WERR
#ifdef MORE_CACHE_DEBUG
|
9b4402 | 2001-03-11 | Martin Nilsson | | # define MORE_CACHE_WERR(X) report_debug("CACHE: "+X+"\n");
|
b1be43 | 2000-02-15 | Martin Nilsson | | #else
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | # define MORE_CACHE_WERR(X)
|
b1be43 | 2000-02-15 | Martin Nilsson | | #endif
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
1e857b | 2000-08-01 | Martin Nilsson | | static mapping(string:mapping(string:array)) cache;
static mapping(string:int) hits=([]), all=([]);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
bfb3d6 | 2001-07-20 | Martin Stjernholm | | void flush_memory_cache (void|string in) {
if (in) {
m_delete (cache, in);
m_delete (hits, in);
m_delete (all, in);
}
else {
cache=([]);
hits=([]);
all=([]);
}
|
49f924 | 2000-05-15 | Martin Nilsson | | }
|
fc7d5a | 2001-07-03 | Martin Nilsson | | constant svalsize = 4*4;
|
0281ea | 2000-03-07 | Martin Nilsson | |
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
f6d62d | 1997-03-26 | Per Hedbor | | void cache_expire(string in)
{
|
49f924 | 2000-05-15 | Martin Nilsson | | CACHE_WERR(sprintf("cache_expire(\"%s\")", in));
|
f6d62d | 1997-03-26 | Per Hedbor | | m_delete(cache, in);
}
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | mixed cache_lookup(string in, string what)
{
|
a56589 | 1999-12-27 | Martin Nilsson | | CACHE_WERR(sprintf("cache_lookup(\"%s\",\"%s\") -> ", in, what));
|
b1fca0 | 1996-11-12 | Per Hedbor | | all[in]++;
|
9a002e | 2000-04-19 | Martin Nilsson | | int t=time(1);
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
1b41df | 2000-04-18 | Martin Nilsson | | if(array entry = (cache[in] && cache[in][what]) )
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
1b41df | 2000-04-18 | Martin Nilsson | | if (entry[TIMEOUT] && entry[TIMEOUT] < t) {
|
249ed1 | 2000-01-06 | Martin Stjernholm | | m_delete (cache[in], what);
|
1b41df | 2000-04-18 | Martin Nilsson | | CACHE_WERR("Timed out");
|
249ed1 | 2000-01-06 | Martin Stjernholm | | }
else {
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
1b41df | 2000-04-18 | Martin Nilsson | | cache[in][what][TIMESTAMP]=t;
|
249ed1 | 2000-01-06 | Martin Stjernholm | | CACHE_WERR("Hit");
hits[in]++;
return entry[DATA];
}
else CACHE_WERR("Miss");
return ([])[0];
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
471c29 | 2000-09-04 | Jonas Wallden | |
array(string) cache_indices(string|void in)
{
if (in)
return (cache[in] && indices(cache[in])) || ({ });
else
return indices(cache);
}
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
1e857b | 2000-08-01 | Martin Nilsson | | mapping(string:array(int)) status()
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
a8228b | 2000-08-14 | Jonas Wallden | | mapping(string:array(int)) ret = ([ ]);
foreach(indices(cache), string name) {
string show_name = (name / ":")[0];
|
b7d890 | 2000-08-14 | Jonas Wallden | | array(int) entry = ({ sizeof(cache[name]),
hits[name],
all[name],
|
fc7d5a | 2001-07-03 | Martin Nilsson | | sizeof(encode_value(cache[name])) });
|
a8228b | 2000-08-14 | Jonas Wallden | | if (!zero_type(ret[show_name]))
for (int idx = 0; idx < 3; idx++)
ret[show_name][idx] += entry[idx];
else
ret[show_name] = entry;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
1e857b | 2000-08-01 | Martin Nilsson | | return ret;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | void cache_remove(string in, string what)
{
|
a56589 | 1999-12-27 | Martin Nilsson | | CACHE_WERR(sprintf("cache_remove(\"%s\",\"%O\")", in, what));
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!what)
m_delete(cache, in);
else
|
a56589 | 1999-12-27 | Martin Nilsson | | if(cache[in])
|
b1fca0 | 1996-11-12 | Per Hedbor | | m_delete(cache[in], what);
}
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
f7a34a | 1998-06-24 | Johan Schön | | mixed cache_set(string in, string what, mixed to, int|void tm)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | #if MORE_CACHE_DEBUG
|
7bcd14 | 2000-02-12 | Martin Nilsson | | CACHE_WERR(sprintf("cache_set(\"%s\", \"%s\", %O)\n",
in, what, to));
#else
CACHE_WERR(sprintf("cache_set(\"%s\", \"%s\", %t)\n",
|
a56589 | 1999-12-27 | Martin Nilsson | | in, what, to));
|
7bcd14 | 2000-02-12 | Martin Nilsson | | #endif
|
9a002e | 2000-04-19 | Martin Nilsson | | int t=time(1);
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!cache[in])
cache[in]=([ ]);
cache[in][what] = allocate(ENTRY_SIZE);
cache[in][what][DATA] = to;
|
1b41df | 2000-04-18 | Martin Nilsson | | if(tm) cache[in][what][TIMEOUT] = t + tm;
cache[in][what][TIMESTAMP] = t;
|
f7a34a | 1998-06-24 | Johan Schön | | return to;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
cfb98d | 2000-04-30 | Martin Nilsson | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | void cache_clean()
{
|
460da4 | 1997-10-30 | Per Hedbor | | remove_call_out(cache_clean);
|
ea9a4b | 2001-01-10 | Per Hedbor | | int gc_time=[int](([function(string:mixed)]roxenp()->query)("mem_cache_gc"));
|
b1fca0 | 1996-11-12 | Per Hedbor | | string a, b;
|
349263 | 2000-02-08 | Martin Nilsson | | array c;
|
9a002e | 2000-04-19 | Martin Nilsson | | int t=time(1);
|
a56589 | 1999-12-27 | Martin Nilsson | | CACHE_WERR("cache_clean()");
|
b1fca0 | 1996-11-12 | Per Hedbor | | foreach(indices(cache), a)
{
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" Class " + a);
|
b1fca0 | 1996-11-12 | Per Hedbor | | foreach(indices(cache[a]), b)
{
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" " + b + " ");
|
349263 | 2000-02-08 | Martin Nilsson | | c = cache[a][b];
|
ba73a2 | 1996-12-10 | Per Hedbor | | #ifdef DEBUG
|
349263 | 2000-02-08 | Martin Nilsson | | if(!intp(c[TIMESTAMP]))
|
b1be43 | 2000-02-15 | Martin Nilsson | | error(" Illegal timestamp in cache ("+a+":"+b+")\n");
|
ba73a2 | 1996-12-10 | Per Hedbor | | #endif
|
7bcd14 | 2000-02-12 | Martin Nilsson | | if(c[TIMEOUT] && c[TIMEOUT] < t) {
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" DELETED (explicit timeout)");
|
b1fca0 | 1996-11-12 | Per Hedbor | | m_delete(cache[a], b);
}
|
b1be43 | 2000-02-15 | Martin Nilsson | | else {
if(!c[SIZE]) {
|
fc7d5a | 2001-07-03 | Martin Nilsson | | c[SIZE]=(sizeof(encode_value(b)) + sizeof(encode_value(c[DATA])) +
5*svalsize + 4)/100;
|
b1be43 | 2000-02-15 | Martin Nilsson | |
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" Cache entry size percieved as " +
([int]c[SIZE]*100) + " bytes\n");
|
b1be43 | 2000-02-15 | Martin Nilsson | | }
|
bfac9d | 2000-02-17 | Martin Nilsson | | if(c[TIMESTAMP]+1 < t && c[TIMESTAMP] + gc_time -
|
b1be43 | 2000-02-15 | Martin Nilsson | | c[SIZE] < t)
{
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" DELETED");
|
b1be43 | 2000-02-15 | Martin Nilsson | | m_delete(cache[a], b);
}
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | #ifdef MORE_CACHE_DEBUG
|
b1be43 | 2000-02-15 | Martin Nilsson | | else
CACHE_WERR("Ok");
|
32aa83 | 2000-02-02 | Per Hedbor | | #endif
|
b1be43 | 2000-02-15 | Martin Nilsson | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!sizeof(cache[a]))
{
|
b9fbf7 | 2001-01-04 | Martin Nilsson | | MORE_CACHE_WERR(" Class DELETED.");
|
b1fca0 | 1996-11-12 | Per Hedbor | | m_delete(cache, a);
}
}
}
|
4d3bfb | 2000-02-18 | Martin Nilsson | | call_out(cache_clean, gc_time);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
b3a87b | 2001-01-21 | Martin Nilsson | |
|
69c041 | 2001-03-19 | Martin Nilsson | |
private mapping(string:mapping(string:mixed)) nongc_cache;
void nongarbing_cache_set(string cache_id, string key, mixed value) {
|
38a256 | 2001-04-19 | Jonas Wallden | | if(nongc_cache[cache_id])
nongc_cache[cache_id][key] = value;
else
nongc_cache[cache_id] = ([ key:value ]);
|
69c041 | 2001-03-19 | Martin Nilsson | | }
mixed nongarbing_cache_lookup(string cache_id, string key) {
return nongc_cache[cache_id]?nongc_cache[cache_id][key]:([])[0];
}
void nongarbing_cache_remove(string cache_id, string key) {
if(nongc_cache[cache_id]) m_delete(nongc_cache[cache_id], key);
}
void nongarbing_cache_flush(string cache_id) {
m_delete(nongc_cache, cache_id);
}
|
fc7d5a | 2001-07-03 | Martin Nilsson | | mapping(string:array(int)) ngc_status() {
mapping(string:array(int)) res = ([]);
foreach(indices(nongc_cache), string cache)
res[cache] = ({ sizeof(nongc_cache[cache]),
sizeof(encode_value(nongc_cache[cache])) });
return res;
}
|
69c041 | 2001-03-19 | Martin Nilsson | |
|
b3a87b | 2001-01-21 | Martin Nilsson | |
#ifndef SESSION_BUCKETS
# define SESSION_BUCKETS 4
#endif
#ifndef SESSION_SHIFT_TIME
|
d82ce4 | 2001-04-23 | Martin Nilsson | | # define SESSION_SHIFT_TIME 15*60
|
b3a87b | 2001-01-21 | Martin Nilsson | | #endif
|
9b4402 | 2001-03-11 | Martin Nilsson | |
|
296af9 | 2001-02-04 | Martin Nilsson | | private mapping(string:int) session_persistence;
|
9b4402 | 2001-03-11 | Martin Nilsson | |
|
b3a87b | 2001-01-21 | Martin Nilsson | | private array(mapping(string:mixed)) session_buckets;
|
9b4402 | 2001-03-11 | Martin Nilsson | |
private Sql.Sql db;
private int max_persistence;
|
b3a87b | 2001-01-21 | Martin Nilsson | |
|
9b4402 | 2001-03-11 | Martin Nilsson | |
private void store_session(string id, mixed data, int t) {
data = encode_value(data);
if(catch(db->query("INSERT INTO session_cache VALUES (%s," +
t + ",%s)", id, data)))
db->query("UPDATE session_cache SET data=%s, persistence=" +
t + " WHERE id=%s", data, id);
}
|
b3a87b | 2001-01-21 | Martin Nilsson | | private void session_cache_handler() {
remove_call_out(session_cache_handler);
|
296af9 | 2001-02-04 | Martin Nilsson | | int t=time(1);
|
9b4402 | 2001-03-11 | Martin Nilsson | | if(max_persistence>t) {
clean:
foreach(indices(session_buckets[-1]), string id) {
if(session_persistence[id]<t) {
m_delete(session_buckets[-1], id);
m_delete(session_persistence, id);
continue;
}
for(int i; i<SESSION_BUCKETS-2; i++)
if(session_buckets[i][id]) {
continue clean;
}
if(objectp(session_buckets[-1][id])) {
m_delete(session_buckets[-1], id);
m_delete(session_persistence, id);
continue;
}
store_session(id, session_buckets[-1][id], session_persistence[id]);
|
296af9 | 2001-02-04 | Martin Nilsson | | m_delete(session_buckets[-1], id);
m_delete(session_persistence, id);
}
}
|
9b4402 | 2001-03-11 | Martin Nilsson | |
|
296af9 | 2001-02-04 | Martin Nilsson | | session_buckets = ({ ([]) }) + session_buckets[..SESSION_BUCKETS-2];
|
b3a87b | 2001-01-21 | Martin Nilsson | | call_out(session_cache_handler, SESSION_SHIFT_TIME);
}
|
9b4402 | 2001-03-11 | Martin Nilsson | |
private void session_cache_destruct() {
remove_call_out(session_cache_handler);
int t=time(1);
if(max_persistence>t) {
report_notice("Synchronizing session cache");
foreach(session_buckets, mapping(string:mixed) session_bucket)
foreach(indices(session_bucket), string id)
if(session_persistence[id]>t) {
store_session(id, session_bucket[id], session_persistence[id]);
m_delete(session_persistence, id);
}
}
report_notice("Session cache synchronized\n");
}
|
14151c | 2001-04-21 | Martin Nilsson | |
void clear_session(string id) {
m_delete(session_persistence, id);
foreach(session_buckets, mapping bucket)
m_delete(bucket, id);
db->query("DELETE FROM session_cache WHERE id=%s", id);
}
|
9b4402 | 2001-03-11 | Martin Nilsson | |
|
b3a87b | 2001-01-21 | Martin Nilsson | | mixed get_session_data(string id) {
mixed data;
foreach(session_buckets, mapping bucket)
if(data=bucket[id]) {
session_buckets[0][id] = data;
return data;
}
|
9b4402 | 2001-03-11 | Martin Nilsson | | data = db->query("SELECT data FROM session_cache WHERE id=%s", id);
if(sizeof([array]data) &&
!catch(data=decode_value( ([array(mapping(string:string))]data)[0]->data )))
return data;
|
b3a87b | 2001-01-21 | Martin Nilsson | | return ([])[0];
}
|
9b4402 | 2001-03-11 | Martin Nilsson | |
string set_session_data(mixed data, void|string id, void|int persistence,
void|int(0..1) store) {
|
b3a87b | 2001-01-21 | Martin Nilsson | | if(!id) id = ([function(void:string)]roxenp()->create_unique_id)();
|
296af9 | 2001-02-04 | Martin Nilsson | | session_persistence[id] = persistence;
|
b3a87b | 2001-01-21 | Martin Nilsson | | session_buckets[0][id] = data;
|
9b4402 | 2001-03-11 | Martin Nilsson | | max_persistence = max(max_persistence, persistence);
if(store && persistence) store_session(id, data, persistence);
|
b3a87b | 2001-01-21 | Martin Nilsson | | return id;
}
|
9b4402 | 2001-03-11 | Martin Nilsson | |
private void setup_tables() {
if(catch(db->query("select id from session_cache where id=''"))) {
db->query("CREATE TABLE session_cache ("
"id CHAR(32) NOT NULL PRIMARY KEY, "
"persistence INT UNSIGNED NOT NULL DEFAULT 0, "
"data BLOB NOT NULL)");
}
}
void init_session_cache() {
|
390993 | 2001-04-09 | Per Hedbor | | db = (([function(string:function(string:object(Sql.Sql)))]master()->resolv)
("DBManager.get"))("local");
|
9b4402 | 2001-03-11 | Martin Nilsson | | if( !db )
|
60d562 | 2001-05-18 | Martin Nilsson | | report_fatal("No 'local' database!\n");
else
setup_tables();
|
9b4402 | 2001-03-11 | Martin Nilsson | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | void create()
{
|
1847a2 | 1999-09-06 | Per Hedbor | | add_constant( "cache", this_object() );
|
5b4a54 | 2001-02-08 | Martin Nilsson | | cache = ([ ]);
|
bfac9d | 2000-02-17 | Martin Nilsson | | call_out(cache_clean, 60);
|
5b4a54 | 2001-02-08 | Martin Nilsson | |
|
69c041 | 2001-03-19 | Martin Nilsson | | nongc_cache = ([ ]);
|
5b4a54 | 2001-02-08 | Martin Nilsson | | session_buckets = ({ ([]) }) * SESSION_BUCKETS;
session_persistence = ([]);
|
b3a87b | 2001-01-21 | Martin Nilsson | | call_out(session_cache_handler, SESSION_SHIFT_TIME);
|
5b4a54 | 2001-02-08 | Martin Nilsson | |
|
b1be43 | 2000-02-15 | Martin Nilsson | | CACHE_WERR("Now online.");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
9b4402 | 2001-03-11 | Martin Nilsson | |
void destroy() {
session_cache_destruct();
return;
}
|