Algorithm-SkipList
view release on metacpan or search on metacpan
lib/Algorithm/SkipList.pm view on Meta::CPAN
} else { # key1 = key2
$node1 = $node1->header()->[0],
if $node1;
$node2 = $node2->header()->[0],
if $node2;
}
}
}
sub append {
my $list1 = shift;
my $list2 = shift;
unless (defined $list2) { return; }
my $node = $list1->_greatest_node;
if ($node) {
my ($next) = $list2->_first_node;
if ($list1->list->level > $list2->list->level) {
if ($list1->list->level < $list1->max_level) {
my $i = $list1->list->level;
while (!defined $list1->list->header()->[$i]) { $i--; }
$list1->list->header()->[$i+1] = $next;
} else {
my $i = $list1->list->level-1;
my $x = $list1->list->header()->[$i];
while (defined $x->header()->[$i]) {
$x = $x->header()->[$i];
}
$x->header()->[$i] = $next;
}
$node->header()->[0] = $next;
} else {
for (my $i=0; $i<$node->level; $i++) {
$node->header()->[$i] = $next;
}
for (my $i=$list1->list->level; $i<$list2->list->level; $i++) {
$list1->list->header()->[$i] = $next;
}
}
$list1->{SIZE} += $list2->size;
$list1->{LIST_END} = $list2->{LIST_END};
} else {
$list1->{LIST} = $list2->list;
$list1->{SIZE} = $list2->size;
$list1->{LIST_END} = $list2->{LIST_END};
}
$list1->_adjust_level_threshold;
}
sub _node_by_index {
my ($self, $index) = @_;
# Bug: for some reason, change $[ does not affect this module.
# if ($index >= $[) {
# $index -= $[;
# }
if ($index < 0) {
$index += $self->size;
}
if (($index < 0) || ($index >= $self->size)) {
carp "index out of range", if (warnings::enabled);
return;
}
my ($node, $last_index) = @{ $self->{LASTKEY} || [ ] };
if ((defined $last_index) && ($last_index <= $index)) {
($last_index, $index) = ($index, $index - $last_index);
}
else {
$last_index = $index;
$node = undef;
}
$node ||= $self->_first_node;
unless ($node) {
return;
}
while ($node && $index--) {
$node = $node->header()->[0];
}
$self->last_key( $node, $last_index );
return $node;
}
sub key_by_index {
my ($self, $index) = @_;
my $node = $self->_node_by_index($index);
if ($node) {
return $node->key;
} else {
return;
}
}
sub value_by_index {
my ($self, $index) = @_;
my $node = $self->_node_by_index($index);
if ($node) {
return $node->value;
} else {
return;
}
}
sub index_by_key {
my ($self, $key) = @_;
( run in 0.698 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )