I am trying to use the Set::IntervalTree
module and I think it is giving me the same node pointers if I insert the elements in a loop.
If I insert them outside a loop sequentially one after the another the nodes are inserted fine and the find
/ find_window
calls works perfectly. But on the nodes which were added in the loop, the find functions give strange results.
#!/usr/bin/perl
use Set::IntervalTree;
my $tree = Set::IntervalTree->new;
$tree->insert("60:70", 60, 70);
$tree->insert("70:80", 70, 80);
$tree->insert("80:90", 80, 90);
for(my $i = 0; $i < 60; $i=$i+10)
{
$j = $i+10;
print "$i".":"."$j\n";
$tree->insert("$i".":"."$j", $i, $i+10);
}
print $tree->str;
my $results1 = $tree->fetch(25, 28);
my $window = $tree->fetch_window(25,250);
my @arr1 = @$results1;
print " @arr1 found.\n";
my $results2 = $tree->fetch(65, 68);
my @arr2 = @$results2;
print " @arr2 found.\n";
This is the output. Check the node pointers.. the ones added from the loop have same pointers and they return wrong interval (which i guess is due to the same pointer values.)
Node:0x9905b20, k=0, h=9, mH=9 l->key=NULL r->key=NULL p->key=10 color=BLACK
Node:0x9905b20, k=10, h=19, mH=29 l->key=0 r->key=20 p->key=30 color=RED
Node:0x9905b20, k=20, h=29, mH=29 l->key=NULL r->key=NULL p->key=10 color=BLACK
Node:0x9905b20, k=30, h=39, mH=89 l->key=10 r->key=70 p->key=NULL color=BLACK
Node:0x9905b20, k=40, h=49, mH=49 l->key=NULL r->key=NULL p->key=50 color=RED
Node:0x9905b20, k=50, h=59, mH=69 l->key=40 r->key=60 p->key=70 color=BLACK
Node:0x98c6270, k=60, h=69, mH=69 l->key=NULL r->key=NULL p->key=50 color=RED
Node:0x98fd138, k=70, h=79, mH=89 l->key=50 r->key=80 p->key=30 color=RED
Node:0x98fd078, k=80, h=89, mH=89 l->key=NULL r->key=NULL p->key=70 color=BLACK
50:60 found.
60:70 found.
It looks like you have to use a Perl scalar variable if you are calling insert
from an inner block. If you use an interpolated string it will be discarded and overwritten by the subsequent execution of the block.
This code seems to work fine. Please always use strict
and use warnings
on all your programs - particularly those you are asking for help with.
#!/usr/bin/perl
use strict;
use warnings;
use Set::IntervalTree;
my $tree = Set::IntervalTree->new;
for (my $i = 0; $i <= 80; $i += 10) {
my $name = sprintf '%02d:%02d', $i, $i+10;
$tree->insert($name, $i, $i+10);
}
my $results1 = $tree->fetch(25, 28);
print "@$results1 found\n";
my $results2 = $tree->fetch(65, 68);
print "@$results2 found\n";
output
20:30 found
60:70 found