eAccelerator caching

Developer:

a. Reduce load on the DB server

This is based on the caching technique described on https://www.zenphoto.org/2008/01/hacks/ We'll use eAccelerator shm cache instead of storing the query results on disk.
1. Edit the functions-db.php under zp-core directory.
2. Search function query_single_row, change it to:
function query_single_row($sql, $noerrmsg=false) {
if ($cache = get_cache($sql))
return $cache;
$result = query($sql, $noerrmsg);
if ($result) {
$data = mysql_fetch_assoc($result);
store_cache($sql, $data);
return $data;
}
else {
return false;
}
}

3. Search function query_full_array, change it to:
function query_full_array($sql, $noerrmsg = false) {
if ($cache = get_cache($sql))
return $cache;
$result = query($sql, $noerrmsg);
if ($result) {
$allrows = array();
while ($row = mysql_fetch_assoc($result))
$allrows[] = $row;
store_cache($sql, $allrows);
return $allrows;
}
else {
return false;
}
}

4. Last thing, add two functions in functions-db.php. You could change “cachedirectory” to your cache directory, and change $cache_time_out to the expire time you want.
function store_cache($query, $result_cache) {
$cache_time_out = 600;
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))
return;
if (stristr($query, "ORDER BY RAND"))
return;
$key = 'sql_' . md5($query);
$val = serialize($result_cache);
eaccelerator_put($key, $val, $cache_time_out);
}


function get_cache($query) {
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))
return;
if (stristr($query, "ORDER BY RAND"))
return;
$key = 'sql_' . md5($query);
$val = eaccelerator_get($key);
if ( $val != NULL )
return unserialize($val);
}

b. Bypassing directory traversal

ZP scans the albums directory every time the script is executed. Since disk operations are expensive, we can try to limit disk-based I/O to make it load faster. We'll be using eAccelerator to cache our stuff, but you can easily adopt this code for APC, XCache, memcached or even a disk-file.
1. Open class-album.php in zp-core directory.
2. Put the following code at the beginning of the script:
function store_filenames_cache($dir, $has_dir, $pic_cache, $vid_cache) {
$cache_time_out = 600;
if ($has_dir) {
$pic_key = 'dp_' . md5($dir);
$vid_key = 'dv_' . md5($dir);
}
else {
$pic_key = 'fp_' . md5($dir);
$vid_key = 'fv_' . md5($dir);
}
$pic_val = serialize($pic_cache);
$vid_val = serialize($vid_cache);
eaccelerator_put($pic_key, $pic_val, $cache_time_out);
eaccelerator_put($vid_key, $vid_val, $cache_time_out);
}
function get_filenames_cache($dir, $has_dir, &$pic_cache, &$vid_cache) {
if ($has_dir) {
$pic_key = 'dp_' . md5($dir);
$vid_key = 'dv_' . md5($dir);
}
else {
$pic_key = 'fp_' . md5($dir);
$vid_key = 'fv_' . md5($dir);
}
$pic_cache = eaccelerator_get($pic_key);
$vid_cache = eaccelerator_get($vid_key);
if ( $pic_cache != NULL ) {
$pic_cache = unserialize($pic_cache);
}
else {
return FALSE;
}
if ( $vid_cache != NULL ) {
$vid_cache = unserialize($vid_cache);
}
else {
return FALSE;
}
return TRUE;
}

3. Locate the loadFileNames() function, and replace it with this:
function loadFileNames($dirs=false) {
if ($this->isDynamic()) { // there are no 'real' files
return array();
}
$albumdir = getAlbumFolder() . $this->name . "/";
if (!is_dir($albumdir) || !is_readable($albumdir)) {
$msg = gettext("Error: The 'albums' directory")." (" . $this->albumdir . ") ";
if (!is_dir($this->albumdir)) {
$msg .= gettext("cannot be found.");
} else {
$msg .= gettext("is not readable.");
}
die($msg);
}
//masroore - cache these results
if (get_filenames_cache($albumdir, $dirs, $files, $videos) === FALSE) {
$dir = opendir($albumdir);
$files = array();
$videos = array();
while (false !== ($file = readdir($dir))) {
if ($dirs && (is_dir($albumdir.$file) && (substr($file, 0, 1) != '.') || hasDyanmicAlbumSuffix($file))) {
$files[] = $file;
} else if (!$dirs && is_file($albumdir.$file)) {
if (is_valid_video($file)) {
$files[] = $file;
$videos[] = $file;
} else if (is_valid_image($file)) {
$files[] = $file;
}
}
}
closedir($dir);
store_filenames_cache($albumdir, $dirs, $files, $videos);
}
if (count($videos) > 0) {
$video_thumbs = array();
foreach($videos as $video) {
$video_root = substr($video, 0, strrpos($video,"."));
foreach($files as $image) {
$image_root = substr($image, 0, strrpos($image,"."));
if ($image_root == $video_root && $image != $video) {
$video_thumbs[] = $image;
}
}
}
$files = array_diff($files, $video_thumbs);
}
return $files;
}

This extension has been abandoned by the ZenphotoCMS team and we provide it for archival purposes on our "unsuppported-plugins-offical" GitHub repository "as is". .

Info & download (GitHub)

For questions and comments please use the forum or discuss on the social networks.


More by author:

  • Nothing else available by Invarbrass

Related items