// File: /workspace/github_cpp_makefile_star2_O1/narges64[P]SIMBA/garbage_collection.cpp
// Function: find_victim_block(ssd_info*, local*)
STATE find_victim_block(ssd_info * ssd, local * location){
	high_resolution_clock::time_point t1 = high_resolution_clock::now();
	switch (ssd->parameter->gc_algorithm) {
		case GREEDY:
				greedy_algorithm(ssd, location);

				break;
		case FIFO:
				fifo_algorithm(ssd, location);

				break;
		case WINDOWED:
				windowed_algorithm(ssd, location);

				break;
		case RGA:
				RGA_algorithm(ssd, location); // select the best one based on valid number

				break;
		case RANDOM:
				RANDOM_algorithm(ssd, location);

				break;
		case RANDOMP:
				RANDOM_p_algorithm(ssd, location);

				break;
		case RANDOMPP:
				RANDOM_pp_algorithm(ssd, location);

				break;

		default:
		{
			printf("Wrong garbage collection in parameters %d\n", ssd->parameter->gc_algorithm);
			return ERROR;
		}

	}

  	high_resolution_clock::time_point t2 = high_resolution_clock::now();
  	double dif = duration_cast<nanoseconds>( t2 - t1 ).count();
  	// printf ("Elasped time is %lf nanoseconds.\n", dif );

	if (location->block == -1){
		printf("Error: Problem in finding the victim block, time: %lld    gc alg %d \n", ssd->current_time , ssd->parameter->gc_algorithm );
		return FAIL;

	}

	if (ssd->channel_head[location->channel]->lun_head[location->lun]->	
								plane_head[location->plane]->blk_head[location->block]->free_page_num >= ssd->parameter->page_block){
		cout << "Error: too much free page in selected victim \n";
		
		cout << ssd->channel_head[location->channel]->lun_head[location->lun]->plane_head[location->plane]->blk_head[location->block]->free_page_num << endl;
		return FAIL;
	}

	return SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
callq 0x2070
movq 0x58(%r14), %rax
movl 0x74(%rax), %esi
cmpq $0x6, %rsi
ja 0x7099
leaq 0x39a8(%rip), %rax      # 0xaa08
movslq (%rax,%rsi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7684
jmp 0x70d6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x792f
jmp 0x70d6
movl $0x1, 0xc(%rbx)
jmp 0x70d6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x77a5
jmp 0x70d6
leaq 0x39b3(%rip), %rdi      # 0xaa53
xorl %eax, %eax
callq 0x2060
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x71cd
movq %r14, %rdi
movq %rbx, %rsi
callq 0x76de
jmp 0x70d6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x79c6
jmp 0x70d6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7a4a
callq 0x2070
movslq 0xc(%rbx), %rax
cmpq $-0x1, %rax
je 0x71b3
movq 0x58(%r14), %rcx
movq 0x90(%r14), %rdx
movslq (%rbx), %rsi
movq (%rdx,%rsi,8), %rdx
movq 0x50(%rdx), %rdx
movslq 0x4(%rbx), %rsi
movq (%rdx,%rsi,8), %rdx
movq (%rdx), %rdx
movslq 0x8(%rbx), %rsi
movq (%rdx,%rsi,8), %rdx
movq 0x20(%rdx), %rdx
movq (%rdx,%rax,8), %rax
movl 0x4(%rax), %eax
movl $0x1, %ebp
cmpl 0x234(%rcx), %eax
jb 0x71cd
movq 0x6e9b(%rip), %r15      # 0xdfd0
leaq 0x3988(%rip), %rsi      # 0xaac4
movl $0x2e, %edx
movq %r15, %rdi
callq 0x21e0
movq 0x90(%r14), %rax
movslq (%rbx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq 0x4(%rbx), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq 0x8(%rbx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq 0xc(%rbx), %rcx
movq (%rax,%rcx,8), %rax
movl 0x4(%rax), %esi
movq %r15, %rdi
callq 0x22d0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20f0
xorl %ebp, %ebp
jmp 0x71cd
movq (%r14), %rsi
movq 0x58(%r14), %rax
movl 0x74(%rax), %edx
leaq 0x38ba(%rip), %rdi      # 0xaa7e
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x2060
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq