// File: ehw-fit[P]py-paretoarchive/src/paretoarchive/paretoarchive.h
// Function: BspTreeArchive<1>::insert(BspTreeArchive<1>::Node*&, ObjVec<1> const&)
InteriorNode* insert(Node*& node, ObjVec<OBJ> const& y)
	{
#ifdef COUNTER
		cell_counter++;
#endif
		if (node->interior())
		{
			InteriorNode* interior = static_cast<InteriorNode*>(node);
			interior->m_size++;
#ifdef COUNTER
			cmp_counter++;
#endif
			InteriorNode* ret = insert((y[interior->m_objective] < interior->m_threshold) ? interior->m_left : interior->m_right, y);
			return (interior->unbalanceFactor() > balance_threshold) ? interior : ret;
		}
		else
		{
			LeafNode* leaf = static_cast<LeafNode*>(node);

			if (leaf->m_size < bucket_size)
			{
				leaf->m_point[leaf->m_size] = y;
				leaf->m_size++;
				return nullptr;
			}
			else
			{
				// split the leaf
				assert(leaf->m_size == bucket_size);
				LeafNode* l = new LeafNode();
				LeafNode* r = new LeafNode();

				// find objective for split
				vector<unsigned int> dj(OBJ, numeric_limits<unsigned int>::max());
				unsigned int d = 1;
				for (InteriorNode* nn = leaf->m_parent; nn; nn=nn->m_parent, d++) dj[nn->m_objective] = min(dj[nn->m_objective], d);
				unsigned int j = 0;
				for (unsigned int jj=1; jj<OBJ; jj++) if (dj[jj] > dj[j]) j = jj;
				double value[bucket_size + 1];
				while (true)
				{
					// extract set of values
					for (unsigned int i=0; i<bucket_size; i++) value[i] = leaf->m_point[i](j);
					value[bucket_size] = y(j);
					sort(value, value + bucket_size + 1);
					if (value[bucket_size] > value[0]) break;
					// select the next best objective
					dj[j] = 0;
					j = 0;
					for (unsigned int jj=1; jj<OBJ; jj++) if (dj[jj] > dj[j]) j = jj;
				}

				// find split point
				int nl = (bucket_size + 1) / 2;
				assert(nl >= 1);
				int below = nl, above = nl;
				while (below >= 0 && value[below] == value[nl]) below--;
				while (above <= (int)bucket_size && value[above] == value[nl]) above++;
				assert(below >= 0 || above <= bucket_size);
				if (below + 1 > (int)bucket_size + 1 - above) nl = below + 1;
				else nl = above;
				assert(value[nl-1] < value[nl]);
				double theta = 0.5 * (value[nl-1] + value[nl]);

				// insert points into leaves
				for (unsigned int i=0; i<bucket_size; i++)
				{
					if (leaf->m_point[i](j) < theta)
					{
						l->m_point[l->m_size] = leaf->m_point[i];
						l->m_size++;
					}
					else
					{
						r->m_point[r->m_size] = leaf->m_point[i];
						r->m_size++;
					}
				}
				if (y(j) < theta)
				{
					l->m_point[l->m_size] = y;
					l->m_size++;
				}
				else
				{
					r->m_point[r->m_size] = y;
					r->m_size++;
				}
				assert(l->m_size == nl);
				assert(r->m_size == bucket_size + 1 - nl);

				// create new interior node
				InteriorNode* interior = new InteriorNode();
				interior->m_left = l;
				interior->m_right = r;
				interior->m_size = bucket_size + 1;
				interior->m_objective = j;
				interior->m_threshold = theta;
				interior->m_parent = leaf->m_parent;
				l->m_parent = interior;
				r->m_parent = interior;

				// destroy old leaf node
				delete leaf;

				// change the external pointer to keep parent-child relations consistent
				node = interior;

				// don't try to balance the new node
				return nullptr;
			}
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %fs:0x28, %rax
movq %rax, -0x8(%rbp)
movq %rdi, -0xe8(%rbp)
movq %rsi, -0xf0(%rbp)
movq %rdx, -0xf8(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0xf0(%rbp), %rax
movq (%rax), %rdi
callq 0x69990
testb $0x1, %al
jne 0x68ba3
jmp 0x68c81
movq -0xf0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq -0xf8(%rbp), %rdi
movq -0x100(%rbp), %rax
movl 0x30(%rax), %esi
callq 0x69780
movsd (%rax), %xmm1
movq -0x100(%rbp), %rax
movsd 0x28(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x68c04
movq -0x100(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x180(%rbp)
jmp 0x68c16
movq -0x100(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x180(%rbp)
movq -0x178(%rbp), %rdi
movq -0x180(%rbp), %rsi
movq -0xf8(%rbp), %rdx
callq 0x68b50
movq %rax, -0x108(%rbp)
movq -0x100(%rbp), %rdi
callq 0x699b0
movq 0x3e346(%rip), %rax     # 0xa6f90
ucomisd (%rax), %xmm0
jbe 0x68c60
movq -0x100(%rbp), %rax
movq %rax, -0x188(%rbp)
jmp 0x68c6e
movq -0x108(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rax
movq %rax, -0xe0(%rbp)
jmp 0x694d3
movq -0xf0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rax
cmpl $0x14, 0x10(%rax)
jae 0x68cee
movq -0xf8(%rbp), %rcx
movq -0x110(%rbp), %rax
addq $0x18, %rax
movq -0x110(%rbp), %rdx
movl 0x10(%rdx), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x110(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq $0x0, -0xe0(%rbp)
jmp 0x694d3
movl $0x158, %edi            # imm = 0x158
callq 0x293f0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x190(%rbp)
callq 0x697c0
jmp 0x68d0c
movq -0x190(%rbp), %rax
movq %rax, -0x118(%rbp)
movl $0x158, %edi            # imm = 0x158
callq 0x293f0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x198(%rbp)
callq 0x697c0
jmp 0x68d38
movq -0x198(%rbp), %rax
movq %rax, -0x130(%rbp)
callq 0x69a20
movl %eax, -0xcc(%rbp)
leaq -0xcd(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x69a30
movq -0x1a0(%rbp), %rcx
leaq -0xc8(%rbp), %rdi
movl $0x1, %esi
leaq -0xcc(%rbp), %rdx
callq 0x69a50
jmp 0x68d85
leaq -0xcd(%rbp), %rdi
callq 0x69ad0
movl $0x1, -0xd4(%rbp)
movq -0x110(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
cmpq $0x0, -0x138(%rbp)
je 0x68ec0
movq -0x138(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movq %rax, %rdi
leaq -0xd4(%rbp), %rsi
callq 0x69af0
movq %rax, -0x1a8(%rbp)
jmp 0x68deb
movq -0x1a8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x1ac(%rbp)
movq -0x138(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movl -0x1ac(%rbp), %ecx
movl %ecx, (%rax)
movq -0x138(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x68dad
movq -0x190(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
callq 0x293d0
jmp 0x69503
movq -0x198(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
callq 0x293d0
jmp 0x69503
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
leaq -0xcd(%rbp), %rdi
callq 0x69ad0
jmp 0x69503
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
jmp 0x694c5
movl $0x0, -0x13c(%rbp)
movl $0x1, -0x140(%rbp)
cmpl $0x1, -0x140(%rbp)
jae 0x68f39
movl -0x140(%rbp), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movl (%rax), %eax
movl %eax, -0x1b0(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movq %rax, %rcx
movl -0x1b0(%rbp), %eax
cmpl (%rcx), %eax
jbe 0x68f26
movl -0x140(%rbp), %eax
movl %eax, -0x13c(%rbp)
jmp 0x68f28
movl -0x140(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x140(%rbp)
jmp 0x68ed4
jmp 0x68f3b
jmp 0x68f3d
movl $0x0, -0x144(%rbp)
cmpl $0x14, -0x144(%rbp)
jae 0x68fa5
movq -0x110(%rbp), %rax
movl -0x144(%rbp), %ecx
shlq $0x4, %rcx
leaq 0x18(%rax,%rcx), %rdi
movl -0x13c(%rbp), %esi
callq 0x69b50
movq %rax, -0x1b8(%rbp)
jmp 0x68f7a
movq -0x1b8(%rbp), %rax
movsd (%rax), %xmm0
movl -0x144(%rbp), %eax
movsd %xmm0, -0xb0(%rbp,%rax,8)
movl -0x144(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x144(%rbp)
jmp 0x68f47
movq -0xf8(%rbp), %rdi
movl -0x13c(%rbp), %esi
callq 0x69b70
movq %rax, -0x1c0(%rbp)
jmp 0x68fc0
movq -0x1c0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x10(%rbp)
leaq -0x8(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x69b90
jmp 0x68fe2
movsd -0x10(%rbp), %xmm0
ucomisd -0xb0(%rbp), %xmm0
jbe 0x68ff6
jmp 0x6908e
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movl $0x0, (%rax)
movl $0x0, -0x13c(%rbp)
movl $0x1, -0x148(%rbp)
cmpl $0x1, -0x148(%rbp)
jae 0x69089
movl -0x148(%rbp), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movl (%rax), %eax
movl %eax, -0x1c4(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0xc8(%rbp), %rdi
callq 0x69b30
movq %rax, %rcx
movl -0x1c4(%rbp), %eax
cmpl (%rcx), %eax
jbe 0x69076
movl -0x148(%rbp), %eax
movl %eax, -0x13c(%rbp)
jmp 0x69078
movl -0x148(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x148(%rbp)
jmp 0x69024
jmp 0x68f3b
movl $0xa, -0x14c(%rbp)
movl -0x14c(%rbp), %eax
movl %eax, -0x150(%rbp)
movl -0x14c(%rbp), %eax
movl %eax, -0x154(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x150(%rbp)
movb %al, -0x1c5(%rbp)
jl 0x690ef
movslq -0x150(%rbp), %rax
movsd -0xb0(%rbp,%rax,8), %xmm0
movslq -0x14c(%rbp), %rax
ucomisd -0xb0(%rbp,%rax,8), %xmm0
sete %al
setnp %cl
andb %cl, %al
movb %al, -0x1c5(%rbp)
movb -0x1c5(%rbp), %al
testb $0x1, %al
jne 0x690fb
jmp 0x6910c
movl -0x150(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x150(%rbp)
jmp 0x690b0
jmp 0x6910e
xorl %eax, %eax
cmpl $0x14, -0x154(%rbp)
movb %al, -0x1c6(%rbp)
jg 0x6914d
movslq -0x154(%rbp), %rax
movsd -0xb0(%rbp,%rax,8), %xmm0
movslq -0x14c(%rbp), %rax
ucomisd -0xb0(%rbp,%rax,8), %xmm0
sete %al
setnp %cl
andb %cl, %al
movb %al, -0x1c6(%rbp)
movb -0x1c6(%rbp), %al
testb $0x1, %al
jne 0x69159
jmp 0x6916a
movl -0x154(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x154(%rbp)
jmp 0x6910e
movl -0x150(%rbp), %eax
addl $0x1, %eax
movl $0x15, %ecx
subl -0x154(%rbp), %ecx
cmpl %ecx, %eax
jle 0x69193
movl -0x150(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14c(%rbp)
jmp 0x6919f
movl -0x154(%rbp), %eax
movl %eax, -0x14c(%rbp)
movl -0x14c(%rbp), %eax
subl $0x1, %eax
cltq
movsd -0xb0(%rbp,%rax,8), %xmm1
movslq -0x14c(%rbp), %rax
addsd -0xb0(%rbp,%rax,8), %xmm1
movsd 0x254f5(%rip), %xmm0    # 0x8e6c0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x160(%rbp)
movl $0x0, -0x164(%rbp)
cmpl $0x14, -0x164(%rbp)
jae 0x692e9
movq -0x110(%rbp), %rax
movl -0x164(%rbp), %ecx
shlq $0x4, %rcx
leaq 0x18(%rax,%rcx), %rdi
movl -0x13c(%rbp), %esi
callq 0x69b50
movq %rax, -0x1d0(%rbp)
jmp 0x69218
movq -0x1d0(%rbp), %rax
movsd (%rax), %xmm1
movsd -0x160(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x69283
movq -0x110(%rbp), %rcx
addq $0x18, %rcx
movl -0x164(%rbp), %eax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x118(%rbp), %rax
addq $0x18, %rax
movq -0x118(%rbp), %rdx
movl 0x10(%rdx), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x118(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
jmp 0x692d3
movq -0x110(%rbp), %rcx
addq $0x18, %rcx
movl -0x164(%rbp), %eax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x130(%rbp), %rax
addq $0x18, %rax
movq -0x130(%rbp), %rdx
movl 0x10(%rdx), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x130(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
jmp 0x692d5
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x691e1
movq -0xf8(%rbp), %rdi
movl -0x13c(%rbp), %esi
callq 0x69b70
movq %rax, -0x1d8(%rbp)
jmp 0x69304
movq -0x1d8(%rbp), %rax
movsd (%rax), %xmm1
movsd -0x160(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x6935e
movq -0xf8(%rbp), %rcx
movq -0x118(%rbp), %rax
addq $0x18, %rax
movq -0x118(%rbp), %rdx
movl 0x10(%rdx), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x118(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
jmp 0x6939d
movq -0xf8(%rbp), %rcx
movq -0x130(%rbp), %rax
addq $0x18, %rax
movq -0x130(%rbp), %rdx
movl 0x10(%rdx), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x130(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movl $0x38, %edi
callq 0x293f0
movq %rax, -0x1e0(%rbp)
jmp 0x693b0
movq -0x1e0(%rbp), %rdi
callq 0x69bd0
jmp 0x693be
movq -0x1e0(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x118(%rbp), %rcx
movq -0x170(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x130(%rbp), %rcx
movq -0x170(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x170(%rbp), %rax
movl $0x15, 0x10(%rax)
movl -0x13c(%rbp), %ecx
movq -0x170(%rbp), %rax
movl %ecx, 0x30(%rax)
movsd -0x160(%rbp), %xmm0
movq -0x170(%rbp), %rax
movsd %xmm0, 0x28(%rax)
movq -0x110(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x170(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x170(%rbp), %rcx
movq -0x118(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x170(%rbp), %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x110(%rbp), %rax
movq %rax, -0x1e8(%rbp)
cmpq $0x0, %rax
je 0x6947d
movq -0x1e8(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x170(%rbp), %rcx
movq -0xf0(%rbp), %rax
movq %rcx, (%rax)
movq $0x0, -0xe0(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x69c10
jmp 0x694d3
movq -0x1e0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
callq 0x293d0
leaq -0xc8(%rbp), %rdi
callq 0x69c10
jmp 0x69503
movq -0xe0(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq %fs:0x28, %rax
movq -0x8(%rbp), %rcx
cmpq %rcx, %rax
jne 0x6952f
movq -0x1f0(%rbp), %rax
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
movq -0x120(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq %fs:0x28, %rax
movq -0x8(%rbp), %rcx
cmpq %rcx, %rax
jne 0x6952f
movq -0x1f8(%rbp), %rdi
callq 0x29660
callq 0x29420
nopw %cs:(%rax,%rax)
nop