// File: /workspace/github_cpp_makefile_star2_O3/tewalds[P]morat/hex/../lib/compacttree.h
// Function: Morat::CompactTree<Morat::Hex::AgentMCTS::Node>::compact(float, float)
void compact(float arenasize = 0, float generationsize = 0){
		assert(arenasize >= 0 && arenasize <= 1);
		assert(generationsize >= 0 && generationsize <= 1);

		memused = 0;

		if(head->used == 0)
			return;

		//clear the freelist
		freelist.clear();

		Chunk      * schunk = head; //source chunk
		unsigned int soff   = 0;    //source offset
		Chunk      * dchunk = schunk; //destination chunk
		unsigned int doff   = soff;   //destination offset

		unsigned int generationid = (unsigned int)(generationsize * current->id);
		bool compactthischunk = (generationid == 0);

		//iterate over each chunk, moving data blocks to the left to fill empty space
		while(schunk != NULL){
			//iterate over each Data block
			Data * s = (Data *)(schunk->mem + soff);
			assert(s->capacity > 0 && s->capacity < MAX_NUM);

			int ssize = s->mem_size(); //how much to move the source pointer

			//move from -> to, update parent pointer
			if(s->empty()){
				if(!compactthischunk){
					if(s->old()){//this empty segment is an unpopular size, lets compact this chunk to clean up this segment
						compactthischunk = true;
						dchunk = schunk;
						doff = soff;
					}else{ //freed recently, add to the free list
						freelist.push_nolock(s);
						s->header++; //empty, but a generation old
					}
				}//else this position will be overwritten by the next full chunk
			}else{
				if(!compactthischunk){
					memused += ssize;
				}else{
					assert(s->used > 0 && s->used <= s->capacity);
					int dsize = s->memused(); //how much to move the dest pointer
					Data * d = NULL;

					//where to move
					while(1){
						if((d = freelist.pop_nolock(s->used))){ //allocate off the freelist if possible
							break;
						}else if(doff + dsize <= dchunk->capacity){ //if space, allocate from this chunk
							assert(schunk->id > dchunk->id || (schunk == dchunk && soff >= doff)); //make sure I'm moving left
							d = (Data *)(dchunk->mem + doff);
							doff += dsize;
							break;
						}else{ //otherwise finish this chunk and prepare the next
							dchunk->used = doff;
							dchunk->clear_unused();

							dchunk = dchunk->next;
							doff = 0;
						}
					}

					//move!
					s->capacity = s->used;
					if(s != d){
						memmove(reinterpret_cast<void*>(d), reinterpret_cast<void*>(s), dsize);
						d->move(s);
					}
					memused += dsize;
				}
			}

			//update source
			soff += ssize;
			while(schunk && schunk->used <= soff){ //move forward, skip empty chunks
				//if the last chunk was being compacted out of order, finish it off
				if(schunk->id < generationid && compactthischunk){
					dchunk->used = doff;
					dchunk->clear_unused();
				}
				//go to the next source chunk
				schunk = schunk->next;
				soff = 0;
				//if we're done the static generation, initialize the destination chunk
				if(schunk){
					if(schunk->id == generationid){
						dchunk = schunk;
						doff = soff;
					}
					compactthischunk = (schunk->id >= generationid);
				}
			}
		}

		//finish the last used chunk
		dchunk->used = doff;
		dchunk->clear_unused();

		//free unused chunks
		Chunk * del = dchunk;
		while(del->next && del->id < arenasize*current->id){
			del = del->next;
			del->used = 0;
		}

		if(del->next != NULL){
			del->next->dealloc(true);
			delete del->next;
			del->next = NULL;
			numchunks = del->id + 1;
		}

		//set current to head in case some chunks aren't filled completely due to generations
		current = head;
		last = dchunk;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
vxorps %xmm2, %xmm2, %xmm2
vucomiss %xmm2, %xmm0
jb 0x128ff
vmovss 0x1fca8(%rip), %xmm2    # 0x32200
vucomiss %xmm0, %xmm2
jb 0x128ff
vxorps %xmm3, %xmm3, %xmm3
vucomiss %xmm3, %xmm1
jb 0x1291e
vucomiss %xmm1, %xmm2
jb 0x1291e
movq $0x0, 0x13b8(%rdi)
movq %rdi, %r13
movq (%rdi), %r12
cmpl $0x0, 0x10(%r12)
je 0x128d1
leaq 0x20(%r13), %rdi
movl $0x1390, %edx           # imm = 0x1390
xorl %esi, %esi
vmovss %xmm1, 0x18(%rsp)
vmovss %xmm0, 0x8(%rsp)
movq %rdi, 0x10(%rsp)
callq 0x51a0
movq 0x18(%r12), %r9
vmovss 0x8(%rsp), %xmm1
movl 0x4(%r9), %edx
leal -0x1(%rdx), %eax
cmpw $0x270, %ax             # imm = 0x270
ja 0x128e0
movq 0x8(%r13), %rax
vcvtusi2ssl 0x8(%rax), %xmm4, %xmm0
leaq 0x4(%r9), %rax
movq %r12, %r14
vmulss 0x18(%rsp), %xmm0, %xmm0
movq %rax, 0x18(%rsp)
vcvttss2usi %xmm0, %ebx
testl %ebx, %ebx
sete %cl
xorl %eax, %eax
xorl %r8d, %r8d
movzwl %dx, %edx
movl (%r9), %esi
leaq (%rdx,%rdx,2), %r11
shll $0x4, %r11d
addq $0x40, %r11
cmpl $0x4, %esi
ja 0x12659
testb $0x1, %cl
jne 0x126b5
movl %ecx, %r10d
movb $0x1, %cl
movl %r8d, %r15d
movq %r14, %rbp
cmpl $0x4, %esi
je 0x12777
movq 0x10(%rsp), %rdi
incl %esi
movl %eax, %r15d
movq %r12, %rbp
movq (%rdi,%rdx,8), %rcx
movq %rcx, 0x8(%r9)
movq %r9, (%rdi,%rdx,8)
movl %esi, (%r9)
movl %r10d, %ecx
jmp 0x12777
testb $0x1, %cl
je 0x126ae
movb %cl, 0x7(%rsp)
movzwl 0x6(%r9), %ecx
movq %r13, 0x30(%rsp)
leal -0x1(%rcx), %esi
cmpw %dx, %si
jae 0x1293d
movq 0x10(%rsp), %rsi
movzwl %cx, %edx
movl %r8d, 0xc(%rsp)
movq %r11, 0x28(%rsp)
movq %r12, %rbp
leaq (%rdx,%rdx,2), %r10
shll $0x4, %r10d
addq $0x40, %r10
movq (%rsi,%rdx,8), %r13
movq %r10, 0x20(%rsp)
testq %r13, %r13
je 0x126c0
movq 0x10(%rsp), %r12
jmp 0x1271e
addq %r11, 0x13b8(%r13)
movl %eax, %r15d
movq %r12, %rbp
jmp 0x12777
movq 0x10(%rsp), %r12
movl 0xc(%rbp), %edx
leal (%rax,%r10), %r15d
cmpl %edx, %r15d
jbe 0x1280a
movl %eax, 0x10(%rbp)
cmpl %edx, %eax
je 0x1270c
movl %eax, %edi
subq %rdi, %rdx
addq 0x18(%rbp), %rdi
xorl %esi, %esi
movq %r9, %r15
callq 0x51a0
vmovss 0x8(%rsp), %xmm1
movq 0x20(%rsp), %r10
movq 0x28(%rsp), %r11
movl 0xc(%rsp), %r8d
movzwl 0x6(%r15), %ecx
movq %r15, %r9
movzwl %cx, %edx
movq (%rbp), %rbp
xorl %eax, %eax
movq (%r12,%rdx,8), %r13
testq %r13, %r13
je 0x126c5
movq 0x8(%r13), %rsi
movl %eax, %r15d
movq %rsi, (%r12,%rdx,8)
movq 0x18(%rsp), %rax
movw %cx, (%rax)
cmpq %r13, %r9
je 0x12767
movq %r13, %rdi
movq %r9, %rsi
movq %r10, %rdx
movq %r9, %r12
callq 0x55d0
movq %r13, %rdi
movq %r12, %rsi
callq 0x13dc2
vmovss 0x8(%rsp), %xmm1
movq 0x20(%rsp), %r10
movq 0x28(%rsp), %r11
movl 0xc(%rsp), %r8d
movq 0x30(%rsp), %r13
movb 0x7(%rsp), %cl
addq %r10, 0x13b8(%r13)
addl %r11d, %r8d
cmpl %r8d, 0x10(%r14)
ja 0x127d9
xorl %r12d, %r12d
cmpl %ebx, 0x8(%r14)
jae 0x127b1
testb $0x1, %cl
je 0x127b1
movl %r15d, 0x10(%rbp)
movl 0xc(%rbp), %edx
cmpl %edx, %r15d
je 0x127b1
movl %r15d, %edi
subq %rdi, %rdx
addq 0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x51a0
vmovss 0x8(%rsp), %xmm1
movq (%r14), %r14
testq %r14, %r14
je 0x12831
movl 0x8(%r14), %eax
cmpl %ebx, %eax
cmovel %r12d, %r15d
cmoveq %r14, %rbp
setae %cl
cmpl $0x0, 0x10(%r14)
je 0x12783
cmpl %ebx, %eax
setae %cl
xorl %r8d, %r8d
movq 0x18(%r14), %rax
movl %r8d, %edx
movq %rbp, %r12
leaq (%rax,%rdx), %r9
leaq 0x4(%rax,%rdx), %rax
movl (%rax), %edx
movq %rax, 0x18(%rsp)
movl %r15d, %eax
movl %edx, %esi
decl %esi
cmpw $0x271, %si             # imm = 0x271
jb 0x12601
jmp 0x128e0
movl 0x8(%r14), %edx
cmpl 0x8(%rbp), %edx
ja 0x12825
cmpq %rbp, %r14
jne 0x1295c
cmpl %eax, %r8d
jb 0x1295c
movl %eax, %r13d
addq 0x18(%rbp), %r13
jmp 0x12729
movl %r15d, 0x10(%rbp)
movl 0xc(%rbp), %edx
cmpl %edx, %r15d
je 0x12854
movl %r15d, %edi
subq %rdi, %rdx
addq 0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x51a0
vmovss 0x8(%rsp), %xmm1
movq (%rbp), %rax
testq %rax, %rax
je 0x128c5
movq 0x8(%r13), %rcx
vcvtusi2ssl 0x8(%rcx), %xmm4, %xmm0
movq %rbp, %rbx
vmulss %xmm1, %xmm0, %xmm0
vcvtusi2ssl 0x8(%rbx), %xmm4, %xmm1
movq %rax, %rdi
vucomiss %xmm1, %xmm0
jbe 0x12893
movl $0x0, 0x10(%rdi)
movq %rdi, %rbx
movq (%rdi), %rax
testq %rax, %rax
jne 0x1286f
jmp 0x128c5
movl $0x1, %esi
callq 0x13ea2
movq (%rbx), %r14
testq %r14, %r14
je 0x128ad
movq %r14, %rdi
callq 0x13d88
movq %r14, %rdi
callq 0x52e0
movq $0x0, (%rbx)
movl 0x8(%rbx), %eax
incl %eax
movl %eax, 0x18(%r13)
movq (%r13), %rax
movq %rax, 0x8(%r13)
movq %rbp, 0x10(%r13)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2043e(%rip), %rdi     # 0x32d25
leaq 0x1ff57(%rip), %rsi     # 0x32845
leaq 0x20394(%rip), %rcx     # 0x32c89
movl $0x191, %edx            # imm = 0x191
callq 0x51d0
leaq 0x20362(%rip), %rdi     # 0x32c68
leaq 0x1ff38(%rip), %rsi     # 0x32845
leaq 0x20375(%rip), %rcx     # 0x32c89
movl $0x17a, %edx            # imm = 0x17A
callq 0x51d0
leaq 0x203d5(%rip), %rdi     # 0x32cfa
leaq 0x1ff19(%rip), %rsi     # 0x32845
leaq 0x20356(%rip), %rcx     # 0x32c89
movl $0x17b, %edx            # imm = 0x17B
callq 0x51d0
leaq 0x2040a(%rip), %rdi     # 0x32d4e
leaq 0x1fefa(%rip), %rsi     # 0x32845
leaq 0x20337(%rip), %rcx     # 0x32c89
movl $0x1a5, %edx            # imm = 0x1A5
callq 0x51d0
leaq 0x20411(%rip), %rdi     # 0x32d74
leaq 0x1fedb(%rip), %rsi     # 0x32845
leaq 0x20318(%rip), %rcx     # 0x32c89
movl $0x1ae, %edx            # imm = 0x1AE
callq 0x51d0
nop