use strict; use warnings; use diagnostics; use Data::Dumper; my @buffer = qw[a b c d e f 0 1 2]; my $bufsize = 6; my $diff = 2 * $bufsize - scalar(@buffer); my @smallbuf; my $writes = 0; my $source = 0; my $chainfrom = 0; push @smallbuf, $buffer[$source]; while ($writes < scalar(@buffer)) { my $dest = $source < $bufsize ? $source + $bufsize - $diff : $source - $bufsize; push @smallbuf, $buffer[$dest]; $buffer[$dest] = $smallbuf[0]; $writes++; shift @smallbuf; if ($dest == $chainfrom) { $chainfrom++; $source = $chainfrom; $smallbuf[0] = $buffer[$chainfrom]; } else { $source = $dest; } } print Dumper @buffer;