#!/usr/bin/perl
# Compares node distances in memory for different layouts of the following
# binary tree:
# A
# / \
# B C
# / \ / \
# D E F G
# / \ / \ / \ / \
# H I J K L M N O
# / \ / \ / \ / \ / \ / \ / \ / \
# P Q R S T U V W X Y Z 0 1 2 3 4
# Calculates the real node distance.
sub dist($$)
{
my ($i, $j) = @_;
($j,$i) = ($i,$j) if ($i > $j);
# $i<$j. Go one up from the larger node.
return 1 + dist
($i, ($j-1)>>1); }
# Determines the average memory distance for nodes as a function of tree distance.
sub get_dists($$)
{
my $tree = shift; # Original tree ordering my $locality = shift; # Locality-based ordering
my %dists = ();
my %counts = ();
for (my $i=0; $i<length($tree); $i++) {
for (my $j=$i; $j<length($tree); $j++) {
# Find location of $i and $j in the locality-based ordering.
my $ni = substr($tree, $i, 1); my $nj = substr($tree, $j, 1); my $it = index($locality, $ni); my $jt = index($locality, $nj); my $d = (($i <= $j) ? ($j-$i) : ($i-$j));
my $dt = (($it <= $jt) ? ($jt-$it) : ($it-$jt));
my $treedist = dist($i, $j);
$dists{$treedist} += $dt;
$counts{$treedist}++;
}
}
{
$dists{$k} /= $counts{$k};
}
}
my $tree = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"; # original (breadth-first prefix) ordering
my $prefix = "ABDHPQIRSEJTUKVWCFLXYMZ0GN12O34"; # depth-first prefix ordering
my $infix = "PHQDRISBTJUEVKWAXLYFZM0C1N2G3O4"; # infix ordering
my $veb = "ABCDHPQIRSEJTUKVMFLXYMZ0GN12O34"; # V.E.B. layout (hope I got it right)
my %original_dists = get_dists($tree, $tree);
my %prefix_dists = get_dists($tree, $prefix);
my %infix_dists = get_dists($tree, $infix);
my %veb_dists = get_dists($tree, $veb);
print "set key top left;\n"; print "set title 'Locality ratios';\n"; print "set xlabel 'tree distance';\n"; print "set ylabel 'avg. memory distance';\n";
print "plot '-' w lp title 'original', '-' w lp title 'prefix ordering', '-' w lp title 'infix ordering', '-' w lp title 'van-Emde-Boas layout';\n";
foreach my $k (sort keys %original_dists) {
print "$k $original_dists{$k}\n"; }
{
print "$k $prefix_dists{$k}\n"; }
{
print "$k $infix_dists{$k}\n"; }
{
print "$k $veb_dists{$k}\n"; }
IyEvdXNyL2Jpbi9wZXJsCiMgQ29tcGFyZXMgbm9kZSBkaXN0YW5jZXMgaW4gbWVtb3J5IGZvciBkaWZmZXJlbnQgbGF5b3V0cyBvZiB0aGUgZm9sbG93aW5nCiMgYmluYXJ5IHRyZWU6CiMgICAgICAgICAgICAgICAgICAgICAgQQojICAgICAgICAgICAgICAgICAgLyAgICAgICBcCiMgICAgICAgICAgICAgIEIgICAgICAgICAgICAgICBDCiMgICAgICAgICAgICAvICAgXCAgICAgICAgICAgLyAgIFwKIyAgICAgICAgICBEICAgICAgIEUgICAgICAgRiAgICAgICBHCiMgICAgICAgICAvIFwgICAgIC8gXCAgICAgLyBcICAgICAvIFwKIyAgICAgICAgSCAgIEkgICBKICAgSyAgIEwgICBNICAgTiAgIE8KIyAgICAgICAvIFwgLyBcIC8gXCAvIFwgLyBcIC8gXCAvIFwgLyBcCiMgICAgICAgUCBRIFIgUyBUIFUgViBXIFggWSBaIDAgMSAyIDMgNAoKIyBDYWxjdWxhdGVzIHRoZSByZWFsIG5vZGUgZGlzdGFuY2UuCnN1YiBkaXN0KCQkKQp7CiAgbXkgKCRpLCAkaikgPSBAXzsKICByZXR1cm4gMCBpZiAoJGkgPT0gJGopOwogICgkaiwkaSkgPSAoJGksJGopIGlmICgkaSA+ICRqKTsKICAjICRpPCRqLiBHbyBvbmUgdXAgZnJvbSB0aGUgbGFyZ2VyIG5vZGUuCiAgcmV0dXJuIDEgKyBkaXN0KCRpLCAoJGotMSk+PjEpOwp9CgojIERldGVybWluZXMgdGhlIGF2ZXJhZ2UgbWVtb3J5IGRpc3RhbmNlIGZvciBub2RlcyBhcyBhIGZ1bmN0aW9uIG9mIHRyZWUgZGlzdGFuY2UuCnN1YiBnZXRfZGlzdHMoJCQpCnsKICBteSAkdHJlZSA9IHNoaWZ0OyAgICAgIyBPcmlnaW5hbCB0cmVlIG9yZGVyaW5nCiAgbXkgJGxvY2FsaXR5ID0gc2hpZnQ7ICMgTG9jYWxpdHktYmFzZWQgb3JkZXJpbmcKCiAgbXkgJWRpc3RzID0gKCk7CiAgbXkgJWNvdW50cyA9ICgpOwoKICBmb3IgKG15ICRpPTA7ICRpPGxlbmd0aCgkdHJlZSk7ICRpKyspCiAgewogICAgZm9yIChteSAkaj0kaTsgJGo8bGVuZ3RoKCR0cmVlKTsgJGorKykKICAgIHsKICAgICAgIyBGaW5kIGxvY2F0aW9uIG9mICRpIGFuZCAkaiBpbiB0aGUgbG9jYWxpdHktYmFzZWQgb3JkZXJpbmcuCiAgICAgIG15ICRuaSA9IHN1YnN0cigkdHJlZSwgJGksIDEpOwogICAgICBteSAkbmogPSBzdWJzdHIoJHRyZWUsICRqLCAxKTsKICAgICAgbXkgJGl0ID0gaW5kZXgoJGxvY2FsaXR5LCAkbmkpOwogICAgICBteSAkanQgPSBpbmRleCgkbG9jYWxpdHksICRuaik7CiAgICAgIG15ICRkID0gKCgkaSA8PSAkaikgPyAoJGotJGkpIDogKCRpLSRqKSk7CiAgICAgIG15ICRkdCA9ICgoJGl0IDw9ICRqdCkgPyAoJGp0LSRpdCkgOiAoJGl0LSRqdCkpOwogICAgICBteSAkdHJlZWRpc3QgPSBkaXN0KCRpLCAkaik7CiAgICAgICRkaXN0c3skdHJlZWRpc3R9ICs9ICRkdDsKICAgICAgJGNvdW50c3skdHJlZWRpc3R9Kys7CiAgICB9CiAgfQogIGZvcmVhY2ggbXkgJGsgKHNvcnQga2V5cyAlY291bnRzKQogIHsKICAgICRkaXN0c3ska30gLz0gJGNvdW50c3ska307CiAgfQogIHJldHVybiAlZGlzdHM7Cn0KCm15ICR0cmVlID0gIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQiOyAgICAjIG9yaWdpbmFsIChicmVhZHRoLWZpcnN0IHByZWZpeCkgb3JkZXJpbmcKbXkgJHByZWZpeCA9ICJBQkRIUFFJUlNFSlRVS1ZXQ0ZMWFlNWjBHTjEyTzM0IjsgICMgZGVwdGgtZmlyc3QgcHJlZml4IG9yZGVyaW5nCm15ICRpbmZpeCA9ICJQSFFEUklTQlRKVUVWS1dBWExZRlpNMEMxTjJHM080IjsgICAjIGluZml4IG9yZGVyaW5nCm15ICR2ZWIgPSAiQUJDREhQUUlSU0VKVFVLVk1GTFhZTVowR04xMk8zNCI7ICAgICAjIFYuRS5CLiBsYXlvdXQgKGhvcGUgSSBnb3QgaXQgcmlnaHQpCgpteSAlb3JpZ2luYWxfZGlzdHMgPSBnZXRfZGlzdHMoJHRyZWUsICR0cmVlKTsKbXkgJXByZWZpeF9kaXN0cyA9IGdldF9kaXN0cygkdHJlZSwgJHByZWZpeCk7Cm15ICVpbmZpeF9kaXN0cyA9IGdldF9kaXN0cygkdHJlZSwgJGluZml4KTsKbXkgJXZlYl9kaXN0cyA9IGdldF9kaXN0cygkdHJlZSwgJHZlYik7CgpwcmludCAic2V0IGtleSB0b3AgbGVmdDtcbiI7CnByaW50ICJzZXQgdGl0bGUgJ0xvY2FsaXR5IHJhdGlvcyc7XG4iOwpwcmludCAic2V0IHhsYWJlbCAndHJlZSBkaXN0YW5jZSc7XG4iOwpwcmludCAic2V0IHlsYWJlbCAnYXZnLiBtZW1vcnkgZGlzdGFuY2UnO1xuIjsKCnByaW50ICJwbG90ICctJyB3IGxwIHRpdGxlICdvcmlnaW5hbCcsICctJyB3IGxwIHRpdGxlICdwcmVmaXggb3JkZXJpbmcnLCAnLScgdyBscCB0aXRsZSAnaW5maXggb3JkZXJpbmcnLCAnLScgdyBscCB0aXRsZSAndmFuLUVtZGUtQm9hcyBsYXlvdXQnO1xuIjsKCmZvcmVhY2ggbXkgJGsgKHNvcnQga2V5cyAlb3JpZ2luYWxfZGlzdHMpCnsKICBwcmludCAiJGsgJG9yaWdpbmFsX2Rpc3RzeyRrfVxuIjsKfQpwcmludCAiZVxuIjsKZm9yZWFjaCBteSAkayAoc29ydCBrZXlzICVwcmVmaXhfZGlzdHMpCnsKICBwcmludCAiJGsgJHByZWZpeF9kaXN0c3ska31cbiI7Cn0KcHJpbnQgImVcbiI7CmZvcmVhY2ggbXkgJGsgKHNvcnQga2V5cyAlaW5maXhfZGlzdHMpCnsKICBwcmludCAiJGsgJGluZml4X2Rpc3RzeyRrfVxuIjsKfQpwcmludCAiZVxuIjsKZm9yZWFjaCBteSAkayAoc29ydCBrZXlzICV2ZWJfZGlzdHMpCnsKICBwcmludCAiJGsgJHZlYl9kaXN0c3ska31cbiI7Cn0KcHJpbnQgImVcbiI7Cgo=