// File: /workspace/github_cpp_makefile_star2_O1/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 0x127ce
vmovss 0x1fe24(%rip), %xmm2    # 0x32200
vucomiss %xmm0, %xmm2
jb 0x127ce
vxorps %xmm3, %xmm3, %xmm3
vucomiss %xmm3, %xmm1
jb 0x127ed
vucomiss %xmm1, %xmm2
jb 0x127ed
movq %rdi, %rbx
movq $0x0, 0x13b8(%rdi)
movq (%rdi), %rbp
cmpl $0x0, 0x10(%rbp)
je 0x12781
vmovss %xmm1, 0x10(%rsp)
vmovss %xmm0, 0xc(%rsp)
leaq 0x20(%rbx), %rdi
xorl %r12d, %r12d
movl $0x1390, %edx           # imm = 0x1390
movq %rdi, 0x18(%rsp)
xorl %esi, %esi
callq 0x51a0
testq %rbp, %rbp
movq %rbx, 0x20(%rsp)
je 0x126b9
movq 0x8(%rbx), %rax
vcvtusi2ssl 0x8(%rax), %xmm4, %xmm0
vmulss 0x10(%rsp), %xmm0, %xmm0
vcvttss2usi %xmm0, %ebx
testl %ebx, %ebx
sete %r10b
xorl %r8d, %r8d
xorl %r14d, %r14d
movq %rbp, %r9
xorl %eax, %eax
vmovss 0xc(%rsp), %xmm1
movq 0x18(%rbp), %r15
movl %r14d, %edx
movzwl 0x4(%r15,%rdx), %ecx
leal -0x1(%rcx), %esi
cmpw $0x271, %si             # imm = 0x271
jae 0x12790
addq %rdx, %r15
leaq (%rcx,%rcx,2), %r11
shll $0x4, %r11d
addq $0x40, %r11
movl (%r15), %edx
cmpl $0x4, %edx
ja 0x124e9
testb $0x1, %r10b
jne 0x1254e
movq %r15, 0x10(%rsp)
movb $0x1, %r15b
movl %r14d, %r12d
movq %rbp, %r13
cmpl $0x4, %edx
je 0x12643
movq 0x18(%rsp), %rdi
movq (%rdi,%rcx,8), %rsi
movq 0x10(%rsp), %r15
movq %rsi, 0x8(%r15)
movq %r15, (%rdi,%rcx,8)
incl %edx
movl %edx, (%r15)
jmp 0x1254e
testb $0x1, %r10b
je 0x12542
movzwl 0x6(%r15), %edx
leal -0x1(%rdx), %esi
cmpw %cx, %si
jae 0x127af
leaq (%rdx,%rdx,2), %rdi
shll $0x4, %edi
addq $0x40, %rdi
movzwl 0x6(%r15), %ecx
movq 0x18(%rsp), %rdx
movq (%rdx,%rcx,8), %r13
testq %r13, %r13
movb %r10b, 0xb(%rsp)
movq %r11, 0x28(%rsp)
movq %rdi, 0x10(%rsp)
je 0x12556
movq 0x8(%r13), %rdx
movq 0x18(%rsp), %rsi
movq %rdx, (%rsi,%rcx,8)
movl %eax, %r12d
jmp 0x125ea
movq 0x20(%rsp), %rcx
addq %r11, 0x13b8(%rcx)
movl %eax, %r12d
jmp 0x1263d
leal (%rax,%rdi), %r12d
movl 0xc(%r9), %edx
cmpl %edx, %r12d
jbe 0x125c8
movl %eax, 0x10(%r9)
cmpl %edx, %eax
je 0x125a1
movl %edx, %edx
movl %eax, %edi
subq %rdi, %rdx
addq 0x18(%r9), %rdi
xorl %esi, %esi
movq %r15, %r12
movq %r9, %r15
callq 0x51a0
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %r11
movb 0xb(%rsp), %r10b
movq %r15, %r9
movq %r12, %r15
xorl %r8d, %r8d
vmovss 0xc(%rsp), %xmm1
movq (%r9), %r9
movzwl 0x6(%r15), %ecx
movq 0x18(%rsp), %rax
movq (%rax,%rcx,8), %r13
testq %r13, %r13
jne 0x126b2
movl 0xc(%r9), %edx
xorl %eax, %eax
cmpl %edi, %edx
jb 0x12563
movl %edi, %r12d
movl 0x8(%rbp), %edx
cmpl 0x8(%r9), %edx
ja 0x125e3
cmpq %r9, %rbp
jne 0x1280c
cmpl %eax, %r14d
jb 0x1280c
movl %eax, %r13d
addq 0x18(%r9), %r13
movw %cx, 0x4(%r15)
cmpq %r13, %r15
je 0x12631
movq %r13, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %rdx
movq %r9, 0x30(%rsp)
callq 0x55d0
movq %r13, %rdi
movq %r15, %rsi
callq 0x13cc4
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %r11
movb 0xb(%rsp), %r10b
movq 0x30(%rsp), %r9
xorl %r8d, %r8d
vmovss 0xc(%rsp), %xmm1
movq 0x20(%rsp), %rax
addq %rdi, 0x13b8(%rax)
movl %r10d, %r15d
movq %r9, %r13
addl %r11d, %r14d
cmpl %r14d, 0x10(%rbp)
ja 0x1269e
cmpl %ebx, 0x8(%rbp)
jae 0x1267e
testb $0x1, %r15b
je 0x1267e
movl %r12d, 0x10(%r13)
movl 0xc(%r13), %edx
cmpl %edx, %r12d
je 0x1267e
movl %r12d, %edi
subq %rdi, %rdx
addq 0x18(%r13), %rdi
xorl %esi, %esi
callq 0x51a0
xorl %r8d, %r8d
vmovss 0xc(%rsp), %xmm1
movq (%rbp), %rbp
testq %rbp, %rbp
je 0x12696
cmpl %ebx, 0x8(%rbp)
cmovel %r8d, %r12d
cmoveq %rbp, %r13
setae %r15b
xorl %r14d, %r14d
testq %rbp, %rbp
jne 0x12646
movq %r13, %r9
movl %r15d, %r10d
movl %r12d, %eax
testq %rbp, %rbp
jne 0x12479
jmp 0x126c2
xorl %eax, %eax
jmp 0x1252d
movq %rbp, %r13
vmovss 0xc(%rsp), %xmm1
movl %r12d, 0x10(%r13)
movl 0xc(%r13), %edx
cmpl %edx, %r12d
je 0x126e6
movl %r12d, %edi
subq %rdi, %rdx
addq 0x18(%r13), %rdi
xorl %esi, %esi
callq 0x51a0
vmovss 0xc(%rsp), %xmm1
movq (%r13), %rdi
testq %rdi, %rdi
sete %al
movq 0x20(%rsp), %rdx
je 0x12776
movq 0x8(%rdx), %rcx
vcvtusi2ssl 0x8(%rcx), %xmm4, %xmm0
vmulss %xmm1, %xmm0, %xmm0
vcvtusi2ssl 0x8(%r13), %xmm4, %xmm1
vucomiss %xmm1, %xmm0
jbe 0x12737
movq %rdi, %rbx
movl $0x0, 0x10(%rdi)
movq (%rdi), %rdi
testq %rdi, %rdi
sete %al
je 0x12776
vcvtusi2ssl 0x8(%rbx), %xmm4, %xmm1
vucomiss %xmm1, %xmm0
ja 0x12713
jmp 0x1273a
movq %r13, %rbx
testb %al, %al
jne 0x12776
movq %rdx, %r15
movl $0x1, %esi
callq 0x13da4
movq (%rbx), %r14
testq %r14, %r14
je 0x12763
movq %r14, %rdi
callq 0x13c8a
movq %r14, %rdi
callq 0x52e0
movq $0x0, (%rbx)
movl 0x8(%rbx), %eax
incl %eax
movq %r15, %rdx
movl %eax, 0x18(%r15)
movq (%rdx), %rax
movq %rax, 0x8(%rdx)
movq %r13, 0x10(%rdx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2058e(%rip), %rdi     # 0x32d25
leaq 0x200a7(%rip), %rsi     # 0x32845
leaq 0x204e4(%rip), %rcx     # 0x32c89
movl $0x191, %edx            # imm = 0x191
callq 0x51d0
leaq 0x20598(%rip), %rdi     # 0x32d4e
leaq 0x20088(%rip), %rsi     # 0x32845
leaq 0x204c5(%rip), %rcx     # 0x32c89
movl $0x1a5, %edx            # imm = 0x1A5
callq 0x51d0
leaq 0x20493(%rip), %rdi     # 0x32c68
leaq 0x20069(%rip), %rsi     # 0x32845
leaq 0x204a6(%rip), %rcx     # 0x32c89
movl $0x17a, %edx            # imm = 0x17A
callq 0x51d0
leaq 0x20506(%rip), %rdi     # 0x32cfa
leaq 0x2004a(%rip), %rsi     # 0x32845
leaq 0x20487(%rip), %rcx     # 0x32c89
movl $0x17b, %edx            # imm = 0x17B
callq 0x51d0
leaq 0x20561(%rip), %rdi     # 0x32d74
leaq 0x2002b(%rip), %rsi     # 0x32845
leaq 0x20468(%rip), %rcx     # 0x32c89
movl $0x1ae, %edx            # imm = 0x1AE
callq 0x51d0
nop