Perhaps this could be done a bit more efficiently, I'm not sure.use strict; use warnings; package FastRanges; sub new($$$) { my $class = shift; my $max_length = shift; my $ranges_a = shift; my @lookup; for ( @{$ranges_a} ) { my ( $start, $end ) = @$_; my @idx = $end >= $start ? $start .. $end : ( $start .. $max_length, 1 .. $end ); for my $i (@idx) { $lookup[$i] .= pack 'L', $end } } bless \@lookup, $class; } sub num_ranges_containing($$$) { my $self = shift; my ( $start, $end ) = @_; # query range coordinates return 0 unless ( defined $self->[$start] ) ; # no ranges overlap the start position of the query if ( $end >= $start ) { # query range is simple # any inverted range in {LOOKUP}[$start] must contain it, # and so does any simple range which ends at or after $end return 0 + grep { $_ < $start or $end <= $_ } unpack 'L*', $self->[$start]; } else { # query range is inverted # only inverted ranges in {LOOKUP}[$start] which also end # at of after $end contain it. simple ranges can't contain # the query range return 0 + grep { $_ < $start and $end <= $_ } unpack 'L*', $self->[$start]; } } 1;
Thanks for noting the bug, BrowserUK! I'm sure you saved me a lot of future frustration.
And if you indeed think it now works and also pretty much optimized, I'd be happy to get some ideas for the original question.
In reply to Re^6: Serializing a large object
by daverave
in thread Serializing a large object
by daverave
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |