Changeset 114 for trunk/xcache.c
- Timestamp:
- 2006-08-30T02:31:03+02:00 (7 years ago)
- File:
-
- 1 edited
-
trunk/xcache.c (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/xcache.c
r113 r114 39 39 #include <assert.h> 40 40 41 #define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > pentry->ctime + (pentry)->ttl) 41 42 #define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0) 42 43 #define LOCK(x) xc_lock(x->lck) … … 65 66 static xc_hash_t xc_var_hentry = {0}; 66 67 68 static zend_ulong xc_php_ttl = 0; 69 static zend_ulong xc_var_maxttl = 0; 70 71 enum { xc_deletes_gc_interval = 120 }; 72 static zend_ulong xc_php_gc_interval = 0; 73 static zend_ulong xc_var_gc_interval = 0; 74 67 75 /* total size */ 68 76 static zend_ulong xc_php_size = 0; … … 162 170 } 163 171 /* }}} */ 172 static 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 /* }}} */ 164 188 static void xc_entry_remove_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */ 165 189 { 166 xc_entry_t ** last= &(xce->cache->entries[xce->hvalue]);190 xc_entry_t **pp = &(xce->cache->entries[xce->hvalue]); 167 191 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) { 169 193 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); 181 195 return; 182 196 } … … 219 233 #endif 220 234 235 /* helper function that loop through each entry */ 236 #define XC_ENTRY_APPLY_FUNC(name) int name(xc_entry_t *entry TSRMLS_DC) 237 typedef XC_ENTRY_APPLY_FUNC((*cache_apply_dmz_func_t)); 238 static 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 */ 262 static 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 /* }}} */ 271 static 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 /* }}} */ 279 static 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 /* }}} */ 292 static 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 /* }}} */ 305 static 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 319 static 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 /* }}} */ 340 static 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 /* }}} */ 351 static 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 221 365 /* helper functions for user functions */ 222 366 static void xc_fillinfo_dmz(xc_cache_t *cache, zval *return_value TSRMLS_DC) /* {{{ */ … … 236 380 add_assoc_long_ex(return_value, ZEND_STRS("ooms"), cache->ooms); 237 381 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); 240 384 241 385 MAKE_STD_ZVAL(blocks); … … 402 546 } 403 547 /* }}} */ 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 442 549 static inline void xc_entry_unholds_real(xc_stack_t *holds, xc_cache_t **caches, int cachecount TSRMLS_DC) /* {{{ */ 443 550 { … … 781 888 } 782 889 /* }}} */ 783 xc_entry_gc(TSRMLS_C);784 890 ENTER_LOCK(cache) { /* {{{ store/add entry */ 785 891 stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); … … 987 1093 xc_cache_t **caches = NULL, *cache; 988 1094 xc_mem_t *mem; 1095 time_t now = time(NULL); 989 1096 int i; 990 1097 xc_memsize_t memsize; … … 1017 1124 cache->mem = mem; 1018 1125 cache->cacheid = i; 1126 cache->last_gc_deletes = now; 1127 cache->last_gc_expires = now; 1019 1128 caches[i] = cache; 1020 1129 } … … 1140 1249 { 1141 1250 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); 1142 1254 #ifdef HAVE_XCACHE_COVERAGER 1143 1255 xc_coverager_request_shutdown(TSRMLS_C); … … 1345 1457 } 1346 1458 } LEAVE_LOCK(cache); 1347 xc_ entry_gc(TSRMLS_C);1459 xc_gc_deletes(TSRMLS_C); 1348 1460 } 1349 1461 break; … … 1417 1529 } 1418 1530 /* }}} */ 1419 #define TIME_MAX (sizeof(time_t) == sizeof(long) ? LONG_MAX : INT_MAX)1420 1531 /* {{{ proto mixed xcache_get(string name) 1421 1532 Get cached data by specified name */ … … 1435 1546 stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 1436 1547 if (stored_xce) { 1437 if (XG(request_time) <= stored_xce-> data.var->etime) {1548 if (XG(request_time) <= stored_xce->ctime + stored_xce->ttl) { 1438 1549 xc_processor_restore_zval(return_value, stored_xce->data.var->value TSRMLS_CC); 1439 1550 /* return */ … … 1457 1568 zval *name; 1458 1569 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) { 1462 1573 return; 1463 1574 } 1575 1576 /* max ttl */ 1577 if (xc_var_maxttl && (!xce.ttl || xce.ttl > xc_var_maxttl)) { 1578 xce.ttl = xc_var_maxttl; 1579 } 1580 1464 1581 xce.data.var = &var; 1465 1582 xc_entry_init_key_var(&xce, name TSRMLS_CC); … … 1471 1588 } 1472 1589 var.value = value; 1473 var.etime = ttl ? XG(request_time) + ttl : TIME_MAX;1474 1590 RETVAL_BOOL(xc_entry_store_dmz(&xce TSRMLS_CC) != NULL ? 1 : 0); 1475 1591 } LEAVE_LOCK(xce.cache); … … 1493 1609 stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 1494 1610 if (stored_xce) { 1495 if ( XG(request_time) <= stored_xce->data.var->etime) {1611 if (VAR_ENTRY_EXPIRED(stored_xce)) { 1496 1612 RETVAL_TRUE; 1497 1613 /* return */ … … 1539 1655 zval *name; 1540 1656 long count = 1; 1541 long ttl = 0;1542 1657 long value = 0; 1543 1658 zval oldzval; 1544 1659 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) { 1546 1662 return; 1547 1663 } 1664 1665 /* max ttl */ 1666 if (xc_var_maxttl && (!xce.ttl || xce.ttl > xc_var_maxttl)) { 1667 xce.ttl = xc_var_maxttl; 1668 } 1669 1548 1670 xce.data.var = &var; 1549 1671 xc_entry_init_key_var(&xce, name TSRMLS_CC); … … 1555 1677 fprintf(stderr, "incdec: gotxce %s\n", xce.name.str.val); 1556 1678 #endif 1557 stored_var = stored_xce->data.var;1558 1679 /* timeout */ 1559 if ( XG(request_time) > stored_var->etime) {1680 if (VAR_ENTRY_EXPIRED(stored_xce)) { 1560 1681 #ifdef DEBUG 1561 1682 fprintf(stderr, "incdec: expired\n"); … … 1566 1687 else { 1567 1688 /* do it in place */ 1689 stored_var = stored_xce->data.var; 1568 1690 if (Z_TYPE_P(stored_var->value) == IS_LONG) { 1691 stored_xce->ctime = XG(request_time); 1692 stored_xce->ttl = xce.ttl; 1569 1693 #ifdef DEBUG 1570 1694 fprintf(stderr, "incdec: islong\n"); … … 1574 1698 RETVAL_LONG(value); 1575 1699 Z_LVAL_P(stored_var->value) = value; 1576 break; 1700 break; /* leave lock */ 1577 1701 } 1578 1702 else { … … 1596 1720 RETVAL_LONG(value); 1597 1721 var.value = return_value; 1598 var.etime = ttl ? XG(request_time) + ttl : TIME_MAX; 1722 1599 1723 if (stored_xce) { 1600 1724 xce.atime = stored_xce->atime; … … 1913 2037 } 1914 2038 1915 #if def ZEND_ENGINE_21916 #define OnUpdate Int OnUpdateLong2039 #ifndef ZEND_ENGINE_2 2040 #define OnUpdateLong OnUpdateInt 1917 2041 #endif 1918 2042 … … 1932 2056 STD_PHP_INI_BOOLEAN("xcache.optimizer", "0", PHP_INI_ALL, OnUpdateBool, optimizer, zend_xcache_globals, xcache_globals) 1933 2057 #endif 2058 STD_PHP_INI_BOOLEAN("xcache.var_ttl", "0", PHP_INI_ALL, OnUpdateLong, var_ttl, zend_xcache_globals, xcache_globals) 1934 2059 #ifdef HAVE_XCACHE_COVERAGER 1935 2060 PHP_INI_ENTRY1 ("xcache.coveragedump_directory", "/tmp/pcov/", PHP_INI_SYSTEM, xc_OnUpdateString, &xc_coveragedump_dir) … … 1992 2117 php_info_print_table_start(); 1993 2118 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"); 2001 2130 php_info_print_table_end(); 2002 2131 … … 2097 2226 } 2098 2227 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"); 2106 2239 2107 2240 if (xc_php_size <= 0) {
Note: See TracChangeset
for help on using the changeset viewer.

