// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]optimal-seed-solver/optimalSolver.cc
// Function: OptimalSolver::init(int, int)
void OptimalSolver::init(int readLength, int seedNum) {
	//Initialize the matrix
	if (matrix != NULL) {
		delete [] matrix;
		matrix = NULL;
	}

	this->readLength = readLength;

	if (readLength >= seedNum * tree.getHashLength() )
		this->seedNum = seedNum;
	else
		this->seedNum = readLength / tree.getHashLength();

	//Position count for the level
	int lvPosCount;

	//Matrix overall size
	int matrixSize = 0;

	//For the first 1 seed case, we need to consider all cases
	lvPosCount = readLength + 1 - tree.getHashLength();
	matrixSize += (lvPosCount + 1) * lvPosCount / 2;

	//For the next N-2 seed cases, we need to consider all cases, while leaving
	//the last minLength out (because we don't need to)
	for (int i = 1; i < this->seedNum - 1; i++) {
		//Notice that for the rest levels, we do not need to consider the last
		//hashLength positions
		lvPosCount = readLength + 1 - tree.getHashLength() * (i + 2);
		matrixSize += (lvPosCount + 1) * lvPosCount / 2;
	}

	//For the last seed, it's simpler all cases for dividers
	lvPosCount = readLength + 1 - this->seedNum * tree.getHashLength();
	matrixSize += lvPosCount;

	//Allocate space for the matrix
	matrix = new Cell[matrixSize];
	defaultCells = new Cell[matrixSize];

	//Progress counter
	int matrixProgress = 0;
	//sublevel counter
	int levelIdx = 0;
	//Fill the level pointers
	level.resize(this->seedNum);
	//Find the first row
	lvPosCount = readLength + 1 - tree.getHashLength();
	level[0].resize(lvPosCount);
	for (int i = lvPosCount; i > 0; i--) {
		level[0][levelIdx] = matrix + matrixProgress;
		matrixProgress += i;
		levelIdx++;
	}

	//Find the reminding levels
	for (int idx = 1; idx < this->seedNum - 1; idx++) {
		lvPosCount = readLength + 1 - tree.getHashLength() * (idx + 2);
		level[idx].resize(lvPosCount);
		//reset the sublevel counter
		levelIdx = 0;
		for (int i = lvPosCount; i > 0; i--) {
			level[idx][levelIdx] = matrix + matrixProgress;
			matrixProgress += i;
			levelIdx++;
		}
	}

	//Set the last level
	level[this->seedNum - 1].resize(1);
	level[this->seedNum - 1][0] = matrix + matrixProgress;

	//Just to check the matrixSize
	assert (matrixProgress + readLength + 1 - this->seedNum * tree.getHashLength() == matrixSize);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, %ebp
movl %esi, %ebx
movq %rdi, %r14
movq 0x368(%rdi), %rdi
testq %rdi, %rdi
je 0x48ab
callq 0x3340
movq $0x0, 0x368(%r14)
movl %ebx, 0x35c(%r14)
movq %r14, %rdi
callq 0x749e
imull %ebp, %eax
cmpl %ebx, %eax
jbe 0x48d3
movq %r14, %rdi
callq 0x749e
movl %eax, %ecx
movl %ebx, %eax
xorl %edx, %edx
divl %ecx
movl %eax, %ebp
movl %ebp, 0x360(%r14)
movq %rbx, 0x10(%rsp)
leal 0x1(%rbx), %ebp
movq %r14, %rdi
callq 0x749e
movl %ebp, %ecx
subl %eax, %ecx
leal 0x1(%rcx), %eax
imull %ecx, %eax
movl %eax, %ebx
shrl $0x1f, %ebx
addl %eax, %ebx
sarl %ebx
movl 0x360(%r14), %r12d
cmpl $0x3, %r12d
jl 0x4948
movl $0x1, %r15d
movq %r14, %rdi
callq 0x749e
leal 0x2(%r15), %ecx
imull %eax, %ecx
movl %ebp, %eax
subl %ecx, %eax
leal 0x1(%rax), %ecx
imull %eax, %ecx
movl %ecx, %eax
shrl $0x1f, %eax
addl %ecx, %eax
sarl %eax
addl %eax, %ebx
incl %r15d
movl 0x360(%r14), %r12d
leal -0x1(%r12), %eax
cmpl %eax, %r15d
jl 0x4910
movq %r14, %rdi
callq 0x749e
imull %r12d, %eax
movl %ebp, %r13d
subl %eax, %r13d
addl %ebx, %r13d
movslq %r13d, %r15
movl $0x28, %ecx
movq %r15, %rax
mulq %rcx
movq $-0x1, %r12
cmovnoq %rax, %r12
movq %r12, %rdi
callq 0x3030
testl %r15d, %r15d
je 0x49b0
leaq (%r15,%r15,4), %rcx
leaq (%rax,%rcx,8), %rcx
pcmpeqd %xmm0, %xmm0
movq %rax, %rdx
movq $-0x1, (%rdx)
movb $0x0, 0x8(%rdx)
movdqu %xmm0, 0xc(%rdx)
movdqu %xmm0, 0x18(%rdx)
addq $0x28, %rdx
cmpq %rcx, %rdx
jne 0x4992
movq %rax, 0x368(%r14)
movq %r12, %rdi
callq 0x3030
testl %r13d, %r13d
je 0x49f1
leaq (%r15,%r15,4), %rcx
leaq (%rax,%rcx,8), %rcx
pcmpeqd %xmm0, %xmm0
movq %rax, %rdx
movq $-0x1, (%rdx)
movb $0x0, 0x8(%rdx)
movdqu %xmm0, 0xc(%rdx)
movdqu %xmm0, 0x18(%rdx)
addq $0x28, %rdx
cmpq %rcx, %rdx
jne 0x49d3
movl %r13d, 0x4(%rsp)
movq %rax, 0x388(%r14)
leaq 0x370(%r14), %rdi
movslq 0x360(%r14), %rsi
callq 0x5ffc
movq %r14, %rdi
callq 0x749e
movl %ebp, %ebx
subl %eax, %ebx
movq 0x370(%r14), %rdi
movslq %ebx, %r15
movq %r15, %rsi
callq 0x6038
testl %r15d, %r15d
jle 0x4a6e
movl %ebx, %eax
shlq $0x3, %rax
xorl %ecx, %ecx
xorl %r13d, %r13d
movl %r13d, %edx
leaq (%rdx,%rdx,4), %rdx
shlq $0x3, %rdx
addq 0x368(%r14), %rdx
movq 0x370(%r14), %rsi
movq (%rsi), %rsi
movq %rdx, (%rsi,%rcx)
addl %ebx, %r13d
addq $0x8, %rcx
decl %ebx
cmpq %rcx, %rax
jne 0x4a3e
jmp 0x4a71
xorl %r13d, %r13d
movl 0x360(%r14), %eax
cmpl $0x3, %eax
jl 0x4b45
movl %ebp, 0xc(%rsp)
movq 0x10(%rsp), %rax
addl $0x2, %eax
movl %eax, 0x8(%rsp)
movl $0xfffffffd, %esi       # imm = 0xFFFFFFFD
movl $0x1, %ebp
movl %esi, (%rsp)
movq %r14, %rdi
callq 0x749e
movl %eax, %r15d
leal 0x2(%rbp), %eax
imull %r15d, %eax
movl 0xc(%rsp), %ecx
subl %eax, %ecx
leaq (,%rbp,2), %rbx
addq %rbp, %rbx
leaq (,%rbx,8), %rdi
addq 0x370(%r14), %rdi
movslq %ecx, %r12
movq %r12, %rsi
callq 0x6038
testl %r12d, %r12d
jle 0x4b28
movl (%rsp), %esi
imull %esi, %r15d
addl 0x8(%rsp), %r15d
xorl %eax, %eax
movl %r13d, %ecx
leaq (%rcx,%rcx,4), %rcx
shlq $0x3, %rcx
addq 0x368(%r14), %rcx
movq 0x370(%r14), %rdx
movq (%rdx,%rbx,8), %rdx
movq %rcx, (%rdx,%rax)
addl %r15d, %r13d
decl %r13d
movl %r15d, %ecx
decl %ecx
addq $0x8, %rax
movl %ecx, %r15d
cmpl $0x1, %ecx
jg 0x4aee
jmp 0x4b2b
movl (%rsp), %esi
incq %rbp
movslq 0x360(%r14), %rax
decq %rax
decl %esi
cmpq %rax, %rbp
jl 0x4a9b
jmp 0x4b47
decl %eax
cltq
leaq (%rax,%rax,2), %rdi
shlq $0x3, %rdi
addq 0x370(%r14), %rdi
movl $0x1, %esi
callq 0x6038
movl %r13d, %eax
leaq (%rax,%rax,4), %rax
shlq $0x3, %rax
addq 0x368(%r14), %rax
movslq 0x360(%r14), %rbx
movq 0x370(%r14), %rcx
leaq (%rbx,%rbx,2), %rdx
movq -0x18(%rcx,%rdx,8), %rcx
movq %rax, (%rcx)
movq %r14, %rdi
callq 0x749e
imull %ebx, %eax
movq 0x10(%rsp), %rcx
addl %r13d, %ecx
subl %eax, %ecx
incl %ecx
cmpl 0x4(%rsp), %ecx
jne 0x4bba
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6503(%rip), %rdi      # 0xb0c4
leaq 0x6551(%rip), %rsi      # 0xb119
leaq 0x655b(%rip), %rcx      # 0xb12a
movl $0x71, %edx
callq 0x3190
nop