Memcached_DataObject stores empty values in the cache

There's great value in knowing that something doesn't exist. We
now cache this information, and carefully compare the results from
cache as $results !== false instead of !empty($results), since some
empty values (null, 0, empty array, empty string) are stored in the
cache.

Caching staticGet() and pkeyGet() now store DB misses in the cache,
and cachedQuery() checks for empty results from the cache.
This commit is contained in:
Evan Prodromou 2010-01-04 10:00:17 -10:00
parent a1821ec8af
commit abc9b33241

View File

@ -19,8 +19,6 @@
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Memcached_DataObject extends DB_DataObject class Memcached_DataObject extends DB_DataObject
{ {
/** /**
@ -57,7 +55,7 @@ class Memcached_DataObject extends DB_DataObject
unset($i); unset($i);
} }
$i = Memcached_DataObject::getcached($cls, $k, $v); $i = Memcached_DataObject::getcached($cls, $k, $v);
if ($i) { if ($i !== false) { // false == cache miss
return $i; return $i;
} else { } else {
$i = DB_DataObject::factory($cls); $i = DB_DataObject::factory($cls);
@ -69,6 +67,12 @@ class Memcached_DataObject extends DB_DataObject
$i->encache(); $i->encache();
return $i; return $i;
} else { } else {
// save the fact that no such row exists
$c = self::memcache();
if (!empty($c)) {
$ck = self::cachekey($cls, $k, $v);
$c->set($ck, null);
}
return false; return false;
} }
} }
@ -77,10 +81,13 @@ class Memcached_DataObject extends DB_DataObject
function &pkeyGet($cls, $kv) function &pkeyGet($cls, $kv)
{ {
$i = Memcached_DataObject::multicache($cls, $kv); $i = Memcached_DataObject::multicache($cls, $kv);
if ($i) { if ($i !== false) { // false == cache miss
return $i; return $i;
} else { } else {
$i = new $cls(); $i = DB_DataObject::factory($cls);
if (empty($i)) {
return false;
}
foreach ($kv as $k => $v) { foreach ($kv as $k => $v) {
$i->$k = $v; $i->$k = $v;
} }
@ -88,6 +95,11 @@ class Memcached_DataObject extends DB_DataObject
$i->encache(); $i->encache();
} else { } else {
$i = null; $i = null;
$c = self::memcache();
if (!empty($c)) {
$ck = self::multicacheKey($cls, $kv);
$c->set($ck, null);
}
} }
return $i; return $i;
} }
@ -220,16 +232,22 @@ class Memcached_DataObject extends DB_DataObject
function multicache($cls, $kv) function multicache($cls, $kv)
{ {
ksort($kv); ksort($kv);
$c = Memcached_DataObject::memcache(); $c = self::memcache();
if (!$c) { if (!$c) {
return false; return false;
} else { } else {
$pkeys = implode(',', array_keys($kv)); return $c->get(self::multicacheKey($cls, $kv));
$pvals = implode(',', array_values($kv));
return $c->get(Memcached_DataObject::cacheKey($cls, $pkeys, $pvals));
} }
} }
static function multicacheKey($cls, $kv)
{
ksort($kv);
$pkeys = implode(',', array_keys($kv));
$pvals = implode(',', array_values($kv));
return self::cacheKey($cls, $pkeys, $pvals);
}
function getSearchEngine($table) function getSearchEngine($table)
{ {
require_once INSTALLDIR.'/lib/search_engines.php'; require_once INSTALLDIR.'/lib/search_engines.php';
@ -264,7 +282,8 @@ class Memcached_DataObject extends DB_DataObject
$key_part = common_keyize($cls).':'.md5($qry); $key_part = common_keyize($cls).':'.md5($qry);
$ckey = common_cache_key($key_part); $ckey = common_cache_key($key_part);
$stored = $c->get($ckey); $stored = $c->get($ckey);
if ($stored) {
if ($stored !== false) {
return new ArrayWrapper($stored); return new ArrayWrapper($stored);
} }