	#!/usr/bin/perl
	#
	# predict delays between accesses
	#
	
	#define constants
		
	$_Timestamp=0; 	$_Elapsed_Time=1;	$_HTTP_code=2;  
	$_Size=3; 	$_Method=4; 		$_URL=5;
	$_Exp_Date=6;	$_Next_Acc=7; 		$_Cacheable=8;
	$elapsed_time = 0;	#simulation time
	$dhit = 0;	#correctly predicted delays
	$dmiss = 0;	#incorrectly predicted delays

   	#open log file
	#open(LOG, "+<rez_pred_delays.txt") || die "$0: rez_pred_delays.txt will not open.";
	#seek(LOG, 0,2);
	&load_ptable;

	#process all files in directory with extension ".new"
	foreach $file (<*.new>) {
       	open(TRACES, "<$file") || die "$file will not open.";
		print "\nOpened: ". $file. "\n";
		seek(TRACES, 0,2); $file_size = tell(TRACES); seek(TRACES, 0,0); 
		
		$pos = tell(TRACES);
		$prev_pos = tell(TRACES);
		$start_time = time();
		while(<TRACES>) { # takes data from $file
			$proc=tell(TRACES)/$file_size;
			print "\rdone: ".$proc." of 1     ";
			if($proc>0.010){last;}
			@list = split(" ", $_);
			if($list[$_Cacheable]){
				&predict_delays;
			}
		}
		$end_time = time();
		close(TRACES);
		$elapsed_time += ($end_time-$start_time);
		print "\nHits:$dhit Misses: $dmiss hitrate: ". ($dhit/($dhit+$dmiss)*100)."\n";
		print "\nClosed: ". $file."\n";
		print "\nElapsed: $elapsed_time seconds";

    }

	#&storeaa(\%stat, ">rez_pred_delays.txt");

## end ##


#############################################
# algorythms
#############################################


###########
# DELAYS  #
###########

	sub predict_delays{
		my($del, $pom, @pomlist, $prev_acc, $state, $pstate);
		if(defined($stat{$list[$_URL]})){
			$pom=$stat{$list[$_URL]};
			@pomlist=split(" ", $pom);
			$prev_acc=shift(@pomlist);
			$del = $list[$_Timestamp]-$prev_acc;
			&det_state(\$del, \$state);
			#print "$del, $state ";
			push(@pomlist, $state);
			&next_state(\@pomlist, \$pstate);
			#print "$pstate\n";
			unshift(@pomlist, $list[$_Timestamp]);
			$stat{$list[$_URL]}=join(" ", @pomlist);
			$del = $list[$_Next_Acc]-$list[$_Timestamp];
			&det_state(\$del, \$state);
			#print "$state\n";
			if($state<=$pstate && $state >= 0){$dhit++;}else{$dmiss++;};
		}else{
			push(@pomlist, 11);
			&next_state(\@pomlist, \$pstate);
			#print "* $pstate\n";
			$del = $list[$_Next_Acc]-$list[$_Timestamp];
			&det_state(\$del, \$state);
			#print "$state\n";
			if($state<=$pstate && $state >= 0){$dhit++;}else{$dmiss++;};
			if($state>=0){$stat{$list[$_URL]}="$list[$_Timestamp] 11";}
		}
		print "hitrate: ". ($dhit/($dhit+$dmiss)*100)."      ";

	}

#########################
#load probability table #
#########################

	sub load_ptable{
		my($i, $j, $pom);
   		#open probability file
		open(PROB, "<probabilities.txt") || die "$0: probabilities.txt will not open.";
		
		for($i=0; $i<11; $i++){
			for($j=0; $j<12; $j++){
				$ptable[$i][$j]=<PROB>;
				chop($ptable[$i][$j]);
				#print $ptable[$i][$j]." ";
			}
			#print "\n";
		}
		
		close(PROB);
	}

	sub det_state($$){
		my($lok_del, $lok_state); 
		$lok_del=shift(@_); $lok_state=shift(@_);
			if($$lok_del>=0){
			  if($$lok_del<=32){
				$$lok_state=0;
			  }elsif($$lok_del<=195){
				$$lok_state=1;
			  }elsif($$lok_del<=1005){
				$$lok_state=2;
			  }elsif($$lok_del<=3116){
				$$lok_state=3;
			  }elsif($$lok_del<=7910){
				$$lok_state=4;
			  }elsif($$lok_del<=17463){
				$$lok_state=5;
			  }elsif($$lok_del<=34918){
				$$lok_state=6;
			  }elsif($$lok_del<=66842){
				$$lok_state=7;
			  }elsif($$lok_del<=116272){
				$$lok_state=8;
			  }elsif($$lok_del<=343966){
				$$lok_state=9;
			  }else{
				$$lok_state=10;
			  }
			}else{
			  $$lok_state=-1;
			}

	}
	
	sub next_state($$){
		my($i, $max_prob, $lok_prevdel, $lok_nstate, $lok_laststate); 
		$lok_prevdel=shift(@_); $lok_nstate=shift(@_); $max_prob=0;
		$lok_laststate=$lok_prevdel->[$#$lok_prevdel];
		#print $#$lok_prevdel." laststate=$lok_laststate";
		
		if($lok_laststate!=11){
			for($i=$#$lok_prevdel; $i>=0; $i--){
				if($max_prob<$ptable[$lok_laststate][$lok_prevdel->[$i]]){
					$max_prob=$ptable[$lok_laststate][$lok_prevdel->[$i]];
					$$lok_nstate=$lok_prevdel->[$i];
				}
			}
			
			#for($i=9; $i>=0; $i--){
			#	if($max_prob<$ptable[$lok_laststate][$i]){
			#		$max_prob=$ptable[$lok_laststate][$i];
			#		$$lok_nstate=$i;
			#	}
			#}
			
			#$$lok_nstate=9;
		}else{
			for($i=9; $i>=0; $i--){
				if($max_prob<$ptable[10][$i]){
					$max_prob=$ptable[10][$i];
					$$lok_nstate=$i;
				}
			}
		}
		#print " nextstate=$$lok_nstate\n";
	}

############################################
#subroutine for dumping asoc array to file #
############################################

sub storeaa($$){
	my $a=shift(@_), $f=shift(@_), $key;

	open(DMP, "$f") || die "$0: will not open.";
	
		while (($key, $val) = each (%$a) ){
			print DMP $key." ".$val."\n";
			#print DMP $$a{$key}."\n";
		}

	close DMP;
}

sub loadaa($$){
	my $a=shift(@_), $f=shift(@_), $key;

	open(DMP, "<$f") || die "$0: will not open.";
	
		while(<DMP>) { # takes data from $file
			@list = split(" ", $_);
			$$a{$list[0]}=$list[1];
		}

	close DMP;
}
