pre-fetch groups for notices

This commit is contained in:
Evan Prodromou 2011-08-02 18:13:56 -04:00
parent 447ae92eca
commit d918ee95f4
2 changed files with 68 additions and 26 deletions

View File

@ -1408,6 +1408,9 @@ class Notice extends Memcached_DataObject
* *
* @return array of Group objects * @return array of Group objects
*/ */
protected $_groups = -1;
function getGroups() function getGroups()
{ {
// Don't save groups for repeats // Don't save groups for repeats
@ -1415,31 +1418,29 @@ class Notice extends Memcached_DataObject
if (!empty($this->repeat_of)) { if (!empty($this->repeat_of)) {
return array(); return array();
} }
$ids = array(); if ($this->_groups != -1)
{
$keypart = sprintf('notice:groups:%d', $this->id); return $this->_groups;
$idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$gi = new Group_inbox();
$gi->selectAdd();
$gi->selectAdd('group_id');
$gi->notice_id = $this->id;
$ids = $gi->fetchAll('group_id');
self::cacheSet($keypart, implode(',', $ids));
} }
$gis = Memcached_DataObject::listGet('Group_inbox', 'notice_id', array($this->id));
foreach ($gis[$this->id] as $gi)
{
$ids[] = $gi->group_id;
}
$groups = User_group::multiGet('id', $ids); $groups = User_group::multiGet('id', $ids);
return $groups->fetchAll(); $this->_groups = $groups->fetchAll();
return $this->_groups;
}
function _setGroups($groups)
{
$this->_groups = $groups;
} }
/** /**
@ -2462,7 +2463,7 @@ class Notice extends Memcached_DataObject
function __sleep() function __sleep()
{ {
$vars = parent::__sleep(); $vars = parent::__sleep();
$skip = array('_original', '_profile'); $skip = array('_original', '_profile', '_groups');
return array_diff($vars, $skip); return array_diff($vars, $skip);
} }
@ -2503,4 +2504,39 @@ class Notice extends Memcached_DataObject
return Memcached_DataObject::pivotGet('Profile', 'id', $ids); return Memcached_DataObject::pivotGet('Profile', 'id', $ids);
} }
static function fillGroups(&$notices)
{
$ids = array();
foreach ($notices as $notice) {
$ids[] = $notice->id;
}
$ids = array_unique($ids);
$gis = Memcached_DataObject::listGet('Group_inbox', 'notice_id', $ids);
common_debug(sprintf("Notice::fillGroups(): got %d results for %d notices", count($gis), count($ids)));
foreach ($gis as $id => $gi)
{
foreach ($gi as $g)
{
$gids[] = $g->group_id;
}
}
$gids = array_unique($gids);
$group = Memcached_DataObject::pivotGet('User_group', 'id', $gids);
foreach ($notices as $notice)
{
$grps = array();
$gi = $gis[$notice->id];
foreach ($gi as $g) {
$grps[] = $group[$g->group_id];
}
$notice->_setGroups($grps);
}
}
} }

View File

@ -81,9 +81,15 @@ abstract class FilteringNoticeStream extends NoticeStream
break; break;
} }
while ($raw->fetch()) { $notices = $raw->fetchAll();
if ($this->filter($raw)) {
$filtered[] = clone($raw); // XXX: this should probably only be in the scoping one.
Notice::fillGroups($notices);
foreach ($notices as $notice) {
if ($this->filter($notice)) {
$filtered[] = $notice;
if (count($filtered) >= $total) { if (count($filtered) >= $total) {
break; break;
} }