In Special:AllPages, limit the size of hierarchical lists
authorTim Starling <tstarling@wikimedia.org>
Mon, 11 Nov 2013 02:35:43 +0000 (13:35 +1100)
committerOri Livneh <ori@wikimedia.org>
Wed, 13 Nov 2013 00:02:43 +0000 (16:02 -0800)
Traversal of the entire page list by spidering the top levels is thought
to require O(N^3) DB CPU time where N is the number of pages on the
wiki. So introduce a limit for the size of such lists, as measured by
the pre-existing estimateRowCount().

Bug: 56840
Change-Id: I189ba71de869496a36f49283ec6dce7bbdfccd73

includes/specials/SpecialAllpages.php

index a082049..388705d 100644 (file)
@@ -49,6 +49,16 @@ class SpecialAllpages extends IncludableSpecialPage {
         */
        protected $maxPageLength = 70;
 
+       /**
+        * Maximum number of pages in a hierarchical ("top level") list.
+        *
+        * Traversal of the entire page list by spidering the top levels is thought
+        * to require O(N^3) DB CPU time where N is the number of pages on the wiki.
+        * See bug 56840. If this limit is exceeded, the behaviour becomes like a
+        * simple alphabetic pager.
+        */
+       protected $maxTopLevelPages = 50000;
+
        /**
         * Determines, which message describes the input field 'nsfrom'.
         *
@@ -201,6 +211,14 @@ class SpecialAllpages extends IncludableSpecialPage {
                $lines = $wgMemc->get( $key );
 
                $count = $dbr->estimateRowCount( 'page', '*', $where, __METHOD__ );
+
+               // Don't show a hierarchical list if the number of pages is very large,
+               // since generating it will cause a lot of scanning
+               if ( $count > $this->maxTopLevelPages ) {
+                       $this->showChunk( $namespace, $from, $to, $hideredirects );
+                       return;
+               }
+
                $maxPerSubpage = intval( $count / $this->maxLineCount );
                $maxPerSubpage = max( $maxPerSubpage, $this->maxPerPage );