Location: PHPKode > projects > Tv.2 CMS > tv2engine/ctlRtVarCache.class.php
<?php

/** 
 * General purpose runtime cache for variables and objects
 * 
 * @package tv2-engine
 * @author Emilis Dambauskas (hide@address.com)
 * @copyright 2002–2003 Emilis Dambauskas under {@link http://opensource.org/licenses/artistic-license.php Artistic license}
 * @version $Id: ctlRtVarCache.class.php,v 1.2 2003/07/09 05:36:03 lunaticlt Exp $
 * @class ctlRtVarCache 
 */
class ctlRTvarCache
{
	/**
	 * Stored data array
	 * @attribute private array $data
	 */
	var $data;
	
	/**
	 * Array containing types of vars/objects stored in cache
	 * @attribute private array $types
	 */
	var $types;
	
	/**
	 * Key array
	 * @attribute private array $keys
	 */
	var $keys;
	
	/**
	 * Counter. Needed for indexing vars
	 * @attribute private int $counter
	 */
	var $counter;
	
	/**
	 * Cache size
	 * @attribute private int size
	 */
	var $size;
	
	/**
	 * Constructor. Initializes attributes
	 *
	 * @constructor ctlRtVarCache   
	 * @param optional int limit cache size (default 100)
	 */  
	function ctlRTvarCache($limit = 100)
	{
		$this->size = $limit;
		$this->types = array();
		$this->keys = array();
		$this->data = array();
		$this->counter = 1;
	}
	
	/**
	 * Sends an error to the {@link $errors} object and returns FALSE
	 *
	 * @method private error
	 * @return boolean always FALSE
	 * @param string $msg error message
	 * @use $errors
	 */
	function error($msg)
	{
		$GLOBALS['errors']->add(get_class($this).': '.$msg);
		return FALSE;
	}
	
	/**
	 * This function prints info about cache contents grouped by types. Usefull 
	 * for debugging purposes.
	 *
	 * @method public debugOut   
	 */  
	function debugOut()
	{
		foreach($this->types as $typeId => $typeN)
		{
			echo "\n<hr><b>".$typeN." (".sizeof($this->keys[$typeId])."):</b><bR><pre>";
			print_r($this->keys[$typeId]);
			echo "</pre>\n";
		}
	}
	
	
	/**
	 * This method calls a method on object in cache with given $id. Used in 
	 * $this->delete() and $this->deleteKeys() methods.
	 *
	 * @method private callObjectMethod
	 * @return mixed whatever the object method returns or FALSE on failure 
	 * @param mixed $id id of object in cache 
	 * @param string $ObjectMethod Object method name 
	 * @param optional array $ObjectMethodParams Array of parameters to be passed to the method.  
	 */  
	function callObjectMethod($id, $ObjectMethod, $ObjectMethodParams = FALSE)
	{
		if ($ObjectMethod && is_object($this->data[$id]))
			{
				if ($ObjectMethodParams === FALSE)
						$result = call_user_func_array(array(&$this->data[$id], $ObjectMethod));
				else
						$result = call_user_func_array(array(&$this->data[$id], $ObjectMethod), $ObjectMethodParams);
				return $result;
			}
		else return FALSE;
	}
	
	
	/**
	 * Returns internal type id
	 *
	 * @method private findTypeId
	 * @return mixed type id or FALSE on failure 
	 * @param string $type type name  
	 */  
	function findTypeId($type)
	{
		return array_search($type, $this->types, TRUE);
	}
	
