Roxen.git / server / base_server / configuration.pike

version» Context lines:

Roxen.git/server/base_server/configuration.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2004, Roxen IS.   //      // @appears Configuration   //! A site's main configuration    - constant cvs_version = "$Id: configuration.pike,v 1.666 2009/01/29 20:48:08 marty Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.667 2009/02/24 16:48:43 mast Exp $";   #include <module.h>   #include <module_constants.h>   #include <roxen.h>   #include <request_trace.h>   #include <timers.h>      #define CATCH(P,X) do{mixed e;if(e=catch{X;})report_error("While "+P+"\n"+describe_backtrace(e));}while(0)      // Tell Pike.count_memory this is global.   constant pike_cycle_depth = 0;
Roxen.git/server/base_server/configuration.pike:229:    int hits, misses;       void flush()    {   #ifndef RAM_CACHE_NO_RELOAD_FLUSH    current_size = 0;    cache = ([]);   #endif    }    +  // Heuristic to calculate the entry size. Besides the data itself, +  // we add the size of the key. Even though it's a shared string we +  // can pretty much assume it has no other permanent refs. 128 is a +  // constant penalty that accounts for the keypair in the mapping and +  // that leaf entries are stored in arrays. + #define CALC_ENTRY_SIZE(key, data) (sizeof (data) + sizeof (key) + 128) +     // Expire a single entry.    protected void really_low_expire_entry(string key)    {    EntryType e = m_delete(cache, key);    if (arrayp(e)) { -  current_size -= sizeof(e[0]); +  current_size -= CALC_ENTRY_SIZE (key, e[0]);    if (e[1]->co_handle) {    remove_call_out(e[1]->co_handle);    }    }    }       // NOTE: Avoid using this function if possible! O(n)    protected int low_expire_entry(string key_prefix)    {    if (!key_prefix) return 0;
Roxen.git/server/base_server/configuration.pike:273:    {    if (!id) {    low_expire_entry(key_prefix);    return;    }    string url = key_prefix;    sscanf(url, "%[^\0]", url);    while(1) {    EntryType val;    if (arrayp(val = cache[key_prefix])) { -  current_size -= sizeof(val[0]); +  current_size -= CALC_ENTRY_SIZE (key_prefix, val[0]);    m_delete(cache, key_prefix);    return;    }    if (!val) {    return;    }       string|array(string) key_frag;    if (stringp(val)) {    key_frag = id->request_headers[val];
Roxen.git/server/base_server/configuration.pike:298:    // Avoid spoofing if key_frag happens to contain "\0\0".    key_frag = replace (key_frag, "\0", "\0\1");    else key_frag = "";    key_prefix += "\0\0" + key_frag;    }    }       //! Clear ~1/10th of the cache.    protected void clear_some_cache()    { +  // FIXME: Use an iterator to avoid indices() here.    array(string) q = indices(cache);    if(!sizeof(q))    {    current_size=0;    return;    }       // The following code should be ~O(n * log(n)).    sort(q);    for(int i = 0; i < sizeof(q)/10; i++) {
Roxen.git/server/base_server/configuration.pike:322:    if (!q[r]) continue;    if (!has_prefix(q[r], key_prefix)) break;    really_low_expire_entry(q[r]);    q[r] = 0;    }    }    }       void set(string url, string data, mapping meta, int expire, RequestID id)    { -  if( strlen( data ) > max_file_size ) { +  int entry_size = CALC_ENTRY_SIZE (url, data); +  +  if( entry_size > max_file_size ) {    // NOTE: There's a possibility of a stale entry remaining in the    // cache until it expires, rather than being replaced here.    SIMPLE_TRACE_ENTER (this, "Result of size %d is too large "    "to store in the protocol cache (limit %d)", -  sizeof (data), max_file_size); +  entry_size, max_file_size);    SIMPLE_TRACE_LEAVE ("");    return;    }       SIMPLE_TRACE_ENTER (this, "Storing result of size %d in the protocol cache "    "using key %O (expire in %ds)", -  sizeof (data), url, expire); +  entry_size, url, expire);    string key = url;       foreach(id->misc->vary_cb_order || ({}),    string|function(string, RequestID: string|int) vary_cb) {    array(string|mapping(string:mixed))|string|    function(string, RequestID:string|int) old = cache[key];    if (old && (old != vary_cb)) {    SIMPLE_TRACE_ENTER (this, "Registering vary cb %O - conflicts with "    "existing entry %s, old entry expired",    vary_cb,
Roxen.git/server/base_server/configuration.pike:390:    if (old) {    SIMPLE_TRACE_LEAVE ("Entry conflicts with existing entry %s, "    "old entry expired",    (arrayp (old) ? "of size " + sizeof (old[0]) :    sprintf ("%O", old)));    low_expire_entry(key);    }    else    SIMPLE_TRACE_LEAVE ("");    -  current_size += strlen( data ); +  current_size += entry_size;    cache[key] = ({ data, meta });       // Only the actual cache entry is expired.    // FIXME: This could lead to lots and lots of call outs.. :P    meta->co_handle = call_out(really_low_expire_entry, expire, key);    int n;    while( (current_size > max_size) && (n++<10))    clear_some_cache();    }