// File: /workspace/github_c_makefile_star2_O2/Tarsnap[P]kivaloo/liball/../lib/datastruct/onlinequantile.c
// Function: onlinequantile_add
int
onlinequantile_add(struct onlinequantile * Q, double x)
{
	size_t i;
	double r;

	/* Figure out where the quantile falls after expansion. */
	hazenquantile(Q->N + 1, Q->q, &i, &r);

	/* Which heap needs to grow? */
	if (i + 1 > Q->N_smaller) {
		/* We need to expand the "smaller than quantile" heap. */

		/* Sanity-check. */
		assert(Q->N_smaller == i);

		if (x <= Q->larger_min) {
			/* Add to "smaller" heap. */
			if (doubleheap_add(Q->smaller, -x))
				goto err0;
			Q->N_smaller += 1;

			/* Update smaller_max if necessary. */
			if (Q->smaller_max < x)
				Q->smaller_max = x;
		} else {
			/*
			 * This value is going into the "larger" heap, but we
			 * want the "smaller" heap to be growing; so we need
			 * to take the least element from "larger" and move it
			 * into "smaller".
			 */

			/* Sanity-check. */
			assert(Q->N_smaller < Q->N);

			/* Add element to "smaller" heap. */
			if (doubleheap_add(Q->smaller, -Q->larger_min))
				goto err0;
			Q->N_smaller += 1;
			Q->smaller_max = Q->larger_min;

			/*
			 * Now replace the value we removed from the "larger"
			 * heap with our new value; and figure out what the
			 * new minimum value in that heap is.
			 */
			doubleheap_setmin(Q->larger, x);
			doubleheap_getmin(Q->larger, &Q->larger_min);
		}
	} else {
		/* We need to expand the "larger than quantile" heap. */

		/* Sanity-check. */
		assert(Q->N_smaller - 1 == i);

		/* Where does the new value land? */
		if (x >= Q->smaller_max) {
			/* Add to "larger" heap. */
			if (doubleheap_add(Q->larger, x))
				goto err0;

			/* Update larger_min if necessary. */
			if (Q->larger_min > x)
				Q->larger_min = x;
		} else {
			/*
			 * This value is going into the "smaller" heap, but we
			 * want the "larger" heap to be growing; so we need
			 * to take the greatest element from "smaller" and move
			 * it into "larger".
			 */

			/* Sanity-check. */
			assert(Q->N_smaller > 0);

			/* Add element to "larger" heap. */
			if (doubleheap_add(Q->larger, Q->smaller_max))
				goto err0;
			Q->larger_min = Q->smaller_max;

			/*
			 * Now replace the value we removed from the "smaller"
			 * heap with our new value; and figure out what the
			 * new maximum value in that heap is.
			 */
			doubleheap_setmin(Q->smaller, -x);
			doubleheap_getmin(Q->smaller, &Q->smaller_max);
			Q->smaller_max = - Q->smaller_max;
		}
	}

	/* We have added a new data point (somewhere). */
	Q->N += 1;

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x28, %rsp
movaps %xmm0, (%rsp)
movq %rdi, %rbx
movq 0x20(%rdi), %rdi
incq %rdi
movsd 0x30(%rbx), %xmm0
leaq 0x20(%rsp), %r14
leaq 0x18(%rsp), %rdx
movq %r14, %rsi
callq 0x1b45
movq (%r14), %rax
leaq 0x1(%rax), %rdx
movq 0x28(%rbx), %rcx
cmpq %rcx, %rdx
jbe 0x1d70
cmpq %rax, %rcx
jne 0x1e54
movsd 0x10(%rbx), %xmm0
movapd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
jae 0x1dec
cmpq 0x20(%rbx), %rax
jae 0x1e90
movq 0x8(%rbx), %rdi
xorpd 0x148c(%rip), %xmm0     # 0x31c0
callq 0x2064
testl %eax, %eax
jne 0x1e2c
incq 0x28(%rbx)
leaq 0x10(%rbx), %r14
movsd 0x10(%rbx), %xmm0
movsd %xmm0, 0x18(%rbx)
movq (%rbx), %rdi
movapd (%rsp), %xmm0
callq 0x212c
movq (%rbx), %rdi
movq %r14, %rsi
callq 0x20f8
jmp 0x1e46
leaq -0x1(%rcx), %rdx
cmpq %rax, %rdx
jne 0x1e71
movsd 0x18(%rbx), %xmm0
movapd (%rsp), %xmm1
ucomisd %xmm0, %xmm1
jae 0x1e1c
testq %rcx, %rcx
je 0x1eaf
movq (%rbx), %rdi
callq 0x2064
testl %eax, %eax
jne 0x1e2c
leaq 0x18(%rbx), %r14
movsd 0x18(%rbx), %xmm0
movsd %xmm0, 0x10(%rbx)
movq 0x8(%rbx), %rdi
movaps (%rsp), %xmm0
xorps 0x13f9(%rip), %xmm0     # 0x31c0
callq 0x212c
movq 0x8(%rbx), %rdi
movq %r14, %rsi
callq 0x20f8
movsd 0x18(%rbx), %xmm0
xorpd 0x13db(%rip), %xmm0     # 0x31c0
movlpd %xmm0, 0x18(%rbx)
jmp 0x1e46
movq 0x8(%rbx), %rdi
movapd 0x13c8(%rip), %xmm0     # 0x31c0
xorpd %xmm1, %xmm0
callq 0x2064
testl %eax, %eax
jne 0x1e2c
incq 0x28(%rbx)
movapd (%rsp), %xmm0
ucomisd 0x18(%rbx), %xmm0
jbe 0x1e46
movsd %xmm0, 0x18(%rbx)
jmp 0x1e46
movq (%rbx), %rdi
movapd %xmm1, %xmm0
callq 0x2064
testl %eax, %eax
je 0x1e31
pushq $-0x1
popq %rax
jmp 0x1e4c
movsd 0x10(%rbx), %xmm0
movapd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1e46
movsd %xmm1, 0x10(%rbx)
incq 0x20(%rbx)
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
retq
leaq 0x1414(%rip), %rdi      # 0x326f
leaq 0x139c(%rip), %rsi      # 0x31fe
leaq 0x1418(%rip), %rcx      # 0x3281
pushq $0x7a
popq %rdx
callq 0x10c0
leaq 0x1370(%rip), %rdi      # 0x31e8
leaq 0x137f(%rip), %rsi      # 0x31fe
leaq 0x13fb(%rip), %rcx      # 0x3281
movl $0xa2, %edx
callq 0x10c0
leaq 0x13c4(%rip), %rdi      # 0x325b
leaq 0x1360(%rip), %rsi      # 0x31fe
leaq 0x13dc(%rip), %rcx      # 0x3281
movl $0x8e, %edx
callq 0x10c0
leaq 0x1403(%rip), %rdi      # 0x32b9
leaq 0x1341(%rip), %rsi      # 0x31fe
leaq 0x13bd(%rip), %rcx      # 0x3281
movl $0xb6, %edx
callq 0x10c0