class CacheSharedMemory {
protected function encode($value) {
return serialize($value);
}
protected function decode($value){
return unserialize($value);
}
protected function deleteSMB($ID) {
$shm_id = @shmop_open($ID, "w", 0, 0);
@shmop_delete($shm_id);
@shmop_close($shm_id);
}
protected function writeSMB($ID, $value, $perm = 0644) {
$this->deleteSMB($ID);
$value = $this->encode($value);
$shm_id = shmop_open($ID, "c", $perm, strlen($value));
shmop_write($shm_id, $value, 0);
shmop_close($shm_id);
}
protected function readSMB($ID) {
$shm_id = @shmop_open($ID, "a", 0, 0);
$value = $this->decode(@shmop_read($shm_id, 0, @shmop_size($shm_id)));
@shmop_close($shm_id);
return $value;
}
protected function getRegistry() {
$reg = $this->readSMB(1);
if(is_array($reg)) {
return $reg;
} else {
$this->writeSMB(1, array());
return $this->getRegistry();
}
}
protected function handleRegistered($handle) {
$reg = $this->getRegistry();
if(in_array($handle, $reg))
return array_search($handle, $reg);
else
return FALSE;
}
protected function registerHandle($handle) {
if(is_string($handle)) {
$key = $this->handleRegistered($handle);
if(is_int($key)) {
return $key;
} else {
$array = $this->getRegistry();
array_push($array, "".$handle);
$this->writeSMB(1, $array);
return $this->handleRegistered($handle);
}
}
}
protected function unregisterByKey($key) {
if(is_int($key)) {
$array = $this->getRegistry();
if($array[$key]) {
unset($array[$key]);
$this->writeSMB(1, $array);
$this->deleteSMB($key + 2);
return TRUE;
} else {
return FALSE;
}
} else {
return FALSE;
}
}
protected function unregisterByHandle($handle) {
return $this->unregisterByKey($this->handleRegistered($handle));
}
public function set($handle, $value) {
$this->writeSMB($this->registerHandle($handle) + 2, $value);
}
public function get($handle) {
if($key = $this->handleRegistered($handle)) {
return $this->readSMB($key + 2);
} else {
return FALSE;
}
}
public function is_set($handle) {
return is_int($this->handleRegistered($handle));
}
public function clear($handle) {
$key = $this->handleRegistered($handle);
if(is_int($key)) {
$this->unregisterByKey($key);
return TRUE;
} else {
return FALSE;
}
}
//Debugging tools
public function debug($tool = NULL) {
switch($tool) {
case "clear":
$this->clearCache();
break;
case "size":
print $this->getTotalCacheSize();
break;
case "registry":
return $this->getRegistry();
case "all":
foreach($this->getRegistry() as $handle) {
$array[$handle] = $this->get($handle);
}
return $array;
case "random":
$array = $this->getRegistry();
$return->id = array_rand($array);
$return->value = $this->get($array[$return->id]);
return $return;
}
}
private function clearCache() {
$registry = $this->getRegistry();
foreach($registry as $key => $handle) {
$this->clear($handle);
}
$this->deleteSMB(1);
}
private function getCacheSize($key) {
return shmop_size(shmop_open($key, "a", 0, 0));
}
private function getTotalCacheSize() {
$si = ' KMGTPEZY';
$bytes = 0;
foreach($this->getRegistry() as $key => $handle) {
$bytes += $this->getCacheSize($key + 2);
}
for($x = 0; $bytes >= 1000 && $x < (strlen($si) - 1); $bytes /= 1000, $x++);
return round($bytes, 2) . $si{$x} . 'B';
}
}