Mailing List Archive

Randompage bug
Hello,

I found a bug in the special:Randompage, it goes like this:

The algorithm picks a random number, then checks in the database for a page
with a higher cur_random (a random value given to each page), and takes the
first page that matches. The problem with this is I only have 2 pages, both
with a very low cur_random value. So often I get redirected to an empty page
(404). I don't know if there's a way to fix this, or a workaround (other
than "make more pages")? Maybe, instead of doing '$rt = "" ' in the else,
you could do another query, but this time with "AND cur_random < $randstr
AND cur_random > 0" (to avoid the homepage).

Final code: (in includes/SpecialRandompage.php)
...
} else {
$sqlget = "SELECT cur_id,cur_title
FROM cur USE INDEX (cur_random)
WHERE cur_namespace=0 AND cur_is_redirect=0
AND cur_random<$randstr
AND cur_random > 0
ORDER BY cur_random DESC
LIMIT 1";
$res = wfQuery( $sqlget, DB_READ, $fname );
if( $s = wfFetchObject( $res ) ) {
$rt = wfUrlEncode( $s->cur_title );
} else {
# No articles?!
$rt = "";
}
}
...

This solution isn't good, it takes nearly always the same page. There should
be a better way :-)


And I also have a problem when I edit a page, then press Save. I get told
there was a conflicting error, but when I return to the page, the update has
been done. I think it's some problem with my session-things (I'm using a
windows webserver, not apache).

Any comments?
Tom
Re: Randompage bug [ In reply to ]
> Hello,
>
> I found a bug in the special:Randompage, it goes like this:

blablah :-)

Sorry to bother you again, I searched google for "mysql random row", guess
what..

Code: (Still in includes/SpecialRandompage.php)

function wfSpecialRandompage()
{
global $wgOut, $wgTitle, $wgArticle, $force;
$fname = "wfSpecialRandompage";

wfSeedRandom();
$result=wfQuery("SELECT cur_title FROM cur WHERE cur_namespace = 0 and
cur_is_redirect=0 and cur_random > 0", DB_READ, $fname);
$min=1;
$max=wfNumRows($result);
if ($max > 0) {
wfDataSeek($result,rand($min,$max)-1);
if ($row = wfFetchObject($result)) {
$rt = wfUrlEncode($row -> cur_title);
}
else {
$rt = "";
}
}
else {
$rt = "";
}
$wgOut->reportTime(); # for logfile
$wgOut->redirect( wfLocalUrl( $rt ) );
}


As you can see, it takes a random tuple from the ones returned by the query.

Thanks for reading all this,
Tom
Re: Randompage bug [ In reply to ]
Tom Muylle wrote:
> $result=wfQuery("SELECT cur_title FROM cur WHERE cur_namespace = 0 and
> cur_is_redirect=0 and cur_random > 0", DB_READ, $fname);
> $min=1;
> $max=wfNumRows($result);
> if ($max > 0) {
> wfDataSeek($result,rand($min,$max)-1);
[snip]
> As you can see, it takes a random tuple from the ones returned by the query.

The trouble with this would be that mysql would collect hundreds of
thousands of titles (on our largest wikis) and send them all back to
PHP. That's a lot of unnecessary overhead for just one title!

On my test box with a copy of en.wikipedia.org:

mysql> select count(cur_title) from cur where cur_namespace=0 and
cur_is_redirect=0 and cur_random > 0;
+------------------+
| count(cur_title) |
+------------------+
| 287328 |
+------------------+
1 row in set (1 min 7.04 sec)

Having a precalculated random index makes it a very very fast easy
operation, where the database's index on a constant lets us get to a
random position without such fuss.

I'm sorry it's not optimized for the case where you have two pages. :)

You shouldn't be receiving a 404 page, though, you should just get the
main page if there's nothing else. Can you demonstrate this exactly?

-- brion vibber (brion @ pobox.com)
Re: Randompage bug [ In reply to ]
Hehe, you're right, sending all the data back was stupid.. Never thought
about it :(
It gave me a 404 or some other error (the page didn't load actually) because
this variable wasn't set correctly in my settings-file: $wgScriptPath =
"/wiki";
I fixed the path and now it works. Just too bad it's not always a page
different from the main page. Oh well, i can live with it.

Thanks for the reply,
Tom