// File: ddunbar[P]PDSample/./WeightedDiscretePDF.cpp
// Function: WeightedDiscretePDF<int>::lengthen(WDPDF_Node<int>*)
void WeightedDiscretePDF<T>::lengthen(WDPDF_Node<T> *n)
{
	if (n->isRed()) {
		n->markBlack();
	} else if (n->parent) {
		WDPDF_Node<T> *sibling = n->sibling();

		if (sibling && sibling->isRed()) {
			n->parent->markRed();
			sibling->markBlack();

			rotate(sibling); // node sibling is now old sibling child, must be black
			sibling = n->sibling();
		}

		// sibling is black

		if (!sibling) {
			lengthen(n->parent);
		} else if (sibling->leftIsBlack() && sibling->rightIsBlack()) {
			if (n->parent->isBlack()) {
				sibling->markRed();
				lengthen(n->parent);
			} else {
				sibling->markRed();
				n->parent->markBlack();
			}
		} else {
			if (n==n->parent->left && sibling->rightIsBlack()) {
				rotate(sibling->left); // sibling->left must be red
				sibling->markRed();
				sibling->parent->markBlack();
				sibling = sibling->parent;
			} else if (n==n->parent->right && sibling->leftIsBlack()) {
				rotate(sibling->right); // sibling->right must be red
				sibling->markRed();
				sibling->parent->markBlack();
				sibling = sibling->parent;
			}

			// sibling is black, and sibling's far child is red

			rotate(sibling);
			if (n->parent->isRed()) sibling->markRed();
			sibling->left->markBlack();
			sibling->right->markBlack();
		}
	}
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x18(%rsp), %rdi
callq 0xf570
testb $0x1, %al
jne 0xf9f8
jmp 0xfa07
movq 0x18(%rsp), %rdi
callq 0xf550
jmp 0xfc11
movq 0x18(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0xfc0f
movq 0x18(%rsp), %rdi
callq 0xfc20
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0xfa74
movq 0x10(%rsp), %rdi
callq 0xf570
testb $0x1, %al
jne 0xfa3e
jmp 0xfa74
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf560
movq 0x10(%rsp), %rdi
callq 0xf550
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xf580
movq 0x18(%rsp), %rdi
callq 0xfc20
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
jne 0xfa94
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0xf9d0
jmp 0xfc0d
movq 0x10(%rsp), %rdi
callq 0xf4b0
testb $0x1, %al
jne 0xfaa4
jmp 0xfb04
movq 0x10(%rsp), %rdi
callq 0xf510
testb $0x1, %al
jne 0xfab4
jmp 0xfb04
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf4f0
testb $0x1, %al
jne 0xfac8
jmp 0xfae7
movq 0x10(%rsp), %rdi
callq 0xf560
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0xf9d0
jmp 0xfaff
movq 0x10(%rsp), %rdi
callq 0xf560
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf550
jmp 0xfc0b
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movq 0x8(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jne 0xfb63
movq 0x10(%rsp), %rdi
callq 0xf510
testb $0x1, %al
jne 0xfb28
jmp 0xfb63
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0xf580
movq 0x10(%rsp), %rdi
callq 0xf560
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf550
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0xfbc2
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movq 0x8(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jne 0xfbc0
movq 0x10(%rsp), %rdi
callq 0xf4b0
testb $0x1, %al
jne 0xfb87
jmp 0xfbc0
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rsi
callq 0xf580
movq 0x10(%rsp), %rdi
callq 0xf560
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf550
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0xfbc2
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xf580
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xf570
testb $0x1, %al
jne 0xfbe5
jmp 0xfbef
movq 0x10(%rsp), %rdi
callq 0xf560
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0xf550
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0xf550
jmp 0xfc0d
jmp 0xfc0f
jmp 0xfc11
addq $0x28, %rsp
retq
nopw %cs:(%rax,%rax)