// File: /workspace/github_cpp_makefile_star2_O2/dudulu233[P]EMA-Tool/ema_tool.cpp
// Function: main
int main(int argc, char* argv[])
{
	if (2 != argc)
	{
		printf("Usage: ./ema_tool config_file_name\n");
		exit(-1);
	}

	if (0 != access(argv[1], F_OK))
	{
		printf("Error, config file %s not exist\n");
		exit(-1);
	}

	_time_analysis.set_start_time();

	bool get_reuse_dis = false;
	uint64 total_trace_cnt = 0;

	cfg_ema* cfg = new cfg_ema();
	string conf_file_name(argv[1]);
	assert(NULL != cfg);
	get_cfg(conf_file_name.c_str(), cfg);

	StatCache* sc = new StatCache(cfg->io_trace_start_time);
	IoRecord* io_trace = new IoRecord();
	LogClear();
	
	LogWrite(1, "process start~");

	FILE* fp = fopen(cfg->cache_file.c_str(), "r");

	_time_analysis.set_end_time();
	_time_analysis.add_time("ema init time");

	while (1) {
		assert(NULL != fp);
		assert(NULL != io_trace);

		_time_analysis.set_start_time();

		if(fscanf(fp, "%lu,%lu",
			&io_trace->alloc_time,
			&io_trace->cache_addr
		) == EOF) break;

		_time_analysis.set_end_time();
		_time_analysis.add_time("read trace");

		//program begin

		if (io_trace->alloc_time < cfg->io_trace_start_time) {
			continue;
		}
		//begin to get the reuse distance
		if (io_trace->alloc_time >= cfg->re_dis_start_time) {
			get_reuse_dis = true;
		}

		//hash(A) mod P < T, sampling rate = T / P * 100%
		//e.g. P=100, T=1,so the sampling rate = 0.01
		string str_cache_addr = to_string(static_cast<long long>(io_trace->cache_addr));
		uint32_t hash = murmurhash(str_cache_addr.c_str(), (str_cache_addr).length(), 0);

		total_trace_cnt++;
		if (hash % cfg->sampling_P < cfg->sampling_T) {
			sc->main_operation(io_trace, get_reuse_dis, cfg->cache_size, cfg->sampling_P, cfg->sampling_T);
		}

		//finish
		if (io_trace->alloc_time >= cfg->io_trace_end_time) {
			sc->main_operation(io_trace, get_reuse_dis, cfg->cache_size, cfg->sampling_P, cfg->sampling_T);
			break;
		}

		
	}


	_time_analysis.set_start_time();
	sc->output_reuse_distance();
	_time_analysis.set_end_time();
	_time_analysis.add_time("output time");

	_time_analysis.print_all_latency();

	string map_size_info = "map_size: " + to_string(static_cast<long long>(sc->get_map_size()));
	int unique_ratio = total_trace_cnt * cfg->sampling_T / sc->get_map_size() / cfg->sampling_P;
	LogWrite(1, map_size_info.c_str());
	string unique_ratio_info = "unique_ratio: 1/" + to_string(static_cast<long long>(unique_ratio));
	LogWrite(1, unique_ratio_info.c_str());
	LogWrite(1, "process end~~");

	delete io_trace;
	io_trace = NULL;
	delete sc;
	sc = NULL;

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
cmpl $0x2, %edi
jne 0x3395
movq %rsi, %rbx
movq 0x8(%rsi), %rdi
xorl %esi, %esi
callq 0x23d0
testl %eax, %eax
jne 0x33a3
leaq 0x58c4(%rip), %rdi      # 0x8650
callq 0x4820
pushq $0x50
popq %rdi
callq 0x2270
movq %rax, %r14
addq $0x10, %rax
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%r14)
movaps %xmm0, 0x20(%r14)
movaps %xmm0, 0x30(%r14)
movaps %xmm0, 0x40(%r14)
movq %rax, (%r14)
andq $0x0, 0x8(%r14)
movq 0x8(%rbx), %rsi
leaq 0xc8(%rsp), %rbx
leaq 0x18(%rsp), %rdx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rdi
movq %r14, (%rsp)
movq %r14, %rsi
callq 0x2757
movl $0x25a0, %edi           # imm = 0x25A0
callq 0x2270
movq (%rsp), %rcx
movq 0x38(%rcx), %rsi
movq %rax, 0x8(%rsp)
movq %rax, %rdi
callq 0x36b4
pushq $0x10
popq %rdi
callq 0x2270
xorps %xmm0, %xmm0
movq %rax, 0x10(%rsp)
movaps %xmm0, (%rax)
callq 0x26a0
movq 0x519b(%rip), %rax      # 0x7fc0
movq (%rax), %rcx
leaq 0x2356(%rip), %r14      # 0x5185
pushq $0xe
popq %rsi
pushq $0x1
popq %rdx
movq %r14, %rdi
callq 0x2420
pushq $0xa
popq %rdi
callq 0x2340
movq 0x53e4(%rip), %rdi      # 0x8230
leaq 0x2341(%rip), %rsi      # 0x5194
callq 0x22b0
movq %rax, %rbx
movq %rax, 0x53f6(%rip)      # 0x8258
leaq 0x168(%rsp), %rdi
leaq 0x18(%rsp), %rdx
movq %r14, %rsi
callq 0x2110
pushq $0x1
popq %rdi
leaq 0x168(%rsp), %r14
movq %r14, %rsi
callq 0x25dc
leaq 0x53cf(%rip), %rsi      # 0x8260
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2350
movq %r14, %rdi
callq 0x2150
movq 0x53ae(%rip), %rdi      # 0x8258
callq 0x22a0
movq 0x53a2(%rip), %rdi      # 0x8258
callq 0x2260
movq (%rsp), %rax
movq (%rax), %rdi
leaq 0x22cd(%rip), %rsi      # 0x5196
callq 0x22b0
movq %rax, %r13
leaq 0x5778(%rip), %rdi      # 0x8650
callq 0x4828
leaq 0x22b4(%rip), %rsi      # 0x5198
leaq 0xa8(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x2110
leaq 0x5753(%rip), %rdi      # 0x8650
leaq 0xa8(%rsp), %rsi
callq 0x4834
leaq 0xa8(%rsp), %rdi
callq 0x2150
testq %r13, %r13
je 0x33b9
movq 0x10(%rsp), %r14
addq $0x8, %r14
movq $0x0, 0x38(%rsp)
leaq 0x5717(%rip), %rbx      # 0x8650
leaq 0x2271(%rip), %r12      # 0x51b1
leaq 0x148(%rsp), %r15
leaq 0x18(%rsp), %rbp
movq $0x0, 0x40(%rsp)
movq %rbx, %rdi
callq 0x4820
movq %r13, %rdi
movq %r12, %rsi
movq 0x10(%rsp), %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2410
cmpl $-0x1, %eax
je 0x3088
movq %rbx, %rdi
callq 0x4828
movq %r15, %rdi
leaq 0x222b(%rip), %rsi      # 0x51b9
movq %rbp, %rdx
callq 0x2110
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4834
movq %r15, %rdi
callq 0x2150
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq (%rsp), %rcx
cmpq 0x38(%rcx), %rax
jb 0x2f56
movq (%rsp), %rcx
cmpq 0x40(%rcx), %rax
movq 0x38(%rsp), %r12
movzbl %r12b, %r12d
pushq $0x1
popq %rax
cmovael %eax, %r12d
movq (%r14), %rsi
movq %rbp, %rdi
callq 0x349f
movq 0x18(%rsp), %rdi
movl 0x20(%rsp), %esi
xorl %edx, %edx
callq 0x2c9b
movq (%rsp), %rcx
movl 0x24(%rcx), %r8d
movl 0x28(%rcx), %r9d
xorl %edx, %edx
divl %r8d
movq %r12, 0x38(%rsp)
movzbl %r12b, %r10d
cmpl %r9d, %edx
jae 0x3033
movq (%rsp), %rax
movl 0x20(%rax), %ecx
movl %r10d, %edx
andl $0x1, %edx
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl %r10d, %r12d
callq 0x3812
movl %r12d, %r10d
movq (%rsp), %rcx
incq 0x40(%rsp)
movq 0x10(%rsp), %rax
movq (%rax), %rax
cmpq 0x48(%rcx), %rax
leaq 0x2166(%rip), %r12      # 0x51b1
jae 0x305a
movq %rbp, %rdi
callq 0x2150
jmp 0x2f56
movq %rcx, %rax
movl 0x20(%rcx), %ecx
movl 0x24(%rax), %r8d
movl 0x28(%rax), %r9d
andl $0x1, %r10d
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl %r10d, %edx
callq 0x3812
leaq 0x18(%rsp), %rdi
callq 0x2150
leaq 0x55c1(%rip), %rdi      # 0x8650
callq 0x4820
movq 0x8(%rsp), %rdi
callq 0x3e32
leaq 0x55ab(%rip), %rdi      # 0x8650
callq 0x4828
leaq 0x2113(%rip), %rsi      # 0x51c4
leaq 0x88(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x2110
leaq 0x5586(%rip), %rdi      # 0x8650
leaq 0x88(%rsp), %rsi
callq 0x4834
leaq 0x88(%rsp), %rdi
callq 0x2150
leaq 0x5565(%rip), %rdi      # 0x8650
callq 0x4960
movq 0x8(%rsp), %rdi
callq 0x3ed8
leaq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0x349f
leaq 0x20c2(%rip), %rsi      # 0x51d0
leaq 0x18(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x34ff
movq 0x4e9c(%rip), %r13      # 0x7fc0
leaq 0x48(%rsp), %rdi
callq 0x2150
movq (%rsp), %r14
movslq 0x28(%r14), %r15
movq 0x8(%rsp), %rdi
callq 0x3ed8
movq %rax, %rbx
movslq 0x24(%r14), %r12
movq (%r13), %rdi
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0x2350
pushq $0xa
popq %rdi
callq 0x2340
movq 0x50ca(%rip), %rdi      # 0x8230
leaq 0x2027(%rip), %rsi      # 0x5194
callq 0x22b0
movq %rax, %r14
movq %rax, 0x50dc(%rip)      # 0x8258
movq 0x18(%rsp), %rsi
leaq 0x128(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x2110
movq 0x40(%rsp), %rax
imulq %r15, %rax
xorl %edx, %edx
divq %rbx
xorl %edx, %edx
divq %r12
movq %rax, %rbx
pushq $0x1
popq %rdi
leaq 0x128(%rsp), %r15
movq %r15, %rsi
callq 0x25dc
leaq 0x509d(%rip), %rsi      # 0x8260
movq %r14, %rdi
xorl %eax, %eax
callq 0x2350
movq %r15, %rdi
callq 0x2150
movq 0x507c(%rip), %rdi      # 0x8258
callq 0x22a0
movq 0x5070(%rip), %rdi      # 0x8258
callq 0x2260
movslq %ebx, %rsi
leaq 0x68(%rsp), %rdi
callq 0x349f
leaq 0x1fda(%rip), %rsi      # 0x51db
leaq 0x48(%rsp), %rdi
leaq 0x68(%rsp), %rdx
callq 0x34ff
leaq 0x68(%rsp), %rdi
callq 0x2150
movq (%r13), %rdi
movq 0x48(%rsp), %rsi
xorl %eax, %eax
callq 0x2350
pushq $0xa
popq %rdi
callq 0x2340
movq 0x4ff7(%rip), %rdi      # 0x8230
leaq 0x1f54(%rip), %rsi      # 0x5194
callq 0x22b0
movq %rax, %rbx
movq %rax, 0x5009(%rip)      # 0x8258
movq 0x48(%rsp), %rsi
leaq 0x108(%rsp), %rdi
leaq 0x68(%rsp), %rdx
callq 0x2110
pushq $0x1
popq %rdi
leaq 0x108(%rsp), %r14
movq %r14, %rsi
callq 0x25dc
leaq 0x4fe0(%rip), %rsi      # 0x8260
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2350
movq %r14, %rdi
callq 0x2150
movq 0x4fbf(%rip), %rdi      # 0x8258
callq 0x22a0
movq 0x4fb3(%rip), %rdi      # 0x8258
callq 0x2260
movq (%r13), %rcx
leaq 0x1f37(%rip), %r14      # 0x51ec
pushq $0xd
popq %rsi
pushq $0x1
popq %rdx
movq %r14, %rdi
callq 0x2420
pushq $0xa
popq %rdi
callq 0x2340
movq 0x4f5e(%rip), %rdi      # 0x8230
leaq 0x1ebb(%rip), %rsi      # 0x5194
callq 0x22b0
movq %rax, %rbx
movq %rax, 0x4f70(%rip)      # 0x8258
leaq 0xe8(%rsp), %rdi
leaq 0x68(%rsp), %rdx
movq %r14, %rsi
callq 0x2110
pushq $0x1
popq %rdi
leaq 0xe8(%rsp), %r14
movq %r14, %rsi
callq 0x25dc
leaq 0x4f49(%rip), %rsi      # 0x8260
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2350
movq %r14, %rdi
callq 0x2150
movq 0x4f28(%rip), %rdi      # 0x8258
callq 0x22a0
movq 0x4f1c(%rip), %rdi      # 0x8258
callq 0x2260
movq 0x10(%rsp), %rdi
callq 0x2240
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
callq 0x37f2
movq %rbx, %rdi
callq 0x2240
leaq 0x48(%rsp), %rdi
callq 0x2150
leaq 0x18(%rsp), %rdi
callq 0x2150
leaq 0xc8(%rsp), %rdi
callq 0x2150
xorl %eax, %eax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1ebe(%rip), %rdi      # 0x525a
callq 0x2390
jmp 0x33b1
leaq 0x1d96(%rip), %rdi      # 0x5140
xorl %eax, %eax
callq 0x2040
pushq $-0x1
popq %rdi
callq 0x22d0
leaq 0x1de6(%rip), %rdi      # 0x51a6
leaq 0x1d9a(%rip), %rsi      # 0x5161
leaq 0x1da0(%rip), %rcx      # 0x516e
movl $0xbf, %edx
callq 0x2190
jmp 0x3400
jmp 0x3400
jmp 0x3461
jmp 0x33e3
movq %rax, %r14
leaq 0x48(%rsp), %rdi
jmp 0x33f5
movq %rax, %r14
leaq 0x68(%rsp), %rdi
callq 0x2150
jmp 0x3403
jmp 0x3400
jmp 0x3400
movq %rax, %r14
leaq 0x18(%rsp), %rdi
jmp 0x345a
movq %rax, %r14
leaq 0x48(%rsp), %rdi
jmp 0x345a
movq %rax, %r14
leaq 0x88(%rsp), %rdi
jmp 0x345a
jmp 0x3461
movq %rax, %r14
leaq 0xa8(%rsp), %rdi
jmp 0x345a
jmp 0x3461
jmp 0x3461
jmp 0x3461
movq %rax, %r14
movq 0x8(%rsp), %rdi
callq 0x2240
jmp 0x3464
jmp 0x3461
jmp 0x3461
jmp 0x3461
jmp 0x3461
jmp 0x3461
movq %rax, %r14
leaq 0x148(%rsp), %rdi
callq 0x2150
jmp 0x3464
movq %rax, %r14
leaq 0xc8(%rsp), %rdi
callq 0x2150
movq %r14, %rdi
callq 0x23e0