From b06fd1d447d5411d8d441e807f93efa897b68aaf Mon Sep 17 00:00:00 2001
From: Dirk Koopman <djk@tobit.co.uk>
Date: Sun, 14 Nov 2021 22:49:49 +0000
Subject: [PATCH] "working" version of spot cache

---
 perl/Spot.pm    | 107 ++++++++++++++++++++++++++++++------------------
 perl/cluster.pl |  17 +++++---
 2 files changed, 80 insertions(+), 44 deletions(-)

diff --git a/perl/Spot.pm b/perl/Spot.pm
index bed8bd20..27b82b38 100644
--- a/perl/Spot.pm
+++ b/perl/Spot.pm
@@ -19,7 +19,8 @@ use DXDupe;
 use Data::Dumper;
 use QSL;
 use DXSql;
-use Julian;
+use Time::HiRes qw(gettimeofday tv_interval);
+
 
 use strict;
 
@@ -186,13 +187,16 @@ sub init
 
 	# initialise the cache if required
 	if ($spotcachedays) {
+		my $t0 = [gettimeofday];
 		$spotcachedays = 2 if $spotcachedays < 2;
-		my $now = $today->sub($spotcachedays);
-		while ($now->cmp($today) >= 0) {
+		dbg "Spot::init - reading in $spotcachedays days of spots into cache"; 
+		for (my $i = 0; $i < $spotcachedays; ++$i) {
+			my $now = $today->sub($i);
 			my $fh = $fp->open($now);
 			if ($fh) {
 				my @in;
-				while (<$fh>) {
+				my $rec;
+				for ($rec = 0; <$fh>; ++$rec) {
 					chomp;
 					my @s = split /\^/;
 					if (@s < 14) {
@@ -203,13 +207,15 @@ sub init
 						push @s, @a[0,1], @b[0,1] if @s < 12;
 						push @s,  $a[2], $b[2] if @s < 14;
 					}
-					push @in, \@s; 
+					unshift @in, \@s; 
 				}
 				$fh->close;
-				$spotcache{"$now->[0]|$now->[1]"} = \@in;
+				dbg("Spot::init read $rec spots from " . _cachek($now));
+				$spotcache{_cachek($now)} = \@in;
 			}
 			$now->add(1);
 		}
+		dbg("Spot::init $spotcachedays files of spots read into cache in " . _diffms($t0) . "mS")
 	}
 }
 
@@ -256,9 +262,9 @@ sub add
 	$fp->writeunix($_[2], $buf);
 	if ($spotcachedays) {
 		my $now = Julian::Day->new($_[2]);
-		my $day = "$now->[0]|$now->[1]";
-		my $r = exists $spotcache{$day} ? $spotcache{$day} : $spotcache{$day} = [];
-		unshift @$r, @_;
+		my $day = _cachek($now);
+		my $r = (exists $spotcache{$day}) ? $spotcache{$day} : ($spotcache{$day} = []);
+		unshift @$r, \@_;
 
 		# remove old days
 		while (keys %spotcache > $spotcachedays+1) {
@@ -364,47 +370,65 @@ sub search
 	for ($i = $count = 0; $count < $to && $i < $maxdays; ++$i) { # look thru $maxdays worth of files only
 		last if $now->cmp($todate) <= 0;
 
-		if ($spotcachedays) {
-			
-		}
-		my $fn = $fp->fn($now->sub($i));
-		if ($readback) {
-			dbg("Spot::search search using tac fn: $fn $i") if isdbg('search');
-			$fh = IO::File->new("$readback $fn |");
-		}
-		else {
-			dbg("Spot::search search fn: $fp->{fn} $i") if isdbg('search');
-			$fh = $fp->open($now->sub($i));	# get the next file
-		}
-		if ($fh) {
-			my $rec = 0;
-			my $in;
-			while (<$fh>) {
-				chomp;
-				my @r = split /\^/;
+
+		my $this = $now->sub($i);
+		my $fn = $fp->fn($this);
+		my $cachekey = _cachek($this); 
+		my $rec = 0;
+
+		if ($spotcachedays && $spotcache{$cachekey}) {
+			foreach my $r (@{$spotcache{$cachekey}}) {
 				++$rec;
 				if ($dofilter && $dxchan && $dxchan->{spotsfilter}) {
-					my ($gotone, undef) = $dxchan->{spotsfilter}->it(@r);
+					my ($gotone, undef) = $dxchan->{spotsfilter}->it(@$r);
 					next unless $gotone;
 				}
-				if (&$ecode(\@r)) {
+				if (&$ecode($r)) {
 					++$count;
 					next if $count < $from;
-					if ($readback) {
-						push @out, \@r;
-						last if $count >= $to;
-					} else {
-						push @out, \@r;
-						shift @out if $count >= $to;
+					push @out, $r;
+					last if $count >= $to;
+				}
+			}
+			dbg("Spot::search cache recs read: $rec") if isdbg('search');
+		} else {
+			if ($readback) {
+				dbg("Spot::search search using tac fn: $fn $i") if isdbg('search');
+				$fh = IO::File->new("$readback $fn |");
+			}
+			else {
+				dbg("Spot::search search fn: $fp->{fn} $i") if isdbg('search');
+				$fh = $fp->open($now->sub($i));	# get the next file
+			}
+			if ($fh) {
+				my $in;
+				while (<$fh>) {
+					chomp;
+					my @r = split /\^/;
+					++$rec;
+					if ($dofilter && $dxchan && $dxchan->{spotsfilter}) {
+						my ($gotone, undef) = $dxchan->{spotsfilter}->it(@r);
+						next unless $gotone;
+					}
+					if (&$ecode(\@r)) {
+						++$count;
+						next if $count < $from;
+						if ($readback) {
+							push @out, \@r;
+							last if $count >= $to;
+						} else {
+							push @out, \@r;
+							shift @out if $count >= $to;
+						}
 					}
 				}
+				dbg("Spot::search file recs read: $rec") if isdbg('search');
+				last if $count >= $to; # stop after to
 			}
-			dbg("Spot::search recs read: $rec") if isdbg('search');
-			last if $count >= $to; # stop after to
-			
-			return ("Spot search error", $@) if $@;
 		}
 	}
+	return ("Spot search error", $@) if $@;
+
 	@out = sort {$b->[2] <=> $a->[2]} @out if @out;
 	return @out;
 }
@@ -561,6 +585,11 @@ sub daily
 	my $date = Julian::Day->new($main::systime)->sub(1);
 	genstats($date) unless checkstats($date);
 }
+
+sub _cachek
+{
+	return "$_[0]->[0]|$_[0]->[1]";
+}
 1;
 
 
diff --git a/perl/cluster.pl b/perl/cluster.pl
index 4c0f374c..d4e9981a 100755
--- a/perl/cluster.pl
+++ b/perl/cluster.pl
@@ -664,19 +664,26 @@ sub setup_start
 	dbg("Start Protocol Engines ...");
 	DXProt->init();
 
+	# read startup script
+	my $script = new Script "startup";
+	$script->run($main::me) if $script;
+
+	# put in a DXCluster node for us here so we can add users and take them away
+	$routeroot = Route::Node->new($mycall, $version*100+5300, Route::here($main::me->here)|Route::conf($main::me->conf));
+	$routeroot->do_pc9x(1);
+	$routeroot->via_pc92(1);
+
 	# make sure that there is a routing OUTPUT node default file
 	#unless (Filter::read_in('route', 'node_default', 0)) {
 	#	my $dxcc = $main::me->dxcc;
 	#	$Route::filterdef->cmd($main::me, 'route', 'accept', "node_default call $mycall" );
 	#}
 
-	my $script = new Script "startup";
-    $script->run($main::me) if $script;
-
 	# initial the Spot stuff
 	dbg("Starting DX Spot system");
-	Spot->init();	#
-	
+	Spot->init();
+
+	# read in any existing message headers and clean out old crap
 	dbg("reading existing message headers ...");
 	DXMsg->init();
 	DXMsg::clean_old();
-- 
2.43.0