// File: /workspace/github_cpp_makefile_star2_O2/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 %r15
pushq %r14
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
callq 0x2060
movq 0x58(%r14), %rax
movl 0x74(%rax), %esi
cmpq $0x6, %rsi
ja 0x6548
leaq 0x33fd(%rip), %rax      # 0x990c
movslq (%rax,%rsi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6a2d
jmp 0x657f
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6cc4
jmp 0x657f
movl $0x1, 0xc(%rbx)
jmp 0x657f
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6b3c
jmp 0x657f
leaq 0x3408(%rip), %rdi      # 0x9957
xorl %eax, %eax
callq 0x2050
pushq $-0x1
jmp 0x65cc
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6a85
jmp 0x657f
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6d59
jmp 0x657f
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6ddb
callq 0x2060
movslq 0xc(%rbx), %rax
cmpq $-0x1, %rax
je 0x65cf
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
cmpl 0x234(%rcx), %eax
jae 0x65eb
pushq $0x1
popq %rbx
jmp 0x6647
movq (%r14), %rsi
movq 0x58(%r14), %rax
movl 0x74(%rax), %edx
leaq 0x33a2(%rip), %rdi      # 0x9982
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x2050
jmp 0x6647
movq 0x79de(%rip), %r15      # 0xdfd0
leaq 0x33cf(%rip), %rsi      # 0x99c8
movq %r15, %rdi
callq 0x2140
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 0x22a0
movq %rax, %rdi
callq 0x20b0
xorl %ebx, %ebx
movl %ebx, %eax
popq %rbx
popq %r14
popq %r15
retq