From d918ee95f482bc3fc67160c4272e97ad1e0c2412 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 2 Aug 2011 18:13:56 -0400 Subject: [PATCH] pre-fetch groups for notices --- classes/Notice.php | 82 +++++++++++++++++++++++++---------- lib/filteringnoticestream.php | 12 +++-- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index 918190a24c..573437caef 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1408,6 +1408,9 @@ class Notice extends Memcached_DataObject * * @return array of Group objects */ + + protected $_groups = -1; + function getGroups() { // Don't save groups for repeats @@ -1415,31 +1418,29 @@ class Notice extends Memcached_DataObject if (!empty($this->repeat_of)) { return array(); } - - $ids = array(); - - $keypart = sprintf('notice:groups:%d', $this->id); - - $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)); + + if ($this->_groups != -1) + { + return $this->_groups; } - + + $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); - 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() { $vars = parent::__sleep(); - $skip = array('_original', '_profile'); + $skip = array('_original', '_profile', '_groups'); return array_diff($vars, $skip); } @@ -2503,4 +2504,39 @@ class Notice extends Memcached_DataObject 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); + } + } } diff --git a/lib/filteringnoticestream.php b/lib/filteringnoticestream.php index f412211074..267955dfd9 100644 --- a/lib/filteringnoticestream.php +++ b/lib/filteringnoticestream.php @@ -81,9 +81,15 @@ abstract class FilteringNoticeStream extends NoticeStream break; } - while ($raw->fetch()) { - if ($this->filter($raw)) { - $filtered[] = clone($raw); + $notices = $raw->fetchAll(); + + // 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) { break; }