<?php
/**
* @author Colin McKinnon
* @licence LGPL version 3
* @package item cache
*
* example of underflow/overflow handlers for itemCache
*
* e.g.
*
* $h = new ic_backend('localhost','user','s3cr3t','main.keystore');
* list($overflow, $underflow)=$h->getHandlers();
* $ic = new itemCache(200, $overflow, 10, $underflow);
*
* while ($r=fetch_input_set()) {
* $r['lookup']=$ic->get($r['key']);
* if ($r['lookup']==null) {
* // i.e. the database set is not complete either...
* $r['lookup']=go_fetch_value_using_expensive_lookup('$r['key']);
* $ic->add($r['key'], $r['lookup']);
* // NB the implicit true flag ensures the data will be written back
* // when evicted
* }
* write_output_set($r);
* }
* $ic->flush();
* exit;
*
* Of course a really efficient solution might benefit from using a
* second instance of itemCache to handle the I/O on the input set
* to batch write operations.
*
*/
class ic_backend {
private $dbh;
private $tableref;
public function __construct($mysql_host, $mysql_user, $mysql_pass, $mysql_tableref)
{
$this->dbh=mysql_connect($mysql_host, $mysql_user, $mysql_pass);
if (!$this->dbh) {
trigger_error('Failed to conect to database: ' . mysql_error());
}
$this->tableref=$mysql_tableref;
}
public function getHandlers()
{
return array(
'overflow'=>array($this, 'overflow'),
'underflow'=>array($this, 'underflow'));
}
/**
* @param mixed $key
* @param object $itemCache
*
* It's the responsibility of the handler to insert the entry
* into the cache.
*/
public function underflow($key, $itemCache)
{
$mykey=mysql_real_escape_string($key, $this->dbh);
$qry="SELECT value FROM ' . $this->tableref . ' WHERE key='$mykey' LIMIT 0,1";
$result=mysql_query($qry, $this->dbh);
if ($result) {
if ($row=mysql_fetch_assoc($result)) {
$itemCache->add($key, $row['value'], false);
// NB the false flag tells the cache not to write this
// value back when evicted
} else {
/* Currently failed lookup (also missing from the database)
* is not cacheable, but we might want to make it cacheable
* e.g.
* $itemCache->add($key, null);
*/
}
} else {
trigger_error('Error fetching data: ' . mysql_error());
}
}
/**
* @param array $data - array of ($key1=>$val1, $key2=>$val2....)
*
* invoked from itemCache
*/
public function overflow($data)
{
$qry="INSERT IGNORE INTO " . $this->tableref . " (key, value) ";
$join=' VALUES ';
foreach ($data as $key=>$val) {
$qry.=$join . "('" . mysql_real_escape_string($key, $this->dbh)
. "','" . mysql_real_escape_string($value, $this->dbh) . "')";
$join=',';
}
if (!mysql_query($qry, $this->dbh)) {
trigger_error('Failed inserting data: ' . mysql_error());
}
}
}
|