Index: memcache.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/memcache/memcache.inc,v
retrieving revision 1.28.2.15
diff -u -p -r1.28.2.15 memcache.inc
--- memcache.inc	1 Oct 2010 14:25:27 -0000	1.28.2.15
+++ memcache.inc	4 Oct 2010 05:48:38 -0000
@@ -164,42 +164,6 @@ class MemCacheDrupal implements DrupalCa
   }
 
   /**
-   * We hash cids to keep them a consistent, managable length.  Alternative algorithms
-   * can be specified if you're looking for better performance (benchmark first!).
-   * Hash collissions are not a big deal, simply leads to all collided items being
-   * flushed together.
-   */
-  function hash_cid($cid) {
-    static $hashes = array();
-    $memcache_hash = variable_get('memcache_hash', 'md5');
-    if (function_exists($memcache_hash)) {
-      $hashes[$cid] = $memcache_hash($cid);
-    }
-    else {
-      $hashes[$cid] = $cid;
-    }
-    return $hashes[$cid];
-  }
-
-  /**
-   * Determine all possible hashes that could match our cid.  We optimize away
-   * the overhead of checking all possible matches by using multiget.
-   */
-  private function multihash_cid($cid) {
-    static $hashes = array();
-    if (!isset($hashes[$this->bin])) {
-      $hashes[$this->bin] = array();
-    }
-    if (!isset($hashes[$this->bin][$cid])) {
-      for ($i = 0; $i <= strlen($cid); $i++) {
-        $subcid = substr($cid, 0, $i);
-        $hashes[$this->bin][$cid][$subcid] = '.wildcard-'. $this->bin . $this->hash_cid($subcid);
-      }
-    }
-    return $hashes[$this->bin][$cid];
-  }
-
-  /**
    * Sum of all matching wildcards.  Checking any single cache item's flush value
    * against this single-value sum tells us whether or not a new wildcard flush
    * has affected the cached item.
@@ -215,46 +179,72 @@ class MemCacheDrupal implements DrupalCa
    */
   private function wildcards($cid, $flush = FALSE) {
     static $wildcards = array();
+    $result = array();
 
-    // If this bin has never had a wildcard flush, or the last wildcard flush
-    // was more than a month ago, simply return an empty array to indicate that
-    // it has never been flushed and to avoid the overhead of a wildcard lookup.
-    if (!$flush && (!isset($this->wildcard_timestamps[$this->bin]) ||
-        $this->wildcard_timestamps[$this->bin] <= (REQUEST_TIME - $this->invalidate))) {
-      return array();
-    }
+    if (isset($wildcard_timestamps[$table]) && is_array($wildcard_timestamps[$table])) {
+      $multihash = array();
+
+      // Find statically cached wildcards, and generate further possible
+      // wildcards for this cid from wildcard lengths that are recorded
+      // as flushed in the past month.
+      foreach ($wildcard_timestamps[$table] as $length => $timestamp) {
+        if ($timestamp >= (REQUEST_TIME - $wildcard_invalidate)) {
+          $key = '.wildcard-' . $table . substr($cid, 0, $length);
+          $wildcard = dmemcache_key($key, $table);
+          if (isset($wildcards[$table][$wildcard])) {
+            $result[$wildcard] = $wildcards[$table][$wildcard];
+          }
+          else {
+            $multihash[$wildcard] = $key;
+          }
+        }
+      }
+
+      // Use getMulti to retrieve any possible but unknown wildcards.
+      if (!empty($multihash)) {
+        $multivalues = dmemcache_get_multi($multihash, $table);
+        if (is_array($multivalues)) {
+          $result = array_merge($result, $multivalues);
+          if (isset($wildcards[$table])) {
+            $wildcards[$table] = array_merge($wildcards[$table], $multivalues);
+          }
+          else {
+            $wildcards[$table] = $multivalues;
+          }
+          $multihash = array_diff_key($multihash, $multivalues);
+        }
 
-    if (!isset($wildcards[$this->bin]) || !isset($wildcards[$this->bin][$cid])) {
-      $multihash = $this->multihash_cid($cid);
-      $wildcards[$this->bin][$cid] = dmemcache_get_multi($multihash, $this->bin);
-      if (!is_array($wildcards[$this->bin][$cid])) {
-        $wildcards[$this->bin][$cid] = array();
+        // $multihash now contains only wildcards that were not in the cache.
+        foreach ($multihash as $wildcard => $key) {
+          $wildcards[$table][$wildcard] = 0;
+          // Storing zero cache flushes makes the cache hit ratio look better,
+          // at the expense of using more cache space.
+          //dmemcache_set($key, 0, 0, $table);
+        }
       }
     }
     if ($flush) {
-      if (!empty($cid)) {
-        // Avoid too many variable_set() by only recording a flush for
-        // a fraction of the wildcard invalidation variable. Defaults to
-        // 28 / 4 = one week.
-        if (!isset($this->wildcard_timestamps[$this->bin]) ||
-            (REQUEST_TIME - $this->wildcard_timestamps[$this->bin] > $this->invalidate / 4)) {
-          $this->wildcard_timestamps[$this->bin] = REQUEST_TIME;
-          variable_set('memcache_wildcard_timestamps', $this->wildcard_timestamps);
-        }
+      // Avoid too many variable_set() by only recording a flush for
+      // a fraction of the wildcard invalidation variable. Defaults to
+      // 28 / 4 = one week.
+      $length = strlen($cid);
+      if (!isset($wildcard_timestamps[$table][$length]) ||
+          ($_SERVER['REQUEST_TIME'] - $wildcard_timestamps[$table][$length] > $wildcard_invalidate / 4)) {
+        $wildcard_timestamps[$table][$length] = $_SERVER['REQUEST_TIME'];
+        variable_set('memcache_wildcard_timestamps', $wildcard_timestamps);
       }
-      $hash = $this->hash_cid($cid);
-      $wildcard = dmemcache_key('.wildcard-' . $this->bin . $hash, $this->bin);
-      if (isset($wildcards[$this->bin][$cid][$wildcard])) {
-        $mc = dmemcache_object($this->bin);
-        $mc->increment($wildcard);
-        $wildcards[$this->bin][$cid][$wildcard]++;
+      $wildcard = dmemcache_key('.wildcard-' . $table . $cid, $table);
+      if (isset($wildcards[$table][$wildcard]) && $wildcards[$table][$wildcard] != 0) {
+         $mc = dmemcache_object($table);
+         $mc->increment($wildcard);
+        $wildcards[$table][$wildcard]++;
       }
       else {
-        $wildcards[$this->bin][$cid][$wildcard] = 1;
-        dmemcache_set('.wildcard-' . $this->bin . $hash, 1, 0, $this->bin);
+        $wildcards[$table][$wildcard] = 1;
+        dmemcache_set('.wildcard-' . $table . $cid, 1, 0, $table);
       }
     }
-    return $wildcards[$this->bin][$cid];
+    return $result;
   }
 
   /**
