Log-Parallel

 view release on metacpan or  search on metacpan

lib/Log/Parallel/Geo/IP.pm  view on Meta::CPAN

		if (length($new) > $cc_file_min_size) {
			write_file("$cc_file_location.tmp", $new);
			rename("$cc_file_location.tmp", $cc_file_location) or die;
		} else {
			my $l = int(length($new)/1024);
			die "IP->country code database isn't big enough (${l}K)";
		}
	}
}

my $ccdata;

my $tries = 0;

#
# Portions of this function are copied from David Sharnoff's
# readfancylog() function in his ccserver program.
#
sub read_data
{
	my ($handle, $val, $pos) = @_;
	die if $tries++ > 40;
	if (defined $pos) {
		pos($ccdata) = $pos;
		$ccdata =~ /\G.*?\n(?=(?:"\d|\z))/gcs;
	}

	$pos = pos($ccdata);

	$ccdata =~ /\G(.*?)\n(?=(?:"\d|\z))/gcs or return (-1, $pos);
	my $line = $1;

	# "4177526784","4194303999","iana","410227200","ZZ","ZZZ","Reserved"

	$line =~ /"(\d+)","(\d+)",".*?","\d+",".*?",".*?",".*?"/;
	return (-1, $pos) if $val < $1;
	return (1, $pos) if $val > $2;
	return (0, $pos);
}

# $pos = binary_search($min, $max, $val, $read, $handle, [$size]);

my $num255_rx = qr/(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)/;
my $ip_rx = qr/$num255_rx\.$num255_rx\.$num255_rx\.$num255_rx/;

sub ip2cc
{
	my ($ip) = @_;

	unless ($ccdata) {
		open my $cc, "-|", "zcat", "-f", $cc_file_location or die;
		local($/) = undef;
		$ccdata = <$cc>;
		$ccdata =~ s/^.*?\n"/\n\n"/s;
	}

	$tries = 0;
	$ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ or die;

	my $val = $4 + $3 * 256 + $2 * 65536 + $1 * (256*256*256);

	my $pos = binary_search(0, length($ccdata), $val, \&read_data, 0, 40);
	return undef unless $pos;

	pos($ccdata) = $pos;
	$ccdata =~ /\G(.*?)\n(?=(?:"\d|\z))/gcs or return undef;
	my $line = $1;
	$line =~ /"\d+","\d+",".*?","\d+","(.*?)","(.*?)","(.*?)"/ or die;

	return $1 unless wantarray;
	return ($1, $2, $3);
}

my $ccfd;
my $last_line;
my $last_begin;



( run in 0.646 second using v1.01-cache-2.11-cpan-454fe037f31 )