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 - 2009, Roxen IS.   //      // @appears Configuration   //! A site's main configuration    - constant cvs_version = "$Id: configuration.pike,v 1.713 2011/02/18 09:58:12 wellhard Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.714 2012/10/14 15:43:05 wellhard 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:231:    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 +  // can pretty much assume it has no other permanent refs. 1024 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) +  // that leaf entries are stored in arrays and the metadata mapping. + #define CALC_ENTRY_SIZE(key, data) (sizeof (data) + sizeof (key) + 1024) + #define CALC_VARY_CB_SIZE(key) (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 -= CALC_ENTRY_SIZE (key, e[0]);    if (e[1]->co_handle) {    remove_call_out(e[1]->co_handle);    }    if (CacheKey cachekey = e[1]->key) {    destruct (cachekey);    } -  +  } else if (!zero_type(e)) { +  current_size -= CALC_VARY_CB_SIZE(key);    }    }       // NOTE: Avoid using this function if possible! O(n)    protected int low_expire_entry(string key_prefix)    {    if (!key_prefix) return 0;    if (arrayp(cache[key_prefix])) {    // Leaf node. No need to loop.    really_low_expire_entry(key_prefix);
Roxen.git/server/base_server/configuration.pike:286:    return;    }    string url = key_prefix;    sscanf(url, "%[^\0]", url);    while(1) {    EntryType val;    if (arrayp(val = cache[key_prefix])) {    current_size -= CALC_ENTRY_SIZE (key_prefix, val[0]);    m_delete(cache, key_prefix);    return; +  } else if (!zero_type(val)) { +  current_size -= CALC_VARY_CB_SIZE(key_prefix);    }    if (!val) {    return;    }       string|array(string) key_frag;    if (stringp(val)) {    key_frag = id->request_headers[val];    } else {    key_frag = val(url, id);    }    if (key_frag)    // 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() +  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++) { +  for(int i = 0; i < sizeof(q)/10 + 1; i++) {    int r = random(sizeof(q));    string key_prefix = q[r = random(sizeof(q))];    if (!key_prefix) continue;    for(;r < sizeof(q); r++,i++) {    if (!q[r]) continue;    if (!has_prefix(q[r], key_prefix)) break;    really_low_expire_entry(q[r]);    q[r] = 0;    }    }
Roxen.git/server/base_server/configuration.pike:361:    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,    (arrayp (old) ? "of size " + sizeof (old[0]) :    sprintf ("%O", old)));    low_expire_entry(key); +  old = UNDEFINED; // Ensure that current size is updated below.    SIMPLE_TRACE_LEAVE ("");    }    cache[key] = vary_cb; -  +  if(!old) { +  current_size += CALC_VARY_CB_SIZE(key); +  }       SIMPLE_TRACE_ENTER (this, "Registering vary cb %O", vary_cb);       string key_frag;    if (stringp(vary_cb)) {    string|array(string) header = id->request_headers[vary_cb];    if (arrayp(header)) key_frag = header * ",";    else key_frag = header;    } else {    int|string frag = vary_cb(url, id);
Roxen.git/server/base_server/configuration.pike:389:    }       SIMPLE_TRACE_LEAVE ("Vary cb resolved to key fragment %O",    key_frag || "");       if (key_frag)    // Avoid spoofing if key_frag happens to contain "\0\0".    key_frag = replace (key_frag, "\0", "\0\1");    else key_frag = "";    key += "\0\0" + key_frag; +  entry_size += 2 + sizeof(key_frag);    }       array(string|mapping(string:mixed))|string|    function(string, RequestID:string) old = cache[key];    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);