Changeset 114 for trunk/xcache.c


Ignore:
Timestamp:
2006-08-30T02:31:03+02:00 (8 years ago)
Author:
moo
Message:

gc expired items, new ini: xcache.ttl xcache.gc_interval xcache.var_ttl xcache.var_maxttl xcache.var_gc_interval

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/xcache.c

    r113 r114  
    3939#include <assert.h> 
    4040 
     41#define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > pentry->ctime + (pentry)->ttl) 
    4142#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0) 
    4243#define LOCK(x) xc_lock(x->lck) 
     
    6566static xc_hash_t xc_var_hentry = {0}; 
    6667 
     68static zend_ulong xc_php_ttl    = 0; 
     69static zend_ulong xc_var_maxttl = 0; 
     70 
     71enum { xc_deletes_gc_interval = 120 }; 
     72static zend_ulong xc_php_gc_interval = 0; 
     73static zend_ulong xc_var_gc_interval = 0; 
     74 
    6775/* total size */ 
    6876static zend_ulong xc_php_size  = 0; 
     
    162170} 
    163171/* }}} */ 
     172static void xc_entry_remove_real_dmz(xc_entry_t *xce, xc_entry_t **pp TSRMLS_DC) /* {{{ */ 
     173{ 
     174    *pp = xce->next; 
     175    xce->cache->entries_count --; 
     176    if (xce->refcount == 0) { 
     177        xc_entry_free_dmz(xce); 
     178    } 
     179    else { 
     180        xce->next = xce->cache->deletes; 
     181        xce->cache->deletes = xce; 
     182        xce->dtime = XG(request_time); 
     183        xce->cache->deletes_count ++; 
     184    } 
     185    return; 
     186} 
     187/* }}} */ 
    164188static void xc_entry_remove_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */ 
    165189{ 
    166     xc_entry_t **last = &(xce->cache->entries[xce->hvalue]); 
     190    xc_entry_t **pp = &(xce->cache->entries[xce->hvalue]); 
    167191    xc_entry_t *p; 
    168     for (p = *last; p; last = &(p->next), p = p->next) { 
     192    for (p = *pp; p; pp = &(p->next), p = p->next) { 
    169193        if (xc_entry_equal_dmz(xce, p)) { 
    170             *last = p->next; 
    171             xce->cache->entries_count ++; 
    172             if (p->refcount == 0) { 
    173                 xc_entry_free_dmz(p); 
    174             } 
    175             else { 
    176                 p->next = p->cache->deletes; 
    177                 p->cache->deletes = p; 
    178                 p->dtime = XG(request_time); 
    179                 xce->cache->deletes_count ++; 
    180             } 
     194            xc_entry_remove_real_dmz(xce, pp TSRMLS_CC); 
    181195            return; 
    182196        } 
     
    219233#endif 
    220234 
     235/* helper function that loop through each entry */ 
     236#define XC_ENTRY_APPLY_FUNC(name) int name(xc_entry_t *entry TSRMLS_DC) 
     237typedef XC_ENTRY_APPLY_FUNC((*cache_apply_dmz_func_t)); 
     238static void xc_entry_apply_dmz(xc_cache_t *cache, cache_apply_dmz_func_t apply_func TSRMLS_DC) /* {{{ */ 
     239{ 
     240    xc_entry_t *p, **pp; 
     241    int i, c; 
     242 
     243    for (i = 0, c = cache->hentry->size; i < c; i ++) { 
     244        pp = &(cache->entries[i]); 
     245        for (p = *pp; p; p = p->next) { 
     246            if (apply_func(p TSRMLS_CC)) { 
     247                xc_entry_remove_real_dmz(p, pp TSRMLS_CC); 
     248            } 
     249            else { 
     250                pp = &(p->next); 
     251            } 
     252        } 
     253    } 
     254} 
     255/* }}} */ 
     256 
     257#define XC_CACHE_APPLY_FUNC(name) void name(xc_cache_t *cache TSRMLS_DC) 
     258/* call graph: 
     259 * xc_php_gc_expires -> xc_gc_expires_var_one -> xc_entry_apply_dmz -> xc_gc_php_entry_expires_dmz 
     260 * xc_var_gc_expires -> xc_gc_expires_one -> xc_entry_apply_dmz -> xc_gc_var_entry_expires_dmz 
     261 */ 
     262static XC_ENTRY_APPLY_FUNC(xc_gc_php_entry_expires_dmz) /* {{{ */ 
     263{ 
     264    fprintf(stderr, "ttl %d, %d %d\n", XG(request_time), entry->atime, xc_php_ttl); 
     265    if (XG(request_time) > entry->atime + xc_php_ttl) { 
     266        return 1; 
     267    } 
     268    return 0; 
     269} 
     270/* }}} */ 
     271static XC_ENTRY_APPLY_FUNC(xc_gc_var_entry_expires_dmz) /* {{{ */ 
     272{ 
     273    if (VAR_ENTRY_EXPIRED(entry)) { 
     274        return 1; 
     275    } 
     276    return 0; 
     277} 
     278/* }}} */ 
     279static void xc_gc_expires_one(xc_cache_t *cache, zend_ulong gc_interval, cache_apply_dmz_func_t apply_func TSRMLS_DC) /* {{{ */ 
     280{ 
     281    fprintf(stderr, "interval %d, %d %d\n", XG(request_time), cache->last_gc_expires, gc_interval); 
     282    if (XG(request_time) - cache->last_gc_expires > gc_interval) { 
     283        ENTER_LOCK(cache) { 
     284            if (XG(request_time) - cache->last_gc_expires > gc_interval) { 
     285                cache->last_gc_expires = XG(request_time); 
     286                xc_entry_apply_dmz(cache, apply_func TSRMLS_CC); 
     287            } 
     288        } LEAVE_LOCK(cache); 
     289    } 
     290} 
     291/* }}} */ 
     292static void xc_php_gc_expires(TSRMLS_D) /* {{{ */ 
     293{ 
     294    int i, c; 
     295 
     296    if (!xc_php_ttl || !xc_php_gc_interval) { 
     297        return; 
     298    } 
     299 
     300    for (i = 0, c = xc_php_hcache.size; i < c; i ++) { 
     301        xc_gc_expires_one(xc_php_caches[i], xc_php_gc_interval, xc_gc_php_entry_expires_dmz TSRMLS_CC); 
     302    } 
     303} 
     304/* }}} */ 
     305static void xc_var_gc_expires(TSRMLS_D) /* {{{ */ 
     306{ 
     307    int i, c; 
     308 
     309    if (!xc_var_gc_interval) { 
     310        return; 
     311    } 
     312 
     313    for (i = 0, c = xc_var_hcache.size; i < c; i ++) { 
     314        xc_gc_expires_one(xc_var_caches[i], xc_var_gc_interval, xc_gc_var_entry_expires_dmz TSRMLS_CC); 
     315    } 
     316} 
     317/* }}} */ 
     318 
     319static XC_CACHE_APPLY_FUNC(xc_gc_delete_dmz) /* {{{ */ 
     320{ 
     321    xc_entry_t *p, **pp; 
     322 
     323    pp = &cache->deletes; 
     324    for (p = *pp; p; p = p->next) { 
     325        if (XG(request_time) - p->dtime > 3600) { 
     326            p->refcount = 0; 
     327            /* issue warning here */ 
     328        } 
     329        if (p->refcount == 0) { 
     330            *pp = p->next; 
     331            cache->deletes_count --; 
     332            xc_entry_free_dmz(p); 
     333        } 
     334        else { 
     335            pp = &(p->next); 
     336        } 
     337    } 
     338} 
     339/* }}} */ 
     340static XC_CACHE_APPLY_FUNC(xc_gc_deletes_one) /* {{{ */ 
     341{ 
     342    if (cache->deletes && XG(request_time) - cache->last_gc_deletes > xc_deletes_gc_interval) { 
     343        ENTER_LOCK(cache) { 
     344            if (cache->deletes && XG(request_time) - cache->last_gc_deletes > xc_deletes_gc_interval) { 
     345                xc_gc_delete_dmz(cache TSRMLS_CC); 
     346            } 
     347        } LEAVE_LOCK(cache); 
     348    } 
     349} 
     350/* }}} */ 
     351static void xc_gc_deletes(TSRMLS_D) /* {{{ */ 
     352{ 
     353    int i, c; 
     354 
     355    for (i = 0, c = xc_php_hcache.size; i < c; i ++) { 
     356        xc_gc_deletes_one(xc_php_caches[i] TSRMLS_CC); 
     357    } 
     358 
     359    for (i = 0, c = xc_var_hcache.size; i < c; i ++) { 
     360        xc_gc_deletes_one(xc_var_caches[i] TSRMLS_CC); 
     361    } 
     362} 
     363/* }}} */ 
     364 
    221365/* helper functions for user functions */ 
    222366static void xc_fillinfo_dmz(xc_cache_t *cache, zval *return_value TSRMLS_DC) /* {{{ */ 
     
    236380    add_assoc_long_ex(return_value, ZEND_STRS("ooms"),      cache->ooms); 
    237381 
    238     add_assoc_long_ex(return_value, ZEND_STRS("cached"), cache->entries_count); 
    239     add_assoc_long_ex(return_value, ZEND_STRS("deleted"), cache->deletes_count); 
     382    add_assoc_long_ex(return_value, ZEND_STRS("cached"),    cache->entries_count); 
     383    add_assoc_long_ex(return_value, ZEND_STRS("deleted"),   cache->deletes_count); 
    240384 
    241385    MAKE_STD_ZVAL(blocks); 
     
    402546} 
    403547/* }}} */ 
    404 static void xc_entry_gc_real(xc_cache_t **caches, int size TSRMLS_DC) /* {{{ */ 
    405 { 
    406     time_t t = XG(request_time); 
    407     int i; 
    408     xc_cache_t *cache; 
    409     typedef xc_entry_t *xc_delete_t; 
    410     xc_delete_t p, *last; 
    411  
    412     for (i = 0; i < size; i ++) { 
    413         cache = caches[i]; 
    414         ENTER_LOCK(cache) { 
    415             if (cache->deletes) { 
    416                 last = (xc_delete_t *) &cache->deletes; 
    417                 for (p = *last; p; p = p->next) { 
    418                     if (t - p->dtime > 3600) { 
    419                         p->refcount = 0; 
    420                         /* issue warning here */ 
    421                     } 
    422                     if (p->refcount == 0) { 
    423                         *last = p->next; 
    424                         cache->deletes_count --; 
    425                         xc_entry_free_dmz(p); 
    426                     } 
    427                     else { 
    428                         last = &(p->next); 
    429                     } 
    430                 } 
    431             } 
    432         } LEAVE_LOCK(cache); 
    433     } 
    434 } 
    435 /* }}} */ 
    436 static void xc_entry_gc(TSRMLS_D) /* {{{ */ 
    437 { 
    438     xc_entry_gc_real(xc_php_caches, xc_php_hcache.size TSRMLS_CC); 
    439     xc_entry_gc_real(xc_var_caches, xc_var_hcache.size TSRMLS_CC); 
    440 } 
    441 /* }}} */ 
     548 
    442549static inline void xc_entry_unholds_real(xc_stack_t *holds, xc_cache_t **caches, int cachecount TSRMLS_DC) /* {{{ */ 
    443550{ 
     
    781888    } 
    782889    /* }}} */ 
    783     xc_entry_gc(TSRMLS_C); 
    784890    ENTER_LOCK(cache) { /* {{{ store/add entry */ 
    785891        stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); 
     
    9871093    xc_cache_t **caches = NULL, *cache; 
    9881094    xc_mem_t *mem; 
     1095    time_t now = time(NULL); 
    9891096    int i; 
    9901097    xc_memsize_t memsize; 
     
    10171124        cache->mem     = mem; 
    10181125        cache->cacheid = i; 
     1126        cache->last_gc_deletes = now; 
     1127        cache->last_gc_expires = now; 
    10191128        caches[i] = cache; 
    10201129    } 
     
    11401249{ 
    11411250    xc_entry_unholds(TSRMLS_C); 
     1251    xc_php_gc_expires(TSRMLS_C); 
     1252    xc_var_gc_expires(TSRMLS_C); 
     1253    xc_gc_deletes(TSRMLS_C); 
    11421254#ifdef HAVE_XCACHE_COVERAGER 
    11431255    xc_coverager_request_shutdown(TSRMLS_C); 
     
    13451457                    } 
    13461458                } LEAVE_LOCK(cache); 
    1347                 xc_entry_gc(TSRMLS_C); 
     1459                xc_gc_deletes(TSRMLS_C); 
    13481460            } 
    13491461            break; 
     
    14171529} 
    14181530/* }}} */ 
    1419 #define TIME_MAX (sizeof(time_t) == sizeof(long) ? LONG_MAX : INT_MAX) 
    14201531/* {{{ proto mixed xcache_get(string name) 
    14211532   Get cached data by specified name */ 
     
    14351546        stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 
    14361547        if (stored_xce) { 
    1437             if (XG(request_time) <= stored_xce->data.var->etime) { 
     1548            if (XG(request_time) <= stored_xce->ctime + stored_xce->ttl) { 
    14381549                xc_processor_restore_zval(return_value, stored_xce->data.var->value TSRMLS_CC); 
    14391550                /* return */ 
     
    14571568    zval *name; 
    14581569    zval *value; 
    1459     long ttl = 0; 
    1460  
    1461     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &name, &value, &ttl) == FAILURE) { 
     1570 
     1571    xce.ttl = XG(var_ttl); 
     1572    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &name, &value, &xce.ttl) == FAILURE) { 
    14621573        return; 
    14631574    } 
     1575 
     1576    /* max ttl */ 
     1577    if (xc_var_maxttl && (!xce.ttl || xce.ttl > xc_var_maxttl)) { 
     1578        xce.ttl = xc_var_maxttl; 
     1579    } 
     1580 
    14641581    xce.data.var = &var; 
    14651582    xc_entry_init_key_var(&xce, name TSRMLS_CC); 
     
    14711588        } 
    14721589        var.value = value; 
    1473         var.etime = ttl ? XG(request_time) + ttl : TIME_MAX; 
    14741590        RETVAL_BOOL(xc_entry_store_dmz(&xce TSRMLS_CC) != NULL ? 1 : 0); 
    14751591    } LEAVE_LOCK(xce.cache); 
     
    14931609        stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 
    14941610        if (stored_xce) { 
    1495             if (XG(request_time) <= stored_xce->data.var->etime) { 
     1611            if (VAR_ENTRY_EXPIRED(stored_xce)) { 
    14961612                RETVAL_TRUE; 
    14971613                /* return */ 
     
    15391655    zval *name; 
    15401656    long count = 1; 
    1541     long ttl = 0; 
    15421657    long value = 0; 
    15431658    zval oldzval; 
    15441659 
    1545     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &name, &count, &ttl) == FAILURE) { 
     1660    xce.ttl = XG(var_ttl); 
     1661    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &name, &count, &xce.ttl) == FAILURE) { 
    15461662        return; 
    15471663    } 
     1664 
     1665    /* max ttl */ 
     1666    if (xc_var_maxttl && (!xce.ttl || xce.ttl > xc_var_maxttl)) { 
     1667        xce.ttl = xc_var_maxttl; 
     1668    } 
     1669 
    15481670    xce.data.var = &var; 
    15491671    xc_entry_init_key_var(&xce, name TSRMLS_CC); 
     
    15551677            fprintf(stderr, "incdec: gotxce %s\n", xce.name.str.val); 
    15561678#endif 
    1557             stored_var = stored_xce->data.var; 
    15581679            /* timeout */ 
    1559             if (XG(request_time) > stored_var->etime) { 
     1680            if (VAR_ENTRY_EXPIRED(stored_xce)) { 
    15601681#ifdef DEBUG 
    15611682                fprintf(stderr, "incdec: expired\n"); 
     
    15661687            else { 
    15671688                /* do it in place */ 
     1689                stored_var = stored_xce->data.var; 
    15681690                if (Z_TYPE_P(stored_var->value) == IS_LONG) { 
     1691                    stored_xce->ctime = XG(request_time); 
     1692                    stored_xce->ttl   = xce.ttl; 
    15691693#ifdef DEBUG 
    15701694                    fprintf(stderr, "incdec: islong\n"); 
     
    15741698                    RETVAL_LONG(value); 
    15751699                    Z_LVAL_P(stored_var->value) = value; 
    1576                     break; 
     1700                    break; /* leave lock */ 
    15771701                } 
    15781702                else { 
     
    15961720        RETVAL_LONG(value); 
    15971721        var.value = return_value; 
    1598         var.etime = ttl ? XG(request_time) + ttl : TIME_MAX; 
     1722 
    15991723        if (stored_xce) { 
    16001724            xce.atime = stored_xce->atime; 
     
    19132037} 
    19142038 
    1915 #ifdef ZEND_ENGINE_2 
    1916 #define OnUpdateInt OnUpdateLong 
     2039#ifndef ZEND_ENGINE_2 
     2040#define OnUpdateLong OnUpdateInt 
    19172041#endif 
    19182042 
     
    19322056    STD_PHP_INI_BOOLEAN("xcache.optimizer",              "0", PHP_INI_ALL,    OnUpdateBool,        optimizer,         zend_xcache_globals, xcache_globals) 
    19332057#endif 
     2058    STD_PHP_INI_BOOLEAN("xcache.var_ttl",                "0", PHP_INI_ALL,    OnUpdateLong,        var_ttl,   zend_xcache_globals, xcache_globals) 
    19342059#ifdef HAVE_XCACHE_COVERAGER 
    19352060    PHP_INI_ENTRY1     ("xcache.coveragedump_directory", "/tmp/pcov/", PHP_INI_SYSTEM, xc_OnUpdateString,   &xc_coveragedump_dir) 
     
    19922117    php_info_print_table_start(); 
    19932118    php_info_print_table_header(2, "Directive ", "Value"); 
    1994     xc_config_long_disp("xcache.size",       "0"); 
    1995     xc_config_hash_disp("xcache.count",      "1"); 
    1996     xc_config_hash_disp("xcache.slots",     "8K"); 
    1997  
    1998     xc_config_long_disp("xcache.var_size",   "0"); 
    1999     xc_config_hash_disp("xcache.var_count",  "1"); 
    2000     xc_config_hash_disp("xcache.var_slots", "8K"); 
     2119    xc_config_long_disp("xcache.size",        "0"); 
     2120    xc_config_hash_disp("xcache.count",       "1"); 
     2121    xc_config_hash_disp("xcache.slots",      "8K"); 
     2122    xc_config_hash_disp("xcache.ttl",         "0"); 
     2123    xc_config_hash_disp("xcache.gc_interval", "0"); 
     2124 
     2125    xc_config_long_disp("xcache.var_size",           "0"); 
     2126    xc_config_hash_disp("xcache.var_count",          "1"); 
     2127    xc_config_hash_disp("xcache.var_slots",         "8K"); 
     2128    xc_config_hash_disp("xcache.var_maxttl",         "0"); 
     2129    xc_config_hash_disp("xcache.var_gc_interval",  "300"); 
    20012130    php_info_print_table_end(); 
    20022131 
     
    20972226    } 
    20982227 
    2099     xc_config_long(&xc_php_size,   "xcache.size",       "0"); 
    2100     xc_config_hash(&xc_php_hcache, "xcache.count",      "1"); 
    2101     xc_config_hash(&xc_php_hentry, "xcache.slots",     "8K"); 
    2102  
    2103     xc_config_long(&xc_var_size,   "xcache.var_size",   "0"); 
    2104     xc_config_hash(&xc_var_hcache, "xcache.var_count",  "1"); 
    2105     xc_config_hash(&xc_var_hentry, "xcache.var_slots", "8K"); 
     2228    xc_config_long(&xc_php_size,       "xcache.size",        "0"); 
     2229    xc_config_hash(&xc_php_hcache,     "xcache.count",       "1"); 
     2230    xc_config_hash(&xc_php_hentry,     "xcache.slots",      "8K"); 
     2231    xc_config_long(&xc_php_ttl,        "xcache.ttl",         "0"); 
     2232    xc_config_long(&xc_php_gc_interval, "xcache.gc_interval", "0"); 
     2233 
     2234    xc_config_long(&xc_var_size,       "xcache.var_size",          "0"); 
     2235    xc_config_hash(&xc_var_hcache,     "xcache.var_count",         "1"); 
     2236    xc_config_hash(&xc_var_hentry,     "xcache.var_slots",        "8K"); 
     2237    xc_config_long(&xc_var_maxttl,     "xcache.var_maxttl",        "0"); 
     2238    xc_config_long(&xc_var_gc_interval, "xcache.var_gc_interval", "120"); 
    21062239 
    21072240    if (xc_php_size <= 0) { 
Note: See TracChangeset for help on using the changeset viewer.