cellog Thu Jun 12 18:56:23 2008 UTC
Modified files: (Branch: PHP_5_3)
/php-src/ext/phar phar.c phar.phar phar_internal.h tar.c zip.c
/php-src/ext/phar/tests phpinfo_001.phpt phpinfo_002.phpt
phpinfo_003.phpt phpinfo_004.phpt
Log:
[DOC] add phar.cache_list, a PATH_SEPARATOR-separated list of full paths to
phar archives to cache
at startup. This caches the manifest, so that on first access to a phar
archive, no file manifest parsing occurs.
This could use further tweaking. For instance, the full copy of the manifest
into the current process may be unnecessary if refcounting could be external
to the manifest. This would be another significant gain. With APC, I
measure a slight perf increase to 19 req/sec up from 16 req/sec, without it
approaches
regular PHP at 3.8 req/sec (regular is 4 req/sec). This is benching
phpMyAdmin
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.c?r1=1.370.2.11r2=1.370.2.12diff_format=u
Index: php-src/ext/phar/phar.c
diff -u php-src/ext/phar/phar.c:1.370.2.11 php-src/ext/phar/phar.c:1.370.2.12
--- php-src/ext/phar/phar.c:1.370.2.11 Mon Jun 9 16:07:18 2008
+++ php-src/ext/phar/phar.c Thu Jun 12 18:56:23 2008
@@ -17,7 +17,7 @@
+--+
*/
-/* $Id: phar.c,v 1.370.2.11 2008/06/09 16:07:18 cellog Exp $ */
+/* $Id: phar.c,v 1.370.2.12 2008/06/12 18:56:23 cellog Exp $ */
#define PHAR_MAIN 1
#include phar_internal.h
@@ -43,6 +43,7 @@
#ifndef PHAR_HAVE_OPENSSL
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t
end, char *key, int key_len, char **signature, int *signature_len TSRMLS_DC);
#endif
+static void destroy_phar_data(void *pDest);
ZEND_DECLARE_MODULE_GLOBALS(phar)
#if PHP_VERSION_ID = 50300
@@ -112,9 +113,94 @@
}
/* }}}*/
+/* this global stores the global cached pre-parsed manifests */
+static HashTable cached_phars;
+static HashTable cached_alias;
+
+static void phar_split_cache_list(TSRMLS_D)
+{
+ char *tmp;
+ char *key, *lasts, *end;
+ char ds[1];
+ phar_archive_data *phar;
+
+ if (!PHAR_GLOBALS-cache_list || !(PHAR_GLOBALS-cache_list[0])) {
+ return;
+ }
+
+ ds[0] = DEFAULT_DIR_SEPARATOR;
+ zend_init_rsrc_list(TSRMLS_C);
+ tmp = estrdup(PHAR_GLOBALS-cache_list);
+
+ /* fake request startup */
+ PHAR_GLOBALS-request_init = 1;
+ PHAR_G(has_bz2) = zend_hash_exists(module_registry, bz2,
sizeof(bz2));
+ PHAR_G(has_zlib) = zend_hash_exists(module_registry, zlib,
sizeof(zlib));
+ zend_hash_init((PHAR_GLOBALS-phar_fname_map),
sizeof(phar_archive_data*), zend_get_hash_value, destroy_phar_data, 1);
+ zend_hash_init((PHAR_GLOBALS-phar_alias_map),
sizeof(phar_archive_data*), zend_get_hash_value, NULL, 1);
+ PHAR_GLOBALS-manifest_cached = 1;
+ PHAR_GLOBALS-persist = 1;
+
+ for (key = php_strtok_r(tmp, ds, lasts);
+ key;
+ key = php_strtok_r(NULL, ds, lasts))
+ {
+ end = strchr(key, DEFAULT_DIR_SEPARATOR);
+ if (end) {
+ if (SUCCESS == phar_open_from_filename(key, end - key,
NULL, 0, 0, phar, NULL TSRMLS_CC)) {
+finish_up:
+ php_stream_close(phar-fp);
+ phar-fp = NULL;
+ } else {
+finish_error:
+ PHAR_GLOBALS-persist = 0;
+ PHAR_GLOBALS-manifest_cached = 0;
+ zend_destroy_rsrc_list(EG(regular_list)
TSRMLS_CC);
+ efree(tmp);
+ zend_hash_destroy((PHAR_G(phar_fname_map)));
+ PHAR_GLOBALS-phar_fname_map.arBuckets = 0;
+ zend_hash_destroy((PHAR_G(phar_alias_map)));
+ PHAR_GLOBALS-phar_alias_map.arBuckets = 0;
+ /* free cached manifests */
+ PHAR_GLOBALS-request_init = 0;
+ return;
+ }
+ } else {
+ if (SUCCESS == phar_open_from_filename(key,
strlen(key), NULL, 0, 0, phar, NULL TSRMLS_CC)) {
+ goto finish_up;
+ } else {
+ goto finish_error;
+ }
+ }
+ }
+ PHAR_GLOBALS-persist = 0;
+ PHAR_GLOBALS-request_init = 0;
+ cached_phars = PHAR_GLOBALS-phar_fname_map;
+ cached_alias = PHAR_GLOBALS-phar_alias_map;
+ PHAR_GLOBALS-phar_fname_map.arBuckets = 0;
+ PHAR_GLOBALS-phar_alias_map.arBuckets = 0;
+
+ zend_destroy_rsrc_list(EG(regular_list) TSRMLS_CC);
+ efree(tmp);
+}
+/* }}} */
+
+ZEND_INI_MH(phar_ini_cache_list) /* {{{ */
+{
+