Algorithm-HyperLogLog
view release on metacpan or search on metacpan
0.14 Sat Apr 14 03:30:00 2013
- Change required perl version
- Add $VERSION to Algorithm/HyperLogLog/PP.pm
0.11 Fri Apr 05 01:40:00 2013
- XSLoader is loaded when runtime
0.10 Wed Apr 03 22:15:00 2013
- [enhancement] register dump/restore feature
- [bugfix] hash calculation error in big endian environment
0.05 Wed Mar 27 23:30:00 2013
- Fixed: integer overflow in 32bit environment
0.04 Sat Mar 23 01:50:00 2013
- Fixed: unportable tests
0.03 Thu Mar 21 03:15:00 2013
- Remove unnecessary code in XS
lib/Algorithm/HyperLogLog.pm view on Meta::CPAN
$PERL_ONLY = !eval { XSLoader::load( __PACKAGE__, $VERSION ); };
}
if ($PERL_ONLY) {
require 'Algorithm/HyperLogLog/PP.pm';
}
}
sub new_from_file {
my ( $class, $filename ) = @_;
open my $fh, '<', $filename or die $!;
my $on_error = sub { close $fh; croak "Invalid dump file($filename)"; };
binmode $fh;
my ( @dumpdata, $buf, $readed );
# Read register size data
$readed = read( $fh, $buf, 1 );
$on_error->() if $readed != 1;
my $k = unpack 'C', $buf;
# Read register content data
my $m = 2**$k;
$readed = read $fh, $buf, $m;
$on_error->() if $readed != $m;
close $fh;
@dumpdata = unpack 'C*', $buf;
my $self = $class->_new_from_dump( $k, \@dumpdata );
return $self;
}
sub dump_to_file {
my ( $self, $filename ) = @_;
my $k = log( $self->register_size ) / log(2); # Calculate log2(register_size)
my $dumpdata = $self->_dump_register();
t/02_basic.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use Test::Fatal qw(exception lives_ok);
use Algorithm::HyperLogLog;
use Algorithm::HyperLogLog::PP;
plan skip_all => 'No XS' unless Algorithm::HyperLogLog->XS;
my $error_sum = 0;
my $repeat = 100;
for ( 1 .. $repeat ) {
my $hll = Algorithm::HyperLogLog->new(16);
my $hllpp = Algorithm::HyperLogLog::PP->new(16);
my %unique = ( q{} => 1 );
for ( 0 .. 999 ) {
t/02_basic.t view on Meta::CPAN
ok 1, 'XS and PP compatibility test';
}
else {
diag $cardinality;
diag $cardinalitypp;
fail();
}
my $unique = scalar keys %unique;
$error_sum += abs( $unique - $cardinality );
}
my $error_avg = $error_sum / $repeat;
my $error_ratio = $error_avg / 10001 * 100;
ok $error_ratio < 1.0, 'Error ratio less than 1.0%';
done_testing();
sub random_string {
my $n = shift;
my $str = q{};
for ( 1 .. $n ) {
my $rand = rand(26);
$str .= chr( ord('A') + $rand );
}
BEGIN {
$Algorithm::HyperLogLog::PERL_ONLY = 1;
}
use Algorithm::HyperLogLog;
my $hll = Algorithm::HyperLogLog->new(16);
isa_ok $hll, 'Algorithm::HyperLogLog';
ok !$hll->XS, 'is Pure Perl?';
my $error_sum = 0;
my $repeat = 100;
for ( 1 .. $repeat ) {
my %unique;
for ( 0 .. 999 ) {
my $str = q{};
while ( exists $unique{$str} ) {
$str = random_string(10);
}
$unique{$str} = 1;
}
$hll->add( keys %unique );
my $num = scalar keys %unique;
my $error_sum += abs( $num - $hll->estimate() );
}
my $error_avg = $error_sum / $repeat;
my $error_ratio = $error_avg / 1000 * 100;
ok $error_ratio < 1;
done_testing();
sub random_string {
my $n = shift;
my $str = q{};
for ( 1 .. $n ) {
my $rand = rand(26);
$str .= chr( ord('A') + $rand );
}
( run in 0.722 second using v1.01-cache-2.11-cpan-65fba6d93b7 )