X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FPrefix.pm;h=83b0ac40c9b870650db4a436fc5db4264658a1fc;hb=7e3729a9039462c460dae4804f40c0bd506f3423;hp=5733ff0254c689dabde03a16371b1f412b442d48;hpb=8178d787d7cc8040fa8958197582bba5c80e6f59;p=spider.git diff --git a/perl/Prefix.pm b/perl/Prefix.pm index 5733ff02..83b0ac40 100644 --- a/perl/Prefix.pm +++ b/perl/Prefix.pm @@ -3,7 +3,7 @@ # # Copyright (c) - Dirk Koopman G1TLH # -# $Id$ +# # package Prefix; @@ -16,24 +16,47 @@ use DXDebug; use DXUtil; use USDB; use LRU; +use DXBearing; use strict; -use vars qw($VERSION $BRANCH); -$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ ); -$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ || (0,0)); -$main::build += $VERSION; -$main::branch += $BRANCH; - use vars qw($db %prefix_loc %pre $lru $lrusize $misses $hits $matchtotal); $db = undef; # the DB_File handle %prefix_loc = (); # the meat of the info %pre = (); # the prefix list $hits = $misses = $matchtotal = 1; # cache stats -$lrusize = 2000; # size of prefix LRU cache +$lrusize = 5000; # size of prefix LRU cache + +sub init +{ + my $r = load(); + return $r if $r; + + # fix up the node's default country codes + unless (@main::my_cc) { + push @main::my_cc, (61..67) if $main::mycall =~ /^GB/; + push @main::my_cc, qw(EA EA6 EA8 EA9) if $main::mycall =~ /^E[ABCD]/; + push @main::my_cc, qw(I IT IS) if $main::mycall =~ /^I/; + push @main::my_cc, qw(SV SV5 SV9) if $main::mycall =~ /^SV/; + + # catchall + push @main::my_cc, $main::mycall unless @main::my_cc; + } -$lru = LRU->newbase('Prefix', $lrusize); + my @c; + for (@main::my_cc) { + if (/^\d+$/) { + push @c, $_; + } else { + my @dxcc = extract($_); + push @c, $dxcc[1]->dxcc if @dxcc > 1; + } + } + return "\@main::my_cc does not contain a valid prefix or callsign (" . join(',', @main::my_cc) . ")" unless @c; + @main::my_cc = @c; + return undef; +} sub load { @@ -43,61 +66,29 @@ sub load untie %pre; %pre = (); %prefix_loc = (); + $lru->close if $lru; + undef $lru; } # tie the main prefix database - $db = tie(%pre, "DB_File", undef, O_RDWR|O_CREAT, 0664, $DB_BTREE) or confess "can't tie \%pre ($!)"; - my $out = $@ if $@; - do "$main::data/prefix_data.pl" if !$out; - $out = $@ if $@; + eval {$db = tie(%pre, "DB_File", undef, O_RDWR|O_CREAT, 0664, $DB_BTREE);}; + my $out = "$@($!)" if !$db || $@ ; + my $fn = localdata("prefix_data.pl"); + die "Prefix.pm: cannot find $fn, have you run /spider/perl/create_prefix.pl?" unless -e $fn; + + eval {do $fn if !$out; }; + $out .= $@ if $@; + $lru = LRU->newbase('Prefix', $lrusize); return $out; } -sub store +sub loaded { - my ($k, $l); - my $fh = new IO::File; - my $fn = "$main::data/prefix_data.pl"; - - confess "Prefix system not started" if !$db; - - # save versions! - rename "$fn.oooo", "$fn.ooooo" if -e "$fn.oooo"; - rename "$fn.ooo", "$fn.oooo" if -e "$fn.ooo"; - rename "$fn.oo", "$fn.ooo" if -e "$fn.oo"; - rename "$fn.o", "$fn.oo" if -e "$fn.o"; - rename "$fn", "$fn.o" if -e "$fn"; - - $fh->open(">$fn") or die "Can't open $fn ($!)"; - - # prefix location data - $fh->print("%prefix_loc = (\n"); - foreach $l (sort {$a <=> $b} keys %prefix_loc) { - my $r = $prefix_loc{$l}; - $fh->printf(" $l => bless( { name => '%s', dxcc => %d, itu => %d, utcoff => %d, lat => %f, long => %f }, 'Prefix'),\n", - $r->{name}, $r->{dxcc}, $r->{itu}, $r->{cq}, $r->{utcoff}, $r->{lat}, $r->{long}); - } - $fh->print(");\n\n"); - - # prefix data - $fh->print("%pre = (\n"); - foreach $k (sort keys %pre) { - $fh->print(" '$k' => ["); - my @list = @{$pre{$k}}; - my $l; - my $str; - foreach $l (@list) { - $str .= " $l,"; - } - chop $str; - $fh->print("$str ],\n"); - } - $fh->print(");\n"); - undef $fh; - untie %pre; + return $db; } + # what you get is a list that looks like:- # # prefix => @list of blessed references to prefix_locs @@ -140,6 +131,7 @@ sub next sub lru_put { my ($call, $ref) = @_; + $call =~ s/^=//; my @s = USDB::get($call); if (@s) { @@ -215,12 +207,26 @@ sub extract LM: foreach $call (split /,/, $calls) { - # first check if the whole thing succeeds either because it is cached - # or because it simply is a stored prefix as callsign (or even a prefix) $matchtotal++; $call =~ s/-\d+$//; # ignore SSIDs - my $p = $lru->get($call); my @nout; + my $ecall = "=$call"; + + # first check if this is a call (by prefixing it with an = sign) + my $p = $lru->get($ecall); + if ($p) { + $hits++; + if (isdbg('prefix')) { + my $percent = sprintf "%.1f", $hits * 100 / $misses; + dbg("Prefix Exact Cache Hit: $call Hits: $hits/$misses of $matchtotal = $percent\%"); + } + push @out, @$p; + next; + } + + # then check if the whole thing succeeds either because it is cached + # or because it simply is a stored prefix as callsign (or even a prefix) + $p = $lru->get($call); if ($p) { $hits++; if (isdbg('prefix')) { @@ -229,26 +235,37 @@ LM: foreach $call (split /,/, $calls) { } push @out, @$p; next; + } + + # is it in the USDB, force a matchprefix to match? + my @s = USDB::get($call); + if (@s) { + @nout = get($call); + @nout = matchprefix($call) unless @nout; + $nout[0] = $ecall if @nout; } else { - - # is it in the USDB, force a matchprefix to match? - my @s = USDB::get($call); - if (@s) { - @nout = get($call); - @nout = matchprefix($call) unless @nout; - $nout[0] = $call if @nout; - } else { - @nout = get($call); - } - # now store it - if (@nout && $nout[0] eq $call) { - $misses++; - lru_put($call, \@nout); - dbg("got exact prefix: $nout[0]") if isdbg('prefix'); - push @out, @nout; - next; - } + # try a straight get for an exact callsign + @nout = get($ecall); + } + + # now store the exact prefix if it has been found + if (@nout && $nout[0] eq $ecall) { + $misses++; + $nout[0] = $call; + lru_put("=$call", \@nout); + dbg("got exact prefix: $nout[0]") if isdbg('prefix'); + push @out, @nout; + next; + } + + # now try a non-exact call/prefix + if ((@nout = get($call)) && $nout[0] eq $call) { + $misses++; + lru_put($call, \@nout); + dbg("got exact prefix: $nout[0]") if isdbg('prefix'); + push @out, @nout; + next; } # now split the call into parts if required @@ -386,7 +403,7 @@ L1: for ($n = 0; $n < @parts; $n++) { } # we are a pirate! - @nout = matchprefix('Q'); + @nout = matchprefix('QQ'); $misses++; lru_put($call, \@nout); push @out, @nout; @@ -437,22 +454,39 @@ sub to_ciz return @out; } +# get the full country data (dxcc, itu, cq, state, city) as a list +# from a callsign. +sub cty_data +{ + my $call = shift; + + my @dxcc = extract($call); + if (@dxcc) { + my $state = $dxcc[1]->state || ''; + my $city = $dxcc[1]->city || ''; + my $name = $dxcc[1]->name || ''; + + return ($dxcc[1]->dxcc, $dxcc[1]->itu, $dxcc[1]->cq, $state, $city, $name); + } + return (666,0,0,'','','Pirate-Country-QQ'); +} + my %valid = ( + city => '0,City', + cont => '0,Continent', + cq => '0,CQ', + dxcc => '0,DXCC', + itu => '0,ITU', lat => '0,Latitude,slat', long => '0,Longitude,slong', - dxcc => '0,DXCC', name => '0,Name', - itu => '0,ITU', - cq => '0,CQ', + qra => '0,Locator', state => '0,State', - city => '0,City', utcoff => '0,UTC offset', - cont => '0,Continent', ); sub AUTOLOAD { - my $self = shift; no strict; my $name = $AUTOLOAD; @@ -463,7 +497,7 @@ sub AUTOLOAD # this clever line of code creates a subroutine which takes over from autoload # from OO Perl - Conway *$AUTOLOAD = sub {@_ > 1 ? $_[0]->{$name} = $_[1] : $_[0]->{$name}} ; - &$AUTOLOAD($self, @_); + goto &$AUTOLOAD; } #