Interleaving numbers
Posted on November 25th, 2010 in Code Repository | 1 Comment »
When you have two numbers that need to be indexed together for speedy lookups there are a variety of mechanisms that can be used, a fast and efficient mechanism is called the Morton Interleave.
/**
* Calculate a Morton Interleave for two numbers.
*
* @param int $x The first number
* @param int $y The second number
* @return int The Morton Interleave
* @author Aidan Lister <aidan@php.net>
* @link http://aidanlister.com/2010/11/interleaving-numbers/
*/
function interleave($x, $y) {
$result = 0;
$position = 0;
$bit = 1;
while ($bit <= $x || $bit <= $y) {
if ($bit & $x)
$result |= 1 << (2*$position+1);
if ($bit & $y)
$result |= 1 << (2*$position);
$position += 1;
$bit = 1 << $position;
}
return $result;
}
A common use case for the interleave is storing a conversation between two users. For example, to retrieve all messages between user 231 and user 119 one would normally query the database with WHERE (sender_id=231 AND receiver_id=119) OR (sender_id=119 AND receiver_id=231).
When using an interleave field, you could do something like WHERE conversation_id=48447. The number 48447 being the interleave, calculated as:
$uids = array(231, 119); interleave(max($uids), min($uids));
This means faster queries and cleaner code!
One Response
Hey There. I discovered your weblog the use of msn. That is a really well written article. I will be sure to bookmark it and come back to learn extra of your helpful information. Thank you for the post. I’ll definitely return.