From d5d80ecd011b216ff70a52302137357f886ddbdf Mon Sep 17 00:00:00 2001 From: Gabriel Wicke Date: Fri, 13 May 2005 21:18:45 +0000 Subject: [PATCH] Incremental categorylink updates, mainly to keep the old timestamp. Timestamp saved in memcached, to allow checking for updates without contacting the db. Might be possible to improve further using the linkscache, i tried but didn't succeed. As-is it should still be faster than the unconditional full deletion/re-addition cycle. --- includes/LinksUpdate.php | 50 +++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php index c161a33c8d..f57b229349 100644 --- a/includes/LinksUpdate.php +++ b/includes/LinksUpdate.php @@ -145,25 +145,63 @@ class LinksUpdate { #------------------------------------------------------------------------------ # Category links if( $wgUseCategoryMagic ) { - $sql = "DELETE FROM $categorylinks WHERE cl_from='{$this->mId}'"; - $dbw->query( $sql, $fname ); + global $messageMemc, $wgDBname; # Get addition list $add = $wgLinkCache->getCategoryLinks(); - # Do the insertion - $sql = ''; - if ( 0 != count ( $add ) ) { + # select existing catlinks for this page + $res = $dbw->select( $categorylinks, array( 'cl_to' ), array( 'cl_from' => $this->mId ), + $fname, 'FOR UPDATE' ); + + $del = array(); + if(0 != $dbw->numRows( $res )) { + while ( $row = $dbw->fetchObject( $res ) ) { + if(!isset($add[$row->cl_to])) { + // in the db, but no longer in the page -> delete + $del[] = $row->cl_to; + } else { + // remove already existing category memberships + // from the add array + unset($add[$row->cl_to]); + } + } + } + // delete any removed categorylinks + if(count($del) > 0) { + // delete old ones + $sql = "DELETE FROM $categorylinks WHERE cl_from='{$this->mId}' AND cl_to IN('"; + $sql .= implode("','", $del) . "')"; + $dbw->query( $sql, $fname ); + foreach($del as $cname){ + $nt = Title::makeTitle( NS_CATEGORY, $cname ); + $nt->invalidateCache(); + // update the timestamp which indicates when the last article + // was added or removed to/from this article + $key = $wgDBname.':Category:'.$nt->getDBkey().':adddeltimestamp'; + $messageMemc->set( $key , wfTimestamp( TS_MW ), 24*3600 ); + #wfDebug( "Linksupdate:Cats:del: ".serialize($nt)." $key \n" ); + } + } + // add any new category memberships + if (count($add) > 0) { $arr = array(); foreach( $add as $cname => $sortkey ) { $nt = Title::makeTitle( NS_CATEGORY, $cname ); if( !$nt ) continue; $nt->invalidateCache(); + // update the timestamp which indicates when the last article + // was added or removed to/from this article + $key = $wgDBname.':Category:'.$nt->getDBkey().':adddeltimestamp'; + $messageMemc->set( $key , wfTimestamp( TS_MW ), 24*3600 ); + #wfDebug( "Linksupdate:Cats:add: ".serialize($nt)." $key\n" ); + #wfDebug( "LU-get: ".$messageMemc->get( $key)."\n"); array_push( $arr, array( 'cl_from' => $this->mId, 'cl_to' => $cname, 'cl_sortkey' => $sortkey ) ); } + // do the actual sql insertion $dbw->insert( 'categorylinks', $arr, $fname, array( 'IGNORE' ) ); } } @@ -296,4 +334,4 @@ class LinksUpdate { $dbw->delete( 'brokenlinks', array( 'bl_to' => $this->mTitle ), $fname ); } } -?> \ No newline at end of file +?> -- 2.20.1