#!/usr/bin/perl -w

#
#  intermediate_join_red
#  Copyright (C) 2010 by USC/ISI
#  $Id$
#  
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License,
#  version 2, as published by the Free Software Foundation.
#  
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  
#  You should have received a copy of the GNU General Public License along
#  with this program; if not, write to the Free Software Foundation, Inc.,
#  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#  
#  
#  This code was originally written by Xun Fan <xunfan@isi.edu>.
#

use Fsdb::IO::Reader;
use Fsdb::IO::Writer;

#my $input_stream = new Fsdb::IO::Reader(-fh => \*STDIN, -fscode => 't');

# my $length = 8; # The history length

my $output_stream = new Fsdb::IO::Writer(-fh => \*STDOUT, -fscode => 't', -cols => [qw(ip history)]);
my $current_ip;
my $current_history = '0';
#my $ip_mask = 2**8 - 1;

use Bit::Vector;
use Bit::Vector::String;

sub bitshiftleft{
	my ($hex) = @_;
	my $bitlength = 4 * length($hex) + 4; # make sure it is long enough to carry all bits
	my $v = Bit::Vector->new_Hex($bitlength, $hex);
	$v->shift_left(0); # add the new census record
	my $v_out = $v->String_Export('h');
	my $out = lc(substr($v_out, 2)); # delete the "0x"
	if (substr($out, 0, 1) eq "0")   # delete the first 0 in the string if it exists.
	{$out = substr($out, 1);}
	return $out;
}

sub bitvecadd{
	my ($a1, $a2) = @_;
	my $carry = 0;
	my $length;
#	(length($a1) <= length($a2)) ? $length=length($a2) : $length=length($a1);
	if (length($a1) <= length($a2))
	{$length = length($a2);}
	else{$length = length($a1);}
	my $b1 = Bit::Vector->new_Hex(4*$length+4, $a1);
	my $b2 = Bit::Vector->new_Hex(4*$length+4, $a2);
	my $b3 = Bit::Vector->new_Hex(4*$length+4, "0");
	$b3->add($b1,$b2,$carry);  # add
	my $v_out = $b3->String_Export('h');
	my $out = lc(substr($v_out, 2)); # delete "0x"
	if (substr($out, 0, 1) eq "0") # delete first 0 if it exists.
	{$out = substr($out, 1);}
	return $out;
}

while(<>){
	my($ip, $history) = split;
	last if (!defined($ip));
	if (!defined($current_ip)){
		$current_ip = $ip;
		if ($history ne "y"){            # it means this's the join result of former censuses
			$current_history =  bitshiftleft($history); # in hex format
		}
		else{
			$current_history = "1";
		}
	}else{
		if($current_ip eq $ip){
			if ($history ne "y"){
                      		my $his = bitshiftleft($history);
	#			print "$his;;;";
				$current_history = bitvecadd($current_history, $his);
	#			print "$current_history\n";
			}
			else{
				$current_history = bitvecadd($current_history, "1");
			}
		}else{
			$output_stream->write_row($current_ip, $current_history);
			$current_ip = $ip;
			$current_history = "0";
			if ($history ne "y"){
				$current_history = bitshiftleft($history);
			}
			else{
				$current_history = "1";
			}
		}
	}
}

$output_stream->write_row($current_ip, $current_history);


