// File: /workspace/github_cpp_makefile_star2_O2/narges64[P]SIMBA/ftl.cpp
// Function: service_in_buffer(ssd_info*, sub_request*)
STATE service_in_buffer(ssd_info * ssd, sub_request * sub){
	// check mapping table and find the request
	if (sub->operation == READ){
		buffer_entry * buf_ent = NULL;
		if (ssd->dram->buffer->buffer_capacity == 0) {
			sub->buf_entry = NULL;
			service_in_flash(ssd, sub);
			return SUCCESS;
		}

		if (ssd->dram->map->map_entry[sub->lpn].buf_ent != NULL){
			buf_ent = ssd->dram->map->map_entry[sub->lpn].buf_ent;
			ssd->dram->buffer->hit_read(buf_ent);
			sub->complete_time = ssd->current_time + 1000;
			sub->buf_entry= buf_ent;
			change_subrequest_state(ssd, sub,SR_MODE_ST_S,
				ssd->current_time,SR_MODE_COMPLETE,sub->complete_time);
		}else {
			service_in_flash(ssd, sub);
		}
	}
	else if (sub->operation == WRITE){
		if (ssd->dram->buffer->buffer_capacity == 0) {
			sub->buf_entry = NULL;
			service_in_flash(ssd, sub);
			return SUCCESS;
		}
		buffer_entry * buf_ent = NULL;
		if (ssd->dram->map->map_entry[sub->lpn].buf_ent == NULL) {
			// Add a new entry to buffer
			buf_ent = ssd->dram->buffer->add_head(sub->lpn);
			sub->buf_entry = NULL;

			if (buf_ent->outlier) {
				buf_ent->sub = sub;
			}else {
				ssd->dram->map->map_entry[sub->lpn].buf_ent = buf_ent;
				// Mark the request as complete
				sub->complete_time = ssd->current_time + 1000;
				// cout << "Delay buffer add (" << sub->lpn << "," << sub->location->plane << ")  " << sub->complete_time - sub->begin_time << endl;
				change_subrequest_state(ssd, sub,SR_MODE_ST_S,ssd->current_time,
							SR_MODE_COMPLETE,sub->complete_time);
				buf_ent->sub = NULL;
			}


			sub_request * evict_sub = create_sub_request(ssd, sub->lpn,NULL, WRITE, sub->io_num);
			evict_sub->buf_entry = buf_ent;
			service_in_flash(ssd, evict_sub);

		}else {	 // write to an entry in the buffer, just need to change the entry and make it dirty
			buf_ent = ssd->dram->map->map_entry[sub->lpn].buf_ent;
			ssd->dram->buffer->hit_write(buf_ent);
			sub->complete_time = ssd->current_time + 1000;
			// cout << "Delay buffer hit (" << sub->lpn << "," << sub->location->plane << ")  " << sub->complete_time - sub->begin_time << endl;
			change_subrequest_state(ssd, sub,SR_MODE_ST_S,
					ssd->current_time,SR_MODE_COMPLETE,sub->complete_time);
			sub->buf_entry = NULL;
		}

	}
	return SUCCESS;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
movl 0x20(%rsi), %eax
testl %eax, %eax
je 0x48e2
cmpl $0x1, %eax
jne 0x494b
movq 0x60(%rbx), %rax
movq 0x18(%rax), %rdi
cmpl $0x0, 0x8(%rdi)
je 0x493b
movq 0x10(%rax), %rax
movq (%rax), %rax
movl 0xc(%r14), %ecx
shlq $0x4, %rcx
movq 0x8(%rax,%rcx), %r15
testq %r15, %r15
je 0x4940
movq %r15, %rsi
callq 0x5ca8
movq (%rbx), %rcx
leaq 0x3e8(%rcx), %r9
movq %r9, 0x58(%r14)
movq %r15, 0x18(%r14)
pushq $0x1
popq %rdx
pushq $0x9
popq %r8
movq %rbx, %rdi
movq %r14, %rsi
callq 0x637a
jmp 0x494b
movq 0x60(%rbx), %rax
movq 0x18(%rax), %rdi
cmpl $0x0, 0x8(%rdi)
je 0x493b
movq 0x10(%rax), %rax
movq (%rax), %rax
movl 0xc(%r14), %esi
movq %rsi, %rcx
shlq $0x4, %rcx
movq 0x8(%rax,%rcx), %rax
testq %rax, %rax
je 0x4954
movq %rax, %rsi
callq 0x5d32
movq (%rbx), %rcx
leaq 0x3e8(%rcx), %r9
movq %r9, 0x58(%r14)
pushq $0x1
popq %rdx
pushq $0x9
popq %r8
movq %rbx, %rdi
movq %r14, %rsi
callq 0x637a
andq $0x0, 0x18(%r14)
jmp 0x494b
andq $0x0, 0x18(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x49cb
pushq $0x1
popq %rax
popq %rbx
popq %r14
popq %r15
retq
callq 0x5cdc
andq $0x0, 0x18(%r14)
movq %rax, %r15
cmpb $0x0, 0x8(%rax)
movq %r14, %rax
jne 0x49a4
movq 0x60(%rbx), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movl 0xc(%r14), %ecx
shlq $0x4, %rcx
movq %r15, 0x8(%rax,%rcx)
movq (%rbx), %rcx
leaq 0x3e8(%rcx), %r9
movq %r9, 0x58(%r14)
pushq $0x1
popq %rdx
pushq $0x9
popq %r8
movq %rbx, %rdi
movq %r14, %rsi
callq 0x637a
xorl %eax, %eax
movq %rax, 0x10(%r15)
movl 0x4(%r14), %r8d
movl 0xc(%r14), %esi
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x4744
movq %r15, 0x18(%rax)
movq %rbx, %rdi
movq %rax, %rsi
jmp 0x4946