// File: ashlall[P]StreamStats/Test/Reservoir_test.cpp
// Function: test_reservoir()
void test_reservoir()
{
	int k = 1000; // Reservoir sample size	
	long quantA,quantB,quantC,quantD,quantE,quantF,quantG,quantH;
	bool condA,condB,condC,condD,condE,condF,condG,condH;
	double upper,lower;
	int n=10000000; 
	
	/*	Extrem case when n = 1
	
	int random_fix1 = rand()% RAND_MAX;
    cout << "random_fix1: " << random_fix1 <<endl;
    int random_fix2 = rand()% RAND_MAX;
    //cout << "random_fix2: " << random_fix2 <<endl;
    int random_fix3 = rand()% RAND_MAX;
    //cout << "random_fix2: " << random_fix3 <<endl;
    */
    
	ReservoirSampling a(k); 
	ReservoirSampling b(k);
	ReservoirSampling c(k);
	ReservoirSampling d(k);
	ReservoirSampling e(k);
	
	/*	Extrem case when n = 1
	
	ReservoirSampling f(k);
	ReservoirSampling g(k);
	ReservoirSampling h(k);
  	*/
  	
	for (int i=0;i <= n;i++) //inserting in increasing order
	{
		a.insert(i); 
		
	}
	
	bool condA1;
	int LA = a.get_stream_size(); //test the function get_stream_size()
	condA1= (LA == n+1);
	assert(condA1 == true);

	
	for (int i = n; i >= 0; i--) //inserting in desceding order
    {
  		b.insert(i); 
    }
    
  	bool condB1;
	int LB = b.get_stream_size(); //test the function get_stream_size()
	condB1= (LB == n+1);
	assert(condB1 == true);
  
 	for (int m = 1; m <= 3; m++) //create 3 "random" sequences with certain patterned seed that holds their randomness every time runs the code
  	{
  		 if (m == 1)
  		 {
  		   	 //cout << "sequence 1: " << endl;
  			 for (int i = 0; i <= n; i++)
   			 {
   			 	srand(i);
  				long rand_num=rand()%n;
  				//cout << rand_num << " ";
  				c.insert(rand_num);  //inserting float number from 0 to n
  			 }
  			 //cout << ""<<endl;
  			 bool condC1;
			 int LC = c.get_stream_size(); //test the function get_stream_size()
			 condC1= (LC == n+1);
			 assert(condC1 == true);
  		}
  		
  		else if(m == 2)
  		{
  		 	  //cout << "sequence 2: " << endl;
  			  for (int i = 0; i <= n; i++)
   			 {
   			    srand(i^2);
  				long rand_num=rand()%n;
  				//cout << rand_num << " ";
  				d.insert(rand_num); //inserting float number from 0 to n
  			 }  
  			 //cout << ""<<endl;
  			 bool condD1;
			 int LD = d.get_stream_size(); //test the function get_stream_size()
			 condD1= (LD == n+1);
			 assert(condD1 == true);
  		}	
  		
  		else 
  		{	
  		  	 //cout << "sequence 3: " << endl;
  			  for (int i = 0; i <= n; i++)
   			 {
   			 	srand(n-i);
  				long rand_num=rand()%n;
  				//cout << rand_num << " ";
  				e.insert(rand_num); //inserting float number from 0 to n
  			 }  
  			 //cout <<""<<endl;
  			 bool condE1;
			 int LE = e.get_stream_size(); //test the function get_stream_size()
			 condE1= (LE == n+1);
			 assert(condE1 == true);
  		}
  	} 

	  /*	Extrem case when n = 1
	  	
  	  f.insert(random_fix1); 
  	  g.insert(random_fix2); 
  	  h.insert(random_fix3);  
  	  */ 
  	
	for (float i=1;i<=100;i++)
	{
  	  double interval=i/100; //getting each percentile probabilty interval
  	  
  	  quantA=a.getQuantile(interval); //getting quantile for each probability interval
  	  quantB=b.getQuantile(interval);//getting quantile for each probability interval
  	  quantC=c.getQuantile(interval);//getting quantile for each probability interval
  	  quantD=d.getQuantile(interval);
  	  quantE=e.getQuantile(interval);
  	  
	  /*	Extrem case when n = 1
	  
  	  quantF=f.getQuantile(interval);
  	  quantG=g.getQuantile(interval);
  	  quantH=h.getQuantile(interval);
  	  */
  	  
  	  lower=(interval-0.05)*n;
  	  upper=(interval+0.05)*n;
  	  
  	  condA= ((lower<=quantA) && (upper>=quantA));
  	  //checking if quantile is within error range

  	  condB= ((lower<=quantB) && (upper >=quantB));
  	  //checking if quantile is within error range

  	  condC= ((lower<=quantC) && (upper>=quantC));
  	  condD= ((lower<=quantD) && (upper>=quantD));
  	  condE= ((lower<=quantE) && (upper>=quantE));
  	  //checking if quantile is within error range
  	  
  	  /*	Extrem case when n = 1
  	  
  	  condF= (random_fix1 == quantF);
  	  condG= (random_fix2 == quantG);
  	  condH= (random_fix3 == quantH);
	  */
  	  
  	  assert(condA==true);
  	  assert(condB==true);
  	  assert(condC==true);
  	  assert(condD==true);
  	  assert(condE==true);
  	  
  	  /*	Extrem case when n = 1
  	  assert(condF==true);
  	  assert(condG==true);
  	  assert(condH==true);
  	  */
  }   
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movl $0x3e8, -0x4(%rbp)      # imm = 0x3E8
movl $0x989680, -0x64(%rbp)  # imm = 0x989680
movl -0x4(%rbp), %esi
leaq -0x80(%rbp), %rdi
callq 0x1300
movl -0x4(%rbp), %esi
leaq -0x98(%rbp), %rdi
callq 0x1300
jmp 0x16c6
movl -0x4(%rbp), %esi
leaq -0xc0(%rbp), %rdi
callq 0x1300
jmp 0x16d7
movl -0x4(%rbp), %esi
leaq -0xd8(%rbp), %rdi
callq 0x1300
jmp 0x16e8
movl -0x4(%rbp), %esi
leaq -0xf0(%rbp), %rdi
callq 0x1300
jmp 0x16f9
movl $0x0, -0xf4(%rbp)
movl -0xf4(%rbp), %eax
cmpl -0x64(%rbp), %eax
jg 0x178c
cvtsi2sdl -0xf4(%rbp), %xmm0
leaq -0x80(%rbp), %rdi
callq 0x1540
movl -0xf4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf4(%rbp)
jmp 0x1703
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x1f69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x1f5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x1f51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x1f45
leaq -0x80(%rbp), %rdi
callq 0x25f0
movq %rax, -0x168(%rbp)
jmp 0x179e
movq -0x168(%rbp), %rax
movl %eax, -0xfc(%rbp)
movl -0xfc(%rbp), %eax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, -0xf5(%rbp)
movb -0xf5(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x17d6
jmp 0x1818
leaq 0x28e3(%rip), %rdi      # 0x40c0
leaq 0x28eb(%rip), %rsi      # 0x40cf
movl $0x37, %edx
leaq 0x28f2(%rip), %rcx      # 0x40e2
callq 0x1060
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x14f0
jmp 0x1f45
movl -0x64(%rbp), %eax
movl %eax, -0x100(%rbp)
cmpl $0x0, -0x100(%rbp)
jl 0x184f
cvtsi2sdl -0x100(%rbp), %xmm0
leaq -0x98(%rbp), %rdi
callq 0x1540
movl -0x100(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x100(%rbp)
jmp 0x1821
leaq -0x98(%rbp), %rdi
callq 0x25f0
movq %rax, -0x170(%rbp)
jmp 0x1864
movq -0x170(%rbp), %rax
movl %eax, -0x108(%rbp)
movl -0x108(%rbp), %eax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, -0x101(%rbp)
movb -0x101(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x189c
jmp 0x18bb
leaq 0x2855(%rip), %rdi      # 0x40f8
leaq 0x2825(%rip), %rsi      # 0x40cf
movl $0x42, %edx
leaq 0x282c(%rip), %rcx      # 0x40e2
callq 0x1060
movl $0x1, -0x10c(%rbp)
cmpl $0x3, -0x10c(%rbp)
jg 0x1b65
cmpl $0x1, -0x10c(%rbp)
jne 0x19a9
movl $0x0, -0x110(%rbp)
movl -0x110(%rbp), %eax
cmpl -0x64(%rbp), %eax
jg 0x1938
movl -0x110(%rbp), %edi
callq 0x10b0
callq 0x1040
cltd
idivl -0x64(%rbp)
movslq %edx, %rax
movq %rax, -0x118(%rbp)
cvtsi2sdq -0x118(%rbp), %xmm0
leaq -0xc0(%rbp), %rdi
callq 0x1540
movl -0x110(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x110(%rbp)
jmp 0x18e9
leaq -0xc0(%rbp), %rdi
callq 0x25f0
movq %rax, -0x178(%rbp)
jmp 0x194d
movq -0x178(%rbp), %rax
movl %eax, -0x120(%rbp)
movl -0x120(%rbp), %eax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, -0x119(%rbp)
movb -0x119(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1985
jmp 0x19a4
leaq 0x277b(%rip), %rdi      # 0x4107
leaq 0x273c(%rip), %rsi      # 0x40cf
movl $0x54, %edx
leaq 0x2743(%rip), %rcx      # 0x40e2
callq 0x1060
jmp 0x1b4f
cmpl $0x2, -0x10c(%rbp)
jne 0x1a83
movl $0x0, -0x124(%rbp)
movl -0x124(%rbp), %eax
cmpl -0x64(%rbp), %eax
jg 0x1a12
movl -0x124(%rbp), %edi
xorl $0x2, %edi
callq 0x10b0
callq 0x1040
cltd
idivl -0x64(%rbp)
movslq %edx, %rax
movq %rax, -0x130(%rbp)
cvtsi2sdq -0x130(%rbp), %xmm0
leaq -0xd8(%rbp), %rdi
callq 0x1540
movl -0x124(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x124(%rbp)
jmp 0x19c0
leaq -0xd8(%rbp), %rdi
callq 0x25f0
movq %rax, -0x180(%rbp)
jmp 0x1a27
movq -0x180(%rbp), %rax
movl %eax, -0x138(%rbp)
movl -0x138(%rbp), %eax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, -0x131(%rbp)
movb -0x131(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1a5f
jmp 0x1a7e
leaq 0x26b0(%rip), %rdi      # 0x4116
leaq 0x2662(%rip), %rsi      # 0x40cf
movl $0x65, %edx
leaq 0x2669(%rip), %rcx      # 0x40e2
callq 0x1060
jmp 0x1b4d
movl $0x0, -0x13c(%rbp)
movl -0x13c(%rbp), %eax
cmpl -0x64(%rbp), %eax
jg 0x1adf
movl -0x64(%rbp), %edi
subl -0x13c(%rbp), %edi
callq 0x10b0
callq 0x1040
cltd
idivl -0x64(%rbp)
movslq %edx, %rax
movq %rax, -0x148(%rbp)
cvtsi2sdq -0x148(%rbp), %xmm0
leaq -0xf0(%rbp), %rdi
callq 0x1540
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0x1a8d
leaq -0xf0(%rbp), %rdi
callq 0x25f0
movq %rax, -0x188(%rbp)
jmp 0x1af4
movq -0x188(%rbp), %rax
movl %eax, -0x150(%rbp)
movl -0x150(%rbp), %eax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movb %al, -0x149(%rbp)
movb -0x149(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1b2c
jmp 0x1b4b
leaq 0x25f2(%rip), %rdi      # 0x4125
leaq 0x2595(%rip), %rsi      # 0x40cf
movl $0x76, %edx
leaq 0x259c(%rip), %rcx      # 0x40e2
callq 0x1060
jmp 0x1b4d
jmp 0x1b4f
jmp 0x1b51
movl -0x10c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10c(%rbp)
jmp 0x18c5
movss 0x2523(%rip), %xmm0     # 0x4090
movss %xmm0, -0x154(%rbp)
movss 0x2517(%rip), %xmm0     # 0x4094
ucomiss -0x154(%rbp), %xmm0
jb 0x1f03
movss -0x154(%rbp), %xmm0
movss 0x24fa(%rip), %xmm1     # 0x4094
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x160(%rbp)
movsd -0x160(%rbp), %xmm0
leaq -0x80(%rbp), %rdi
callq 0x15e0
movsd %xmm0, -0x190(%rbp)
jmp 0x1bc5
movsd -0x190(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x10(%rbp)
movsd -0x160(%rbp), %xmm0
leaq -0x98(%rbp), %rdi
callq 0x15e0
movsd %xmm0, -0x198(%rbp)
jmp 0x1bf4
movsd -0x198(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x18(%rbp)
movsd -0x160(%rbp), %xmm0
leaq -0xc0(%rbp), %rdi
callq 0x15e0
movsd %xmm0, -0x1a0(%rbp)
jmp 0x1c23
movsd -0x1a0(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x20(%rbp)
movsd -0x160(%rbp), %xmm0
leaq -0xd8(%rbp), %rdi
callq 0x15e0
movsd %xmm0, -0x1a8(%rbp)
jmp 0x1c52
movsd -0x1a8(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x28(%rbp)
movsd -0x160(%rbp), %xmm0
leaq -0xf0(%rbp), %rdi
callq 0x15e0
movsd %xmm0, -0x1b0(%rbp)
jmp 0x1c81
movsd -0x1b0(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x30(%rbp)
movsd -0x160(%rbp), %xmm0
movsd 0x236e(%rip), %xmm1     # 0x4010
subsd %xmm1, %xmm0
cvtsi2sdl -0x64(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd 0x2354(%rip), %xmm0     # 0x4010
addsd -0x160(%rbp), %xmm0
cvtsi2sdl -0x64(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x60(%rbp), %xmm1
cvtsi2sdq -0x10(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x1b1(%rbp)
jb 0x1d03
movsd -0x58(%rbp), %xmm0
cvtsi2sdq -0x10(%rbp), %xmm1
ucomisd %xmm1, %xmm0
setae %al
movb %al, -0x1b1(%rbp)
movb -0x1b1(%rbp), %al
andb $0x1, %al
movb %al, -0x49(%rbp)
movsd -0x60(%rbp), %xmm1
cvtsi2sdq -0x18(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x1b2(%rbp)
jb 0x1d3f
movsd -0x58(%rbp), %xmm0
cvtsi2sdq -0x18(%rbp), %xmm1
ucomisd %xmm1, %xmm0
setae %al
movb %al, -0x1b2(%rbp)
movb -0x1b2(%rbp), %al
andb $0x1, %al
movb %al, -0x4a(%rbp)
movsd -0x60(%rbp), %xmm1
cvtsi2sdq -0x20(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x1b3(%rbp)
jb 0x1d7b
movsd -0x58(%rbp), %xmm0
cvtsi2sdq -0x20(%rbp), %xmm1
ucomisd %xmm1, %xmm0
setae %al
movb %al, -0x1b3(%rbp)
movb -0x1b3(%rbp), %al
andb $0x1, %al
movb %al, -0x4b(%rbp)
movsd -0x60(%rbp), %xmm1
cvtsi2sdq -0x28(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x1b4(%rbp)
jb 0x1db7
movsd -0x58(%rbp), %xmm0
cvtsi2sdq -0x28(%rbp), %xmm1
ucomisd %xmm1, %xmm0
setae %al
movb %al, -0x1b4(%rbp)
movb -0x1b4(%rbp), %al
andb $0x1, %al
movb %al, -0x4c(%rbp)
movsd -0x60(%rbp), %xmm1
cvtsi2sdq -0x30(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x1b5(%rbp)
jb 0x1df3
movsd -0x58(%rbp), %xmm0
cvtsi2sdq -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
setae %al
movb %al, -0x1b5(%rbp)
movb -0x1b5(%rbp), %al
andb $0x1, %al
movb %al, -0x4d(%rbp)
movb -0x49(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1e0d
jmp 0x1e2c
leaq 0x2320(%rip), %rdi      # 0x4134
leaq 0x22b4(%rip), %rsi      # 0x40cf
movl $0xa7, %edx
leaq 0x22bb(%rip), %rcx      # 0x40e2
callq 0x1060
movb -0x4a(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1e3b
jmp 0x1e5a
leaq 0x22fe(%rip), %rdi      # 0x4140
leaq 0x2286(%rip), %rsi      # 0x40cf
movl $0xa8, %edx
leaq 0x228d(%rip), %rcx      # 0x40e2
callq 0x1060
movb -0x4b(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1e69
jmp 0x1e88
leaq 0x22dc(%rip), %rdi      # 0x414c
leaq 0x2258(%rip), %rsi      # 0x40cf
movl $0xa9, %edx
leaq 0x225f(%rip), %rcx      # 0x40e2
callq 0x1060
movb -0x4c(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1e97
jmp 0x1eb6
leaq 0x22ba(%rip), %rdi      # 0x4158
leaq 0x222a(%rip), %rsi      # 0x40cf
movl $0xaa, %edx
leaq 0x2231(%rip), %rcx      # 0x40e2
callq 0x1060
movb -0x4d(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1ec5
jmp 0x1ee4
leaq 0x2298(%rip), %rdi      # 0x4164
leaq 0x21fc(%rip), %rsi      # 0x40cf
movl $0xab, %edx
leaq 0x2203(%rip), %rcx      # 0x40e2
callq 0x1060
jmp 0x1ee6
movss 0x21a2(%rip), %xmm0     # 0x4090
addss -0x154(%rbp), %xmm0
movss %xmm0, -0x154(%rbp)
jmp 0x1b75
leaq -0xf0(%rbp), %rdi
callq 0x14f0
leaq -0xd8(%rbp), %rdi
callq 0x14f0
leaq -0xc0(%rbp), %rdi
callq 0x14f0
leaq -0x98(%rbp), %rdi
callq 0x14f0
leaq -0x80(%rbp), %rdi
callq 0x14f0
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
leaq -0xd8(%rbp), %rdi
callq 0x14f0
leaq -0xc0(%rbp), %rdi
callq 0x14f0
leaq -0x98(%rbp), %rdi
callq 0x14f0
leaq -0x80(%rbp), %rdi
callq 0x14f0
movq -0xa0(%rbp), %rdi
callq 0x1110
nop