// File: /workspace/github_cpp_makefile_star2_O2/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 0xe09b
vmovss 0x154ce(%rip), %xmm2    # 0x2321c
vucomiss %xmm0, %xmm2
jb 0xe09b
vxorps %xmm3, %xmm3, %xmm3
vucomiss %xmm3, %xmm1
jb 0xe0ba
vucomiss %xmm1, %xmm2
jb 0xe0ba
andq $0x0, 0x13b8(%rdi)
movq %rdi, %rbx
movq (%rdi), %rax
cmpl $0x0, 0x10(%rax)
je 0xe02f
leaq 0x20(%rbx), %rdi
vmovss %xmm0, 0x30(%rsp)
vmovss %xmm1, 0x10(%rsp)
movq %rdi, 0x28(%rsp)
callq 0xf48a
movq 0x8(%rbx), %rax
vcvtusi2ssl 0x8(%rax), %xmm4, %xmm0
movq (%rbx), %r15
movq %rbx, 0x18(%rsp)
vmulss 0x10(%rsp), %xmm0, %xmm0
movq %r15, %r13
vcvttss2usi %xmm0, %eax
testl %eax, %eax
movl %eax, 0x34(%rsp)
sete %r12b
xorl %ebx, %ebx
xorl %ebp, %ebp
testq %r13, %r13
je 0xdfab
movq 0x18(%r13), %r9
movl %ebp, %eax
movzwl 0x4(%r9,%rax), %ecx
leal -0x1(%rcx), %edx
cmpw $0x271, %dx             # imm = 0x271
jae 0xe03e
addq %rax, %r9
imulq $0x30, %rcx, %rsi
movl (%r9), %edx
addq $0x40, %rsi
cmpl $0x4, %edx
ja 0xde51
movl %r12d, %eax
testb $0x1, %r12b
jne 0xded1
movl %eax, %edi
movb $0x1, %al
movl %ebp, %r12d
movq %r13, %r14
cmpl $0x4, %edx
je 0xdf52
movq 0x28(%rsp), %r10
incl %edx
movq %rsi, %r8
movq %r8, %rsi
movl %ebx, %r12d
movq %r15, %r14
movq (%r10,%rcx,8), %rax
movq %rax, 0x8(%r9)
movq %r9, (%r10,%rcx,8)
movl %edx, (%r9)
movl %edi, %eax
jmp 0xdf52
testb $0x1, %r12b
je 0xdec2
movzwl 0x6(%r9), %eax
movq %rsi, 0x20(%rsp)
movb %r12b, 0xf(%rsp)
leal -0x1(%rax), %edx
cmpw %cx, %dx
jae 0xe05d
movzwl %ax, %ecx
movq %r15, %r14
imulq $0x30, %rcx, %r8
addq $0x40, %r8
movq %r8, 0x10(%rsp)
movq 0x28(%rsp), %rdx
movzwl %ax, %ecx
movq (%rdx,%rcx,8), %r15
testq %r15, %r15
jne 0xded9
leal (%rbx,%r8), %r12d
cmpl 0xc(%r14), %r12d
jbe 0xdeeb
movl %ebx, 0x10(%r14)
movq %r14, %rdi
movq %r9, %rbx
callq 0xf4a0
movq 0x10(%rsp), %r8
movq (%r14), %r14
movzwl 0x6(%rbx), %eax
movq %rbx, %r9
xorl %ebx, %ebx
jmp 0xde85
movq 0x18(%rsp), %rax
addq %rsi, 0x13b8(%rax)
movl %r12d, %eax
movl %ebx, %r12d
movq %r15, %r14
jmp 0xdf52
movq 0x8(%r15), %rdx
movq 0x28(%rsp), %rsi
movl %ebx, %r12d
movq %rdx, (%rsi,%rcx,8)
jmp 0xdf0d
movl 0x8(%r13), %ecx
cmpl 0x8(%r14), %ecx
ja 0xdf06
cmpq %r14, %r13
jne 0xe07c
cmpl %ebx, %ebp
jb 0xe07c
movl %ebx, %r15d
addq 0x18(%r14), %r15
movq 0x20(%rsp), %rsi
movw %ax, 0x4(%r9)
cmpq %r15, %r9
je 0xdf42
movq %r15, %rdi
movq %r9, %rsi
movq %r8, %rdx
movq %r9, %rbx
callq 0x55d0
movq %r15, %rdi
movq %rbx, %rsi
callq 0xf4ba
movq 0x10(%rsp), %r8
movq 0x20(%rsp), %rsi
movq 0x18(%rsp), %rax
addq %r8, 0x13b8(%rax)
movb 0xf(%rsp), %al
movq %r14, %r15
movl 0x34(%rsp), %r14d
movl %r12d, %ebx
addl %esi, %ebp
movl %eax, %r12d
testq %r13, %r13
je 0xddd2
cmpl %ebp, 0x10(%r13)
ja 0xddd2
cmpl %r14d, 0x8(%r13)
jae 0xdf8d
testb $0x1, %r12b
je 0xdf8d
movq %r15, %rdi
movl %ebx, 0x10(%r15)
callq 0xf4a0
movq (%r13), %r13
xorl %ebp, %ebp
testq %r13, %r13
je 0xdf62
xorl %ebp, %ebp
cmpl %r14d, 0x8(%r13)
cmovel %ebp, %ebx
cmoveq %r13, %r15
setae %r12b
jmp 0xdf62
movq %r15, %rdi
movl %ebx, 0x10(%r15)
callq 0xf4a0
movq 0x18(%rsp), %r12
vmovss 0x30(%rsp), %xmm2
movq %r15, %rbx
movq 0x8(%r12), %rax
movq (%rbx), %rdi
testq %rdi, %rdi
je 0xe021
vcvtusi2ssl 0x8(%rbx), %xmm4, %xmm0
vcvtusi2ssl 0x8(%rax), %xmm4, %xmm1
vmulss %xmm2, %xmm1, %xmm1
vucomiss %xmm0, %xmm1
jbe 0xdff3
andl $0x0, 0x10(%rdi)
movq %rdi, %rbx
jmp 0xdfca
pushq $0x1
popq %rsi
callq 0xf582
movq (%rbx), %r14
testq %r14, %r14
je 0xe00b
movq %r14, %rdi
callq 0xf450
movq %r14, %rdi
callq 0x52f0
andq $0x0, (%rbx)
movl 0x8(%rbx), %eax
incl %eax
movl %eax, 0x18(%r12)
movq (%r12), %rax
movq %rax, 0x8(%r12)
movq %r15, 0x10(%r12)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x15b3c(%rip), %rdi     # 0x23b81
leaq 0x15655(%rip), %rsi     # 0x236a1
leaq 0x15a92(%rip), %rcx     # 0x23ae5
movl $0x191, %edx            # imm = 0x191
callq 0x51f0
leaq 0x15b46(%rip), %rdi     # 0x23baa
leaq 0x15636(%rip), %rsi     # 0x236a1
leaq 0x15a73(%rip), %rcx     # 0x23ae5
movl $0x1a5, %edx            # imm = 0x1A5
callq 0x51f0
leaq 0x15b4d(%rip), %rdi     # 0x23bd0
leaq 0x15617(%rip), %rsi     # 0x236a1
leaq 0x15a54(%rip), %rcx     # 0x23ae5
movl $0x1ae, %edx            # imm = 0x1AE
callq 0x51f0
leaq 0x15a22(%rip), %rdi     # 0x23ac4
leaq 0x155f8(%rip), %rsi     # 0x236a1
leaq 0x15a35(%rip), %rcx     # 0x23ae5
movl $0x17a, %edx            # imm = 0x17A
callq 0x51f0
leaq 0x15a95(%rip), %rdi     # 0x23b56
leaq 0x155d9(%rip), %rsi     # 0x236a1
leaq 0x15a16(%rip), %rcx     # 0x23ae5
movl $0x17b, %edx            # imm = 0x17B
callq 0x51f0
nop