// File: CMU-SAFARI[P]MQSim/src/sim/EventTree.cpp
// Function: MQSimEngine::EventTree::Delete(MQSimEngine::EventTreeNode*)
void EventTree::Delete(EventTreeNode* z)
	{
		// A node to be deleted will be: 
		//		1. a leaf with no children
		//		2. have one child
		//		3. have two children
		// If the deleted node is red, the red black properties still hold.
		// If the deleted node is black, the tree needs rebalancing

		EventTreeNode* x;					// work node to contain the replacement node
		EventTreeNode* y;					// work node 

											// find the replacement node (the successor to x) - the node one with 
											// at *most* one child. 
		if (z->Left == SentinelNode || z->Right == SentinelNode)
			y = z;						// node has sentinel as a child
		else
		{
			// z has two children, find replacement node which will 
			// be the leftmost node greater than z
			y = z->Right;				        // traverse right subtree	
			while (y->Left != SentinelNode)		// to find next node in sequence
				y = y->Left;
		}

		// at this point, y contains the replacement node. it's content will be copied 
		// to the valules in the node to be deleted

		// x (y's only child) is the node that will be linked to y's old parent. 
		if (y->Left != SentinelNode)
			x = y->Left;
		else
			x = y->Right;

		// replace x's parent with y's parent and
		// link x to proper subtree in parent
		// this removes y from the chain
		x->Parent = y->Parent;
		if (y->Parent != NULL)
			if (y == y->Parent->Left)
				y->Parent->Left = x;
			else
				y->Parent->Right = x;
		else
			rbTree = x;			// make x the root node

								// copy the values from y (the replacement node) to the node being deleted.
								// note: this effectively deletes the node. 
		if (y != z)
		{
			z->Key = y->Key;
			z->FirstSimEvent = y->FirstSimEvent;
			z->LastSimEvent = y->LastSimEvent;
		}

		if (y->Color == 1)
			Restore_after_delete(x);

		lastNodeFound = SentinelNode;
		delete z;
	}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x28(%rsp), %rax
movq 0x20(%rax), %rax
cmpq 0x91128(%rip), %rax     # 0xda6b0
je 0x4959c
movq 0x28(%rsp), %rax
movq 0x28(%rax), %rax
cmpq 0x91116(%rip), %rax     # 0xda6b0
jne 0x495a8
movq 0x28(%rsp), %rax
movq %rax, 0x18(%rsp)
jmp 0x495da
movq 0x28(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq 0x20(%rax), %rax
cmpq 0x910ea(%rip), %rax     # 0xda6b0
je 0x495d8
movq 0x18(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x495b6
jmp 0x495da
movq 0x18(%rsp), %rax
movq 0x20(%rax), %rax
cmpq 0x910c6(%rip), %rax     # 0xda6b0
je 0x495fc
movq 0x18(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x20(%rsp)
jmp 0x4960a
movq 0x18(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0x18(%rsp), %rax
cmpq $0x0, 0x30(%rax)
je 0x49664
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movq 0x30(%rcx), %rcx
cmpq 0x20(%rcx), %rax
jne 0x49650
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq %rcx, 0x20(%rax)
jmp 0x49662
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq %rcx, 0x28(%rax)
jmp 0x49672
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rsp), %rax
cmpq 0x28(%rsp), %rax
je 0x496b2
movq 0x18(%rsp), %rax
movq (%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x18(%rsp), %rax
cmpl $0x1, 0x18(%rax)
jne 0x496cc
movq 0x10(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x49740
movq 0x10(%rsp), %rax
movq 0x90fd8(%rip), %rcx     # 0xda6b0
movq %rcx, 0x10(%rax)
movq 0x28(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x496f6
movq 0x8(%rsp), %rdi
callq 0x8410
addq $0x38, %rsp
retq
nopl (%rax,%rax)