From d0520bef02658d1365cc54a9546a52a2a09339d3 Mon Sep 17 00:00:00 2001 From: Marius Hoch Date: Thu, 18 Oct 2012 17:07:08 +0200 Subject: [PATCH] (bug 41171) Refactor User::edits() and User::incEditCount() User::edits() lets you fetch a cached number of edits from a slave database. in case the field is not yet filed, we initialize if by hitting the `revision` table and saving the result in user_editcount. User::incEditCount() updates the edit countr and also does a lazy initialization, if needed. As both methods use the same $dbw->update() statement for this, I've created a new, protected initEditCount() function which can take care of that. Change-Id: If111270a84d4278bc4ea14d32ae602069f7c276f --- includes/User.php | 65 +++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/includes/User.php b/includes/User.php index 809c18385c..8df9ea71bb 100644 --- a/includes/User.php +++ b/includes/User.php @@ -2454,18 +2454,7 @@ class User { if( $count === null ) { // it has not been initialized. do so. - $dbw = wfGetDB( DB_MASTER ); - $count = $dbr->selectField( - 'revision', 'count(*)', - array( 'rev_user' => $this->mId ), - __METHOD__ - ); - $dbw->update( - 'user', - array( 'user_editcount' => $count ), - array( 'user_id' => $this->mId ), - __METHOD__ - ); + $count = $this->initEditCount(); } wfProfileOut( __METHOD__ ); $this->mEditCount = $count; @@ -3940,43 +3929,63 @@ class User { public function incEditCount() { if( !$this->isAnon() ) { $dbw = wfGetDB( DB_MASTER ); - $dbw->update( 'user', + $dbw->update( + 'user', array( 'user_editcount=user_editcount+1' ), array( 'user_id' => $this->getId() ), - __METHOD__ ); + __METHOD__ + ); // Lazy initialization check... if( $dbw->affectedRows() == 0 ) { - // Pull from a slave to be less cruel to servers - // Accuracy isn't the point anyway here - $dbr = wfGetDB( DB_SLAVE ); - $count = $dbr->selectField( 'revision', - 'COUNT(rev_user)', - array( 'rev_user' => $this->getId() ), - __METHOD__ ); - // Now here's a goddamn hack... + $dbr = wfGetDB( DB_SLAVE ); if( $dbr !== $dbw ) { // If we actually have a slave server, the count is // at least one behind because the current transaction // has not been committed and replicated. - $count++; + $this->initEditCount( 1 ); } else { // But if DB_SLAVE is selecting the master, then the // count we just read includes the revision that was // just added in the working transaction. + $this->initEditCount(); } - - $dbw->update( 'user', - array( 'user_editcount' => $count ), - array( 'user_id' => $this->getId() ), - __METHOD__ ); } } // edit count in user cache too $this->invalidateCache(); } + /** + * Initialize user_editcount from data out of the revision table + * + * @param $add Integer Edits to add to the count from the revision table + * @return Integer Number of edits + */ + protected function initEditCount( $add = 0 ) { + // Pull from a slave to be less cruel to servers + // Accuracy isn't the point anyway here + $dbr = wfGetDB( DB_SLAVE ); + $count = $dbr->selectField( + 'revision', + 'COUNT(rev_user)', + array( 'rev_user' => $this->getId() ), + __METHOD__ + ); + $count = $count + $add; + + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'user', + array( 'user_editcount' => $count ), + array( 'user_id' => $this->getId() ), + __METHOD__ + ); + + return $count; + } + /** * Get the description of a given right * -- 2.20.1