	/**
	 * Returns internal variable id
	 *
	 * @method private findId
	 * @return mixed var id or FALSE on failure  
	 * @param string $type type name
	 * @param mixed $keys key name or key name array
	 */  
	function findId($type, $keys)
	{
		$t_id = $this->findTypeId($type);
		if (!$t_id)
			return FALSE;

		if (!is_array($keys))
			$keys = (array) $keys;
		
		while ($key = array_pop($keys))
			if (isset($this->keys[$t_id][$key]))
				return $this->keys[$t_id][$key];

		return FALSE;
	}
	
	
	/**
	 * Adds var to cache
	 *
	 * @method public add
	 * @return boolean TRUE on success, FALSE on error 
	 * @param string $type type name 
	 * @param mixed $keys key name, or key name array 
	 * @param optional string $ObjectMethod method name to call on object 
	 * @param optional array $ObjectMethodParams parameters for the method  
	 */  
	function add($type, $keys, &$data, $ObjectMethod = FALSE, $ObjectMethodParams = FALSE)
	{
		$foundType = TRUE;
		if (!is_array($keys))
				$keys = (array)$keys;
		
		// 1. check if type exists:
		$t_id = $this->findTypeId($type);
		if (!$t_id)
		{
			$foundType = FALSE;
			$t_id = $this->counter++;
			$this->types[$t_id] = $type;
		}
	
		// 2. check if entity exists and add or update it:
		if (!$foundType || !($id = $this->findId($type, $keys)))
			$id = $this->counter++;
			
		while ($key = array_pop($keys))
			$this->keys[$t_id][$key] = $id;
			
		// 3. remove first element if cache full:
		if (sizeof($this->data) >= $this->size)
			array_shift($this->data);
		
		$this->data[$id] = &$data;
		
		// call object methods if needed:
		if ($ObjectMethod)
			$this->callObjectMethod($id, $ObjectMethod, $ObjectMethodParams);

		return $id;
	}
	
	
	/**
	 * Adds another key alias for a var
	 *
	 * @method public addKey
	 * @return boolean TRUE on success, FALSE on failure 
	 * @param string $type type name 
	 * @param array $keys array of keys (should contain at least one previously used key).  
	 */  
	function addKey($type, $keys)
	{
		if (!is_array($keys))
			$keys = (array) $keys;
		
		$t_id = $this->findTypeId($type);
		if (!$t_id)
			return FALSE;
		
		$id = $this->findId($type, $keys);
		if (!$id)
			return FALSE;
				
		while ($key = array_pop($keys))
			$this->keys[$t_id][$key] = $id;
		
		return TRUE;
	} // end of function addKey()
	
	
	/**
	 * Deletes entity from cache. Can optionally call a method on objects.
	 *
	 * @method public delete
	 * @return boolean TRUE on success, FALSE on failure 
	 * @param string $type type name 
	 * @param mixed $keys key name or key name array 
	 * @param optional string $ObjectMethod method name to call on object 
	 * @param optional array $ObjectMethodParams parameters for the method  
	 */  
	function delete($type, $keys, $ObjectMethod = FALSE, $ObjectMethodParams = FALSE)
	{
		if ($id = $this->findId($type, $keys))
		{
			// call object methods if needed:
			if ($ObjectMethod)
				$this->callObjectMethod($id, $ObjectMethod, $ObjectMethodParams);
			
			// remove all data about the entity:
			$rm_keys = array_search($id, $this->keys[$type]);
			if (!is_array($rm_keys))
					$rm_keys = (array) $rm_keys;
			while ($key = array_pop($rm_keys))
				unset($this->keys[$t_id][$key]);

			unset($this->data[$id]);
			
			return TRUE;
		}
		else
			return FALSE;
	} // end of function delete();
	
	
	/**
	 * Removes keys that correspond to the var.
	 *
	 * @method public deleteKeys
	 * @return boolean FALSE on failure 
	 * @param string $type type name 
	 * @param mixed $keys key name or array of key names 
	 * @param optional boolean $many If $many == TRUE it means that $keys may belong to different entities (makes operate slower). Default is FALSE. 
	 * @param optional string $ObjectMethod method name to call on object 
	 * @param optional array $ObjectMethodParams parameters for the method  
	 */  
	function deleteKeys($type, $keys, $many = FALSE, $ObjectMethod = FALSE, $ObjectMethodParams = FALSE)
	{
		// 1. check if type exists:
		$t_id = $this->findTypeId($type);
		if (!$t_id)
		{
			$this->error('Unknown type \''.$type.'\' passed to function deleteKeys.');
			return FALSE;
		}
		
		// 2. $keys has to be an array:
		if (is_array($keys))
			$keys = (array) $keys;
		
		// 3a. we have got keys of one entity:
		if (!$many)
		{
			$id = $this->findId($type, $keys);
			while ($key = array_pop($keys))
				unset($this->keys[$t_id]);
			if (!array_search($id, $this->keys[$t_id]))
			{
				if ($ObjectMethod)
					$this->callObjectMethod($id, $ObjectMethod, $ObjectMethodParams);
				unset($this->data[$id]);
			}
		} // end of 3a.
		// 3b. we have got keys of multiple entities:
		else
		{
			while ($key = array_pop($keys))
			{
				if ($id = $this->findId($type, $keys))
				{
					unset($this->keys[$t_id]);
					if (!array_search($id, $this->keys[$t_id]))
					{
						if ($ObjectMethod)
							$this->callObjectMethod($id, $ObjectMethod, $ObjectMethodParams);
						unset($this->data[$id]);
					}
				}
			}
		} // end of 3b.
	} // end of function deleteKeys()
	
	
	/**
	 * Checks if var exists in cache
	 *
	 * @method public exists
	 * @return mixed internal id on success, FALSE on failure 
	 * @param string $type type name 
	 * @param mixed $keys key name or key name array  
	 */  
	function exists($type, $keys)
	{
		$t_id = $this->findTypeId($type);
		if (!$t_id)
			return FALSE;
		
		$id = $this->findId($type, $keys);
		if (!$id)
			return FALSE;

		return $id;
	} // end of function exists
	

	/**
	 * Searches for var and returns a reference to it
	 *
	 * @method public find
	 * @return ref mixed whatever the variable is 
	 * @param string $type type name 
	 * @param mixed $keys key name or array of key names  
	 */  
	function &find($type, $keys)
	{
		$id = $this->findId($type, $keys);
		
		if (!$id)
			return FALSE;
		else
			return $this->data[$id];
	} // end of function &find()

} // end of class ctlRTvarCache

?>
Return current item: Tv.2 CMS