cvs: php4 /pear Makefile.in /pear/Cache Function_Cache.php
| From: | Sebastian Bergmann | Date: | Sun, 10 Dec 2000 18:40:23 +0000 |
| Subject: | cvs: php4 /pear Makefile.in /pear/Cache Function_Cache.php | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-3058@lists.php.net to get a copy of this message | ||
sbergmann Sun Dec 10 10:40:23 2000 EDT
Added files:
/php4/pear/Cache Function_Cache.php
Modified files:
/php4/pear Makefile.in
Log:
Initial commit of Function_Cache.
Index: php4/pear/Makefile.in
diff -u php4/pear/Makefile.in:1.52 php4/pear/Makefile.in:1.53
--- php4/pear/Makefile.in:1.52 Thu Dec 7 03:27:35 2000
+++ php4/pear/Makefile.in Sun Dec 10 10:40:23 2000
@@ -11,6 +11,7 @@
PEAR_SUBDIRS = \
Benchmark \
+ Cache \
Crypt \
Date \
DB \
@@ -26,6 +27,7 @@
PEAR_FILES = \
Benchmark/Iterate.php \
Benchmark/Timer.php \
+ Cache/Function_Cache.php \
Crypt/HCEMD5.php \
Date/Calc.php \
DB.php \
Index: php4/pear/Cache/Function_Cache.php
+++ php4/pear/Cache/Function_Cache.php
<?php
//
// +----------------------------------------------------------------------+
// | PHP version 4.0 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt.
|
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Sebastian Bergmann <sb@sebastian-bergmann.de> |
// +----------------------------------------------------------------------+
//
// $Id: Function_Cache.php,v 1.1 2000/12/10 18:40:23 sbergmann Exp $
//
/**
* Function_Cache
*
* Purpose:
*
* Caching the result and output of functions.
*
* Example:
*
* require_once "Cache/Function_Cache.php";
*
* function foo( $string )
* {
* print $string . "<br>";
* return strrev( $string );
* }
*
* print cache_call( "foo", "test" ) . "<br><br>";
* print cache_call( "foo", "test" ) . "<br><br>";
*
* The function foo() will be executed only once, since the
* arguments of the second call are the same as before. But of
* course you will get the following output:
*
* test
* tset
*
* test
* tset
*
* Note:
*
* You cannot cache every function. You should only cache
* functions that only depend on their arguments and don't use
* global or static variables, don't rely on database queries or
* files, and so on.
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* @module Function_Cache
* @version $Revision: 1.1 $
* @access public
*/
/**
* @const CACHE_SHM_KEY
*/
define( "CACHE_SHM_KEY", 22478 );
/**
* @const CACHE_SHM_VAR
*/
define( "CACHE_SHM_VAR", 224 );
/**
* @const CACHE_SHM_SIZE
*/
define( "CACHE_SHM_SIZE", 524288 );
// check, if Shared Memory support is available
if( function_exists( "sem_get" ) && function_exists( "shm_attach" ) )
{
// use Shared Memory to store cache
$GLOBALS[ "_cache" ][ "mode" ] = "shared_memory";
}
else
{
// use global variable to store cache
$GLOBALS[ "_cache" ][ "mode" ] = "global";
}
// {{{ cache_call()
/**
* Calls a cacheable function or method.
*
* @return mixed $result
* @access public
*/
function cache_call()
{
// get arguments
$arguments = func_get_args();
// init cache
_cache_init();
// reference $GLOBALS[ "_cache" ][ "cache" ] as $cache
$cache =& $GLOBALS[ "_cache" ][ "cache" ];
// calculate hash for function call
$hash = md5( serialize( $arguments ) );
// get function name
$func_name = array_shift( $arguments );
// check, if function call is cached
if( !isset( $cache[ $hash ] ) ||
(
isset( $GLOBALS[ "_cache" ][ "lifetime" ][ $func_name ] ) &&
( time() - $cache[ $hash ][ "last_executed" ] ) > $GLOBALS[ "_cache"
][ "lifetime" ][ $func_name ]
)
)
{
// start output buffering
ob_start();
// call function, store result in cache
$cache[ $hash ][ "return" ] = call_user_func_array( $func_name, $arguments );
// store function's output in cache
$cache[ $hash ][ "output" ] = ob_get_contents();
// store timestamp
$cache[ $hash ][ "last_executed" ] = time();
// end output buffering
ob_end_clean();
// if cache is stored in shared memory update
// the shared memory segment
if( $GLOBALS[ "_cache" ][ "mode" ] == "shared_memory" )
{
_cache_shm_write( $hash );
}
}
// output cached output
print $cache[ $hash ][ "output" ];
// return cached result
return $cache[ $hash ][ "return" ];
}
// }}}
// {{{ cache_flush()
/**
* Flushes the Function Cache.
*
* @access public
*/
function cache_flush()
{
// reset global cache array
$GLOBALS[ "_cache" ][ "cache" ] = array();
// update shared memory segment, if needed
if( $GLOBALS[ "_cache" ][ "mode" ] == "shared_memory" )
{
_cache_shm_write( "flush" );
}
}
// }}}
// {{{ cache_set_lifetime()
/**
* Sets the lifetime for a cacheable function or method.
*
* @param mixed $func_name
* @param integer $lifetime
* @access public
*/
function cache_set_lifetime( $func_name, $lifetime )
{
// check $lifetime argument
if( is_number( $lifetime ) )
{
// store $lifetime
$GLOBALS[ "_cache" ][ "lifetime" ][ $func_name ] = $lifetime;
}
// I'm currently unsure on whether we need to store the
// new lifetime to Shared Memory if it's used
}
// }}}
// {{{ cache_set_mode()
/**
* Sets the mode of storage for the Function Cache.
*
* @param string $mode
* @access public
*/
function cache_set_mode( $mode )
{
// check $mode argument
if( $mode == "global" || $mode == "shared_memory" )
{
// store $mode
$GLOBALS[ "_cache" ][ "mode" ] = $mode;
}
}
// }}}
// {{{ _cache_init()
/**
* Initializes the cache.
*
* @access private
*/
function _cache_init()
{
// check, if we're using Shared Memory
if( $GLOBALS[ "_cache" ][ "mode" ] == "shared_memory" )
{
// read cache from Shared Memory
$GLOBALS[ "_cache" ][ "cache" ] = _cache_shm_read();
}
}
// }}}
// {{{ _cache_shm_read()
/**
* Reads the cache from a Shared Memory segement.
*
* @return array $cache
* @access private
*/
function _cache_shm_read()
{
$sem = sem_get( CACHE_SHM_KEY );
// lock shared memory
sem_acquire( $sem );
// get shared memory segment
$shm = shm_attach( CACHE_SHM_KEY, CACHE_SHM_SIZE );
// read cache contents
$cache = shm_get_var( $shm, CACHE_SHM_VAR );
// release shared memory
sem_release( $sem );
// disconnect from shared memory
shm_detach( $shm );
// return cache contents
return $cache;
}
// }}}
// {{{ _cache_shm_write()
/**
* Writes the cache to a Shared Memory segement.
*
* @access private
*/
function _cache_shm_write( $hash )
{
if( $hash != "flush" )
{
// get current cache
$cache = _cache_shm_read();
// update cache segment for current function call
$cache[ "_cache" ][ $hash ][ "last_executed" ] = $GLOBALS[
"_cache" ][ "cache" ][ $hash ][ "last_executed" ];
$cache[ "_cache" ][ $hash ][ "output" ] = $GLOBALS[
"_cache" ][ "cache" ][ $hash ][ "output" ];
$cache[ "_cache" ][ $hash ][ "return" ] = $GLOBALS[
"_cache" ][ "cache" ][ $hash ][ "return" ];
}
else
{
// flush cache
$cache = array();
}
$sem = sem_get( CACHE_SHM_KEY );
// lock shared memory
sem_acquire( $sem );
// get shared memory segment
$shm = shm_attach( CACHE_SHM_KEY );
// update shared memory segment
shm_put_var( $shm, CACHE_SHM_VAR, $cache );
// release shared memory
sem_release( $sem );
// disconnect from shared memory
shm_detach( $shm );
}
// }}}
?>