﻿--- cacherouter/engines/apc.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/engines/apc.php	Mon May 26 10:48:20 2008 UTC
@@ -27,9 +27,6 @@
     }
     
     $cache = apc_fetch($this->key($key));
-    if (is_object($cache) && $cache->serialized) {
-      $cache->data = unserialize($cache->data);
-    }
     parent::set($key, $cache);
     return $cache;
   }
@@ -50,9 +47,8 @@
    *   Returns TRUE on success or FALSE on failure
    */
   function set($key, $value, $expire = CACHE_PERMENANT, $headers = NULL) {
-    if ($expire == CACHE_TEMPORARY) {
-      $expire = 180;
-    }
+    $return = FALSE;
+    if (!empty($key)) {
     // Create new cache object.
     $cache = new stdClass;
     $cache->cid = $key;
@@ -60,45 +56,44 @@
     $cache->expire = $expire;
     $cache->headers = $headers;
 
-    if (is_array($value) || is_object($value)) {
-      $cache->serialized = TRUE;
-      $cache->data = serialize($value);
-    }
-    else { 
       $cache->serialized = FALSE;
       $cache->data = $value;
+
+      //Store temporary as permanent - clean in flush
+      if ($expire == CACHE_TEMPORARY || $expire == CACHE_PERMENANT) {
+        $ttl = 0;
+      }
+      else {
+        $ttl = $expire - $cache->created;
     }
 
-    if (!empty($key) && !empty($value)) {
-      $this->lock();
+      // Get full key for storage and set it to $expire so we can keep track of the bin
+      $full_key = $this->key($key);
+
+      // Attempt to store full key and value
+      if (apc_store($full_key, $cache, $ttl)) {
+        // Update static cache
+        parent::set($key, $cache);
+        $return = TRUE;
 
       // Get lookup table to be able to keep track of bins
-      $lookup = apc_fetch('lookup_' . $this->name);
+        $this->lock();
+        $lookup = apc_fetch($this->lookup);
 
       // If the lookup table is empty, initialize table
       if (empty($lookup)) {
         $lookup = array();
       }
 
-      // Get full key for storage and set it to 1 so we can keep track of the bin
-      $full_key = $this->key($key);
-      $lookup[$full_key] = 1;
+        $lookup[$full_key] = $expire;
 
-      // Attempt to store full key and value
-      if (!apc_store($full_key, $cache, $expire)) {
-        unset($lookup[$full_key]);
-        $return = FALSE;
-      }
-      else {
-        $return = TRUE;
-      }
-    }
     // Resave the lookup table (even on failure)
-    apc_store('lookup_' . $this->name, $lookup);
+        apc_store($this->lookup, $lookup);
 
     // Remove lock.
     $this->unlock();
-
+      }
+    }
     return $return;
   }
   
@@ -107,36 +102,47 @@
    *   Remove item from cache.
    *
    * @param string $key
-   *   The key to set.
+   *   The key to delete.
    * @return mixed object|bool
    *   Returns either the cache object or FALSE on failure
    */
   function delete($key) {
     // Remove from static array cache.
-    parent::delete($key);
+    parent::flush();
     
     if (substr($key, -1, 1) == '*') {
+      $this->lock();
+      $lookup = apc_fetch($this->lookup);
+      if (is_array($lookup)) {
+        if ($key == '*') {
+          //Fast clean of lookup
+          apc_store($this->lookup, array());
+          $this->unlock();
+          foreach ($lookup as $k => $v) {
+            apc_delete($k);
+          }
+          return TRUE;
+        }
+        else {
       $key = substr($key, 0, strlen($key) - 1);
-      $lookup = apc_fetch('lookup_' . $this->name);
       foreach ($lookup as $k => $v) {
-        if (substr($k, 0, strlen($key) - 1)) {
+            if (strpos($k, $key) === 0) {
+            //if (substr($k, 0, strlen($key) - 1)) {
           apc_delete($k);
           unset($lookup[$k]);  
         }
       }
-      $this->lock();
-      apc_store('lookup_' . $this->name, $lookup);
-      $this->unlock();
     }
-    else {
-      if (!empty($key) && !empty($value)) {
-        if (!apc_delete($this->key($key))) {
-          $return = FALSE;
         }
         else {
-          $return = TRUE;
+      	$lookup = array();
         }
+      apc_store($this->lookup, $lookup);
+      $this->unlock();
       }
+    else {
+      //Remove only key - clean $lookup on flush
+      return apc_delete($this->key($key));
     }
   }
 
@@ -149,10 +155,11 @@
    *   Returns TRUE
    */
   function flush() {
+    parent::flush();
     $this->lock();
 
     // Get lookup table to be able to keep track of bins
-    $lookup = apc_fetch('lookup_' . $this->name);
+    $lookup = apc_fetch($this->lookup);
 
     // If the lookup table is empty, remove lock and return
     if (empty($lookup)) {
@@ -161,14 +168,21 @@
     }
 
     // Cycle through keys and remove each entry from the cache
+    if (is_array($lookup)) {
     foreach ($lookup as $k => $v) {
+        if ($v == CACHE_TEMPORARY || apc_fetch($k) === FALSE) {
       if (apc_delete($k)) {
         unset($lookup[$k]);
       }
     }
+      }
+    }
+    else {
+    	$lookup = array();
+    }
 
     // Resave the lookup table (even on failure)
-    apc_store('lookup_' . $this->name, $lookup);
+    apc_store($this->lookup, $lookup);
 
     // Remove lock
     $this->unlock();
@@ -185,16 +199,28 @@
    *   Returns TRUE on success, FALSE on failure
    */
   function lock() {
+    if (function_exists('apc_add')) {
     // Lock once by trying to add lock file, if we can't get the lock, we will loop
     // for 3 seconds attempting to get lock.  If we still can't get it at that point,
     // then we give up and return FALSE.
-    if (apc_add('lock_' . $this->name, TRUE) === FALSE) {
+      if (apc_add($this->lock, TRUE) === FALSE) {
+        $time = time();
+        while (apc_add($this->lock, TRUE) === FALSE) {
+          if (time() - $time >= 3) {
+            return FALSE;
+          }
+        }
+      }
+    }
+    else {
+      //For old versions of apc (before 3.0.13)
       $time = time();
-      while (apc_add('lock_' . $this->name, TRUE) === FALSE) {
+    	while (apc_fetch($this->lock)) {
         if (time() - $time >= 3) {
           return FALSE;
         }
       }
+    	apc_store($this->lock, TRUE);
     }
     return TRUE;
   }
@@ -208,6 +234,6 @@
    *   Returns TRUE on success, FALSE on failure
    */
   function unlock() {
-    return apc_delete('lock_' . $this->name); 
+    return apc_delete($this->lock);
   }
 }
﻿--- cacherouter/engines/db.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/engines/db.php	Sun May 25 18:34:58 2008 UTC
@@ -35,7 +35,7 @@
       else {
         if ($user->cache > $cache->created) {
           // This cache data is too old and thus not valid for us, ignore it.
-          return FALSE;
+          return 0;
         }
         else {
           $cache->data = db_decode_blob($cache->data);
@@ -47,7 +47,7 @@
       $this->content[$key] = $cache;
       return $cache;
     }
-    return FALSE;
+    return 0;
   }
   
   function set($key, $value, $expire = CACHE_PERMENANT, $headers = NULL) {
@@ -65,11 +65,16 @@
   }
   
   function delete($key) {
-    unset($this->content[$key]);
+    $this->content = array();
     if (substr($key, -1, 1) == '*') {
+      if ($key == '*') {
+        db_query("DELETE FROM {". $this->name ."}");
+      }
+      else {
       $key = substr($key, 0, strlen($key) - 1);
       db_query("DELETE FROM {". $this->name ."} WHERE cid LIKE '%s%%'", $key);  
     }
+    }
     else {
       db_query("DELETE FROM {". $this->name ."} WHERE cid = '%s'", $key);
     }
@@ -80,6 +85,11 @@
     db_query("DELETE FROM {". $this->name ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, time()); 
   }
   
+  function flush($flush) {
+    $this->content = array();
+    db_query("DELETE FROM {". $this->name ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, $flush);
+  }
+
   function gc() {
     // Garbage collection necessary when enforcing a minimum cache lifetime
     $cache_flush = variable_get('cache_flush', 0);
@@ -87,7 +97,7 @@
       // Reset the variable immediately to prevent a meltdown in heavy load situations.
       variable_set('cache_flush', 0);
       // Time to flush old cache data
-      $this->flush();
+      $this->flush($cache_flush);
     }
   }
 }
﻿--- cacherouter/engines/memcache.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/engines/memcache.php	Mon May 26 10:37:28 2008 UTC
@@ -10,18 +10,25 @@
   function __construct($bin) {
     global $conf;
     // Assign the servers on the following order: bin specific -> default specific -> localhost port 11211
-    $this->settings['servers'] = $conf['cacherouter'][$this->name]['server'];
-    if (!isset($conf['cacherouter'][$this->name]['server'])) {
+    if (isset($conf['cacherouter'][$bin]['server'])) {
+    	$this->settings['servers'] = $conf['cacherouter'][$bin]['server'];
+    	$this->settings['compress'] = isset($conf['cacherouter'][$bin]['compress']) ? MEMCACHE_COMPRESSED : 0;
+      $this->settings['shared'] = isset($conf['cacherouter'][$bin]['shared']) ?
+                                  $conf['cacherouter'][$bin]['shared'] : TRUE;
+    }
+    else {
       if (isset($conf['cacherouter']['default']['server'])) {
         $this->settings['servers'] = $conf['cacherouter']['default']['server'];
+        $this->settings['compress'] = isset($conf['cacherouter']['default']['compress']) ? MEMCACHE_COMPRESSED : 0;
+        $this->settings['shared'] = isset($conf['cacherouter']['default']['shared']) ?
+                                    $conf['cacherouter']['default']['shared'] : TRUE;
       }
       else {
         $this->settings['servers'] = array('localhost:11211');
+        $this->settings['compress'] = 0;
+        $this->settings['shared'] = TRUE;
       }
     }
-    $this->settings['compress'] = isset($conf['cacherouter'][$this->name]['compress']) ? MEMCACHE_COMPRESSED : 0;
-    $this->settings['shared'] = isset($conf['cacherouter'][$this->name]['shared']) ?
-                                $conf['cacherouter'][$this->name]['shared'] : TRUE;
                                 
     parent::__construct($bin);
     
@@ -37,73 +44,102 @@
     
     // Get from memcache
     $cache = $this->memcache->get($this->key($key));
-    
-    // Update static cache 
     parent::set($key, $cache);
-    
     return $cache;
   }
   
   function set($key, $value, $expire = CACHE_PERMENANT, $headers = NULL) {
-    if ($expire == CACHE_TEMPORARY) {
-      $expire = 180;
-    }
-    
+    $return = FALSE;
+    if (!empty($key)) {
     // Create new cache object.
     $cache = new stdClass;
     $cache->cid = $key;
     $cache->created = time();
     $cache->expire = $expire;
     $cache->headers = $headers;
-    $cache->data = $value;
-    
-    if (!empty($key) && !empty($value)) {
-      if ($this->settings['shared']) {
-        $this->lock();
 
-        // Get lookup table to be able to keep track of bins
-        $lookup = $this->memcache->get('lookup_' . $this->name);
+      $cache->serialized = FALSE;
+      $cache->data = $value;
 
-        // If the lookup table is empty, initialize table
-        if (empty($lookup)) {
-          $lookup = array();
+      //Store temporary as permanent - clean in flush
+      if ($expire == CACHE_TEMPORARY || $expire == CACHE_PERMENANT) {
+        $ttl = 0;
+      }
+      else {
+        $ttl = $expire - $cache->created;
         }
 
-        // Get full key for storage and set it to 1 so we can keep track of the bin
+      // Get full key for storage and set it to $expire so we can keep track of the bin
         $full_key = $this->key($key);
-        $lookup[$full_key] = 1;
 
         // Attempt to store full key and value
-        if (!$this->memcache->set($full_key, $cache, $this->settings['compress'], $expire)) {
-          unset($lookup[$full_key]);
-          $return = FALSE;
-        }
-        else {
+      if ($this->memcache->set($full_key, $cache, $this->settings['compress'], $ttl)) {
           // Update static cache
           parent::set($key, $cache);
           $return = TRUE;
+
+        if ($this->settings['shared']) {
+          // Get lookup table to be able to keep track of bins
+          $this->lock();
+          $lookup = $this->memcache->get($this->lookup);
+
+          // If the lookup table is empty, initialize table
+          if (empty($lookup)) {
+            $lookup = array();
         }
 
+          $lookup[$full_key] = $expire;
+
         // Resave the lookup table (even on failure)
-        $this->memcache->set('lookup_' . $this->name, $lookup, $this->settings['compress'], $expire);  
+          $this->memcache->set($this->lookup, $lookup, $this->settings['compress']);
 
         // Remove lock.
         $this->unlock();
       }
-      else {
-        // Update memcache
-        return $this->memcache->set($this->key($key), $cache, $this->settings['compress'], $expire);
       }
     }
+    return $return;
   }
   
   function delete($key) {
-    // Delete from static cache
-    parent::delete($key);
+    // Remove from static array cache.
+    parent::flush();
     
-    // Remove from memcache.
+    if (substr($key, -1, 1) == '*') {
+      // Get lookup table to be able to keep track of bins
+      $this->lock();
+      $lookup = $this->memcache->get($this->lookup);
+      if (is_array($lookup)) {
+        if ($key == '*') {
+          //Fast clean of lookup
+          $this->memcache->set($this->lookup, array(), $this->settings['compress']);
+          $this->unlock();
+          foreach ($lookup as $k => $v) {
+            $this->memcache->delete($k);
+          }
+          return TRUE;
+        }
+        else {
+          $key = substr($key, 0, strlen($key) - 1);
+          foreach ($lookup as $k => $v) {
+            if (strpos($k, $key) === 0) {
+            //if (substr($k, 0, strlen($key) - 1)) {
+              $this->memcache->delete($k);
+              unset($lookup[$k]);
+            }
+          }
+        }
+      }
+      else {
+      	$lookup = array();
+      }
+      $this->memcache->set($this->lookup, $lookup, $this->settings['compress']);
+      $this->unlock();
+    }
+    else {
+      //Remove only key - clean $lookup on flush
     return $this->memcache->delete($this->key($key));
-
+    }
   }
   
   function flush() {
@@ -116,7 +152,7 @@
       $this->lock();
 
       // Get lookup table to be able to keep track of bins
-      $lookup = $this->memcache->get('lookup_' . $this->name);
+      $lookup = $this->memcache->get($this->lookup);
 
       // If the lookup table is empty, remove lock and return
       if (empty($lookup)) {
@@ -125,31 +161,37 @@
       }
 
       // Cycle through keys and remove each entry from the cache
+      if (is_array($lookup)) {
       foreach ($lookup as $k => $v) {
+          if ($v == CACHE_TEMPORARY || $this->memcache->get($k) === FALSE) {
         if ($this->memcache->delete($k)) {
           unset($lookup[$k]);
         }
       }
+        }
+      }
+      else {
+      	$lookup = array();
+      }
 
       // Resave the lookup table (even on failure)
-      $this->memcache->set('lookup_' . $this->name, $lookup, $this->settings['compress'], 0);
+      $this->memcache->set($this->lookup, $lookup, $this->settings['compress'], 0);
 
       // Remove lock
       $this->unlock();
     }
-    else {
-      // Flush memcache
-      return $this->memcache->flush();
-    }
+    // Flush memcache - clean all stored data
+    //return $this->memcache->flush();
+    return TRUE;
   }
   
   function lock() {
     // Lock once by trying to add lock file, if we can't get the lock, we will loop
     // for 3 seconds attempting to get lock.  If we still can't get it at that point,
     // then we give up and return FALSE.
-    if ($this->memcache->add('lock_' . $this->name, $this->settings['compress'], 0) === FALSE) {
+    if ($this->memcache->add($this->lock, $this->settings['compress'], 0) === FALSE) {
       $time = time();
-      while ($this->memcache->add('lock_' . $this->name, $this->settings['compress'], 0) === FALSE) {
+      while ($this->memcache->add($this->lock, $this->settings['compress'], 0) === FALSE) {
         if (time() - $time >= 3) {
           return FALSE;
         }
@@ -159,7 +201,7 @@
   }
   
   function unlock() {
-    return $this->memcache->delete('lock_' . $this->name);   
+    return $this->memcache->delete($this->lock);
   }
   
   function connect() {
﻿--- cacherouter/engines/xcache.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/engines/xcache.php	Mon May 26 11:24:49 2008 UTC
@@ -51,9 +51,8 @@
    *   Returns TRUE on success or FALSE on failure
    */
   function set($key, $value, $expire = CACHE_PERMENANT, $headers = NULL) {
-    if ($expire == CACHE_TEMPORARY) {
-      $expire = 180;
-    }
+    $return = FALSE;
+    if (!empty($key)) {
     // Create new cache object.
     $cache = new stdClass;
     $cache->cid = $key;
@@ -61,45 +60,44 @@
     $cache->expire = $expire;
     $cache->headers = $headers;
 
-    if (is_array($value) || is_object($value)) {
-      $cache->serialized = TRUE;
-      $cache->data = serialize($value);
-    }
-    else { 
       $cache->serialized = FALSE;
       $cache->data = $value;
+
+      //Store temporary as permanent - clean in flush
+      if ($expire == CACHE_TEMPORARY || $expire == CACHE_PERMENANT) {
+        $ttl = 0;
+      }
+      else {
+        $ttl = $expire - $cache->created;
     }
 
-    if (!empty($key) && !empty($value)) {
-      $this->lock();
+      // Get full key for storage and set it to $expire so we can keep track of the bin
+      $full_key = $this->key($key);
+
+      // Attempt to store full key and value
+      if (xcache_set($full_key, $cache, $ttl)) {
+        // Update static cache
+        parent::set($key, $cache);
+        $return = TRUE;
 
       // Get lookup table to be able to keep track of bins
-      $lookup = xcache_get('lookup_' . $this->name);
+        $this->lock();
+        $lookup = xcache_get($this->lookup);
 
       // If the lookup table is empty, initialize table
       if (empty($lookup)) {
         $lookup = array();
       }
 
-      // Get full key for storage and set it to 1 so we can keep track of the bin
-      $full_key = $this->key($key);
-      $lookup[$full_key] = 1;
+        $lookup[$full_key] = $expire;
 
-      // Attempt to store full key and value
-      if (!xcache_set($full_key, $cache, $expire)) {
-        unset($lookup[$full_key]);
-        $return = FALSE;
-      }
-      else {
-        $return = TRUE;
-      }
-    }
     // Resave the lookup table (even on failure)
-    xcache_set('lookup_' . $this->name, $lookup);
+        xcache_set($this->lookup, $lookup);
 
     // Remove lock.
     $this->unlock();
-
+      }
+    }
     return $return;
   }
   
@@ -114,30 +112,41 @@
    */
   function delete($key) {
     // Remove from static array cache.
-    parent::delete($key);
+    parent::flush();
     
     if (substr($key, -1, 1) == '*') {
+      $this->lock();
+      $lookup = xcache_get($this->lookup);
+      if (is_array($lookup)) {
+        if ($key == '*') {
+          //Fast clean of lookup
+          xcache_set($this->lookup, array());
+          $this->unlock();
+          foreach ($lookup as $k => $v) {
+            xcache_unset($k);
+          }
+          return TRUE;
+        }
+        else {
       $key = substr($key, 0, strlen($key) - 1);
-      $lookup = xcache_get('lookup_' . $this->name);
       foreach ($lookup as $k => $v) {
-        if (substr($k, 0, strlen($key) - 1)) {
+            if (strpos($k, $key) === 0) {
+            //if (substr($k, 0, strlen($key) - 1)) {
           xcache_unset($k);
           unset($lookup[$k]);  
         }
       }
-      $this->lock();
-      xcache_set('lookup_' . $this->name, $lookup);
-      $this->unlock();
     }
-    else {
-      if (!empty($key) && !empty($value)) {
-        if (!xcache_unset($this->key($key))) {
-          $return = FALSE;
         }
         else {
-          $return = TRUE;
+      	$lookup = array();
         }
+      xcache_set($this->lookup, $lookup);
+      $this->unlock();
       }
+    else {
+      //Remove only key - clean $lookup on flush
+      return xcache_unset($this->key($key));
     }
   }
 
@@ -150,10 +159,11 @@
    *   Returns TRUE
    */
   function flush() {
+    parent::flush();
     $this->lock();
 
     // Get lookup table to be able to keep track of bins
-    $lookup = xcache_get('lookup_' . $this->name);
+    $lookup = xcache_get($this->lookup);
 
     // If the lookup table is empty, remove lock and return
     if (empty($lookup)) {
@@ -162,14 +172,18 @@
     }
 
     // Cycle through keys and remove each entry from the cache
+    if (is_array($lookup)) {
     foreach ($lookup as $k => $v) {
+        if ($v == CACHE_TEMPORARY || xcache_isset($k) === FALSE) {
       if (xcache_unset($k)) {
         unset($lookup[$k]);
       }
     }
+      }
+    }
 
     // Resave the lookup table (even on failure)
-    xcache_set('lookup_' . $this->name, $lookup);
+    xcache_set($this->lookup, $lookup);
 
     // Remove lock
     $this->unlock();
@@ -189,15 +203,15 @@
     // Lock once by trying to add lock file, if we can't get the lock, we will loop
     // for 3 seconds attempting to get lock.  If we still can't get it at that point,
     // then we give up and return FALSE.
-    if (xcache_isset('lock_' . $this->name) === TRUE) {
+    if (xcache_isset($this->lock) === TRUE) {
       $time = time();
-      while (xcache_isset('lock_' . $this->name) === TRUE) {
+      while (xcache_isset($this->lock) === TRUE) {
         if (time() - $time >= 3) {
           return FALSE;
         }
       }
     }
-    xcache_set('lock_' . $this->name, TRUE);
+    xcache_set($this->lock, TRUE);
     return TRUE;
   }
   
@@ -210,6 +224,6 @@
    *   Returns TRUE on success, FALSE on failure
    */
   function unlock() {
-    return xcache_unset('lock_' . $this->name); 
+    return xcache_unset($this->lock);
   }
 }
﻿--- cacherouter/Cache.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/Cache.php	Sun May 25 21:49:09 2008 UTC
@@ -4,13 +4,25 @@
   var $content = array();
   var $prefix = '';
   var $name = '';
+  var $lookup = '';
+  var $lock = '';
   
   function __construct($bin) {
     global $conf;
     
     $this->name = $bin;
+    if (isset($conf['cacherouter'][$bin])) {
     $this->prefix = $conf['cacherouter'][$bin]['prefix'];
   }
+    else {
+    	$this->prefix = $conf['cacherouter']['default']['prefix'];
+    }
+    if ($this->prefix) {
+      $this->prefix .= '-';
+    }
+    $this->lookup = $this->prefix .'lookup_'. $bin;
+    $this->lock = $this->prefix .'lock_'. $bin;
+  }
   
   function get($key) {
     if (isset($this->content[$key])) {
@@ -40,6 +52,6 @@
    *   Returns the full key of the cache item.
    */
   function key($key) {
-    return urlencode(($this->prefix ? $this->prefix . '-' : '') . $this->name . '-' . $key);
+    return urlencode($this->prefix . $this->name . '-' . $key);
   }
 }
﻿--- cacherouter/cacherouter.inc	Mon Mar 31 09:01:19 2008 UTC
+++ cacherouter/cacherouter.inc	Mon May 26 11:42:16 2008 UTC
@@ -8,23 +8,101 @@
 // We set this to true, and let the engines determine if they can implement it.  (e.g. db can't.)
 $conf['page_cache_fastpath'] = TRUE;
 
-function cache_get($key, $bin = 'cache') {
+/**
+ * Return data from the persistent cache. Data may be stored as either plain text or as serialized data.
+ * cache_get will automatically return unserialized objects and arrays.
+ *
+ * @param $cid
+ *   The cache ID of the data to retrieve.
+ * @param $table
+ *   The table $table to store the data in. Valid core values are 'cache_filter',
+ *   'cache_menu', 'cache_page', or 'cache' for the default cache.
+ */
+function cache_get($cid, $table = 'cache') {
   global $cache;
   if (!isset($cache)) {
     $cache = new CacheRouter();
   }
-  return $cache->get($key, $bin);  
+  $data = $cache->get($cid, $table);
+  if (is_object($data)) {
+    return $data;
+  }
+  else {
+    return 0;
+  }
 }
 
-function cache_set($key, $value, $bin = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
+/**
+ * Store data in the persistent cache.
+ *
+ * The persistent cache is split up into four database
+ * tables. Contributed modules can add additional tables.
+ *
+ * 'cache_page': This table stores generated pages for anonymous
+ * users. This is the only table affected by the page cache setting on
+ * the administrator panel.
+ *
+ * 'cache_menu': Stores the cachable part of the users' menus.
+ *
+ * 'cache_filter': Stores filtered pieces of content. This table is
+ * periodically cleared of stale entries by cron.
+ *
+ * 'cache': Generic cache storage table.
+ *
+ * The reasons for having several tables are as follows:
+ *
+ * - smaller tables allow for faster selects and inserts
+ * - we try to put fast changing cache items and rather static
+ *   ones into different tables. The effect is that only the fast
+ *   changing tables will need a lot of writes to disk. The more
+ *   static tables will also be better cachable with MySQL's query cache
+ *
+ * @param $cid
+ *   The cache ID of the data to store.
+ * @param $data
+ *   The data to store in the cache. Complex data types will be automatically serialized before insertion.
+ *   Strings will be stored as plain text and not serialized.
+ * @param $table
+ *   The table $table to store the data in. Valid core values are 'cache_filter',
+ *   'cache_menu', 'cache_page', or 'cache'.
+ * @param $expire
+ *   One of the following values:
+ *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
+ *     explicitly told to using cache_clear_all() with a cache ID.
+ *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
+ *     general cache wipe.
+ *   - A Unix timestamp: Indicates that the item should be kept at least until
+ *     the given time, after which it behaves like CACHE_TEMPORARY.
+ * @param $headers
+ *   A string containing HTTP header information for cached pages.
+ */
+function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
   global $cache;
   if (!isset($cache)) {
     $cache = new CacheRouter();
   }
-  return $cache->set($key, $value, $expire, $headers, $bin);
+  return $cache->set($cid, $data, $expire, $headers, $table);
 }
 
-function cache_clear_all($key = NULL, $bin = NULL, $wildcard = FALSE) {
+/**
+ *
+ * Expire data from the cache. If called without arguments, expirable
+ * entries will be cleared from the cache_page and cache_block tables.
+ *
+ * @param $cid
+ *   If set, the cache ID to delete. Otherwise, all cache entries that can
+ *   expire are deleted.
+ *
+ * @param $table
+ *   If set, the table $table to delete from. Mandatory
+ *   argument if $cid is set.
+ *
+ * @param $wildcard
+ *   If set to TRUE, the $cid is treated as a substring
+ *   to match rather than a complete ID. The match is a right hand
+ *   match. If '*' is given as $cid, the table $table will be emptied.
+ */
+function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
   global $cache;
   global $user;
   
@@ -32,15 +110,15 @@
     $cache = new CacheRouter();
   }
   
-  if (!isset($key) && !isset($bin)) {
+  if (!isset($cid) && !isset($table)) {
     // Clear the block cache first, so stale data will
     // not end up in the page cache.
-    $cache->flush('cache_block');
-    $cache->flush('cache_page');
+    cache_clear_all(NULL, 'cache_block');
+    cache_clear_all(NULL, 'cache_page');
     return;
   }
   
-  if (empty($key)) {
+  if (empty($cid)) {
     if (variable_get('cache_lifetime', 0)) {
       // We store the time in the current user's $user->cache variable which
       // will be saved into the sessions table by sess_write(). We then
@@ -56,29 +134,28 @@
       else if (time() > ($cache_flush + variable_get('cache_lifetime', 0))) {
         // Clear the cache for everyone, cache_flush_delay seconds have
         // passed since the first request to clear the cache.
-        $cache->flush($bin);
+        $cache->flush($table);
         variable_set('cache_flush', 0);
       }
     }
     else {
       // No minimum cache lifetime, flush all temporary cache entries now.
-      $cache->flush($bin);
+      $cache->flush($table);
     }
   }
   else {
     if ($wildcard) {
       if ($cid == '*') {
-        $cache->flush($bin);
+        $cache->delete('*', $table);
       }
       else {
-        $cache->delete($key . '*', $bin);
+        $cache->delete($cid .'*', $table);
       }
     }
     else {
-      $cache->delete($key, $bin);
+      $cache->delete($cid, $table);
     }
   }
-  
 }
 
 /**
﻿--- cacherouter/CacheRouter.php	Mon Mar 31 08:40:50 2008 UTC
+++ cacherouter/CacheRouter.php	Fri May 23 18:13:09 2008 UTC
@@ -13,7 +13,7 @@
   private function __init($bin) {
     global $conf;
     
-    if (isset($conf['cacherouter'][$bin]['engine']) && !isset($map[$bin])) {
+    if (isset($conf['cacherouter'][$bin]['engine']) && !isset($this->map[$bin])) {
       $type = strtolower($conf['cacherouter'][$bin]['engine']);
     }
     else {
@@ -26,39 +26,39 @@
     }
     $cache_engine = $type . 'Cache';
     
-    $this->map[$bin] =& new $cache_engine($bin);
+    $this->map[$bin] = new $cache_engine($bin);
   }
   
   public function get($key, $bin) {
-    if (!isset($map[$bin])) {
+    if (!isset($this->map[$bin])) {
       $this->__init($bin);
     }
     return $this->map[$bin]->get($key);
   }
 
   public function set($key, $value, $expire, $headers, $bin) {
-    if (!isset($map[$bin])) {
+    if (!isset($this->map[$bin])) {
       $this->__init($bin);
     }
     return $this->map[$bin]->set($key, $value, $expire, $headers);
   }
 
   public function delete($key, $bin) {
-    if (!isset($map[$bin])) {
+    if (!isset($this->map[$bin])) {
       $this->__init($bin);
     }
     return $this->map[$bin]->delete($key);
   }
 
   public function flush($bin) {
-    if (!isset($map[$bin])) {
+    if (!isset($this->map[$bin])) {
       $this->__init($bin);
     }
     return $this->map[$bin]->flush();
   }
   
   public function page_fast_cache($bin) {
-    if (!isset($map[$bin])) {
+    if (!isset($this->map[$bin])) {
       $this->__init($bin);
     }
     return $this->map[$bin]->page_fast_cache();
