// File: nmmmnu[P]HM3/hm3/skiplist.cc
// Function: bool hm3::SkipList::putT_<hm3::Pair>(hm3::Pair&&)
bool SkipList::putT_(UPAIR&& newdata){
	const StringRef &key = newdata.getKey();

	if (key.empty())
		return true;

	const auto nl = locate_(key);

	if (nl.node){
		// update in place. node MUST be not NULL...

		const Pair & olddata = nl.node->data;

		// check if the data in database is valid
		if (! newdata.valid(olddata) ){
			// newdata will be magically destroyed.
			return false;
		}

		dataSize_ = dataSize_
			- olddata.getBytes()
			+ newdata.getBytes();

		// copy assignment
		const_cast<Pair &>(olddata) = std::forward<UPAIR>(newdata);

		return true;
	}

	// create new node

	size_t const size = newdata.getBytes();
	height_type const height = _getRandomHeight();

	Node *newnode = new(height, true) Node(std::forward<UPAIR>(newdata));

	if (newnode == nullptr){
		// newdata will be magically destroyed.
		return false;
	}

	/* SEE REMARK ABOUT NEXT[] SIZE AT THE TOP */
	// newnode->height = height

	// place new node where it belongs

	for(height_type i = 0; i < height; ++i){
		if (nl.loc[i]){
			// we are at the middle
			const Node *node = nl.loc[i];

			newnode->next[i] = node->next[i];
			const_cast<Node *>(node)->next[i] = newnode;
		}else{
			newnode->next[i] = heads_[i];
			heads_[i] = newnode;
		}
	}

#ifdef DEBUG_PRINT_LANES
	printf("%3u Lanes-> ", height);
	for(height_type i = 0; i < height; ++i)
		printf("%p ", (void *) newnode->next[i]);
	printf("\n");
#endif

	/* SEE REMARK ABOUT NEXT[] SIZE AT THE TOP */
	// newnode->next[i] = NULL;

	dataSize_ += size;
	++dataCount_;

	return true;
}

// Assembly:
subq $0x298, %rsp            # imm = 0x298
movq %rdi, 0x288(%rsp)
movq %rsi, 0x280(%rsp)
movq 0x288(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x280(%rsp), %rdi
callq 0x14c40
movq %rax, 0x268(%rsp)
movq %rdx, 0x270(%rsp)
leaq 0x268(%rsp), %rax
movq %rax, 0x278(%rsp)
movq 0x278(%rsp), %rdi
callq 0xa220
testb $0x1, %al
jne 0x13994
jmp 0x139a1
movb $0x1, 0x297(%rsp)
jmp 0x13bdf
movq 0x28(%rsp), %rsi
movq 0x278(%rsp), %rdx
leaq 0x60(%rsp), %rdi
xorl %ecx, %ecx
callq 0x13000
cmpq $0x0, 0x60(%rsp)
je 0x13a63
movq 0x60(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x280(%rsp), %rdi
movq 0x58(%rsp), %rsi
xorl %edx, %edx
callq 0xfcc0
testb $0x1, %al
jne 0x139f5
movb $0x0, 0x297(%rsp)
jmp 0x13bdf
movq 0x28(%rsp), %rax
movq 0x210(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x58(%rsp), %rdi
callq 0x15050
movq %rax, %rcx
movq 0x18(%rsp), %rax
subq %rcx, %rax
movq %rax, 0x20(%rsp)
movq 0x280(%rsp), %rdi
callq 0x15050
movq 0x20(%rsp), %rcx
movq %rax, %rdx
movq 0x28(%rsp), %rax
addq %rdx, %rcx
movq %rcx, 0x210(%rax)
movq 0x280(%rsp), %rsi
movq 0x58(%rsp), %rdi
callq 0x14aa0
movb $0x1, 0x297(%rsp)
jmp 0x13bdf
movq 0x280(%rsp), %rdi
callq 0x15050
movq 0x28(%rsp), %rdi
movq %rax, 0x50(%rsp)
callq 0x13250
movb %al, 0x4f(%rsp)
movl $0x10, %edi
movl $0x1, %edx
movzbl 0x4f(%rsp), %esi
callq 0x13bf0
movq %rax, %rdi
movq %rdi, 0x10(%rsp)
movq 0x280(%rsp), %rsi
callq 0x13c60
movq 0x10(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jne 0x13acb
movb $0x0, 0x297(%rsp)
jmp 0x13bdf
movb $0x0, 0x3f(%rsp)
movzbl 0x3f(%rsp), %eax
movzbl 0x4f(%rsp), %ecx
cmpl %ecx, %eax
jge 0x13bad
leaq 0x60(%rsp), %rdi
addq $0x8, %rdi
movzbl 0x3f(%rsp), %eax
movl %eax, %esi
callq 0x13c90
cmpq $0x0, (%rax)
je 0x13b4e
leaq 0x60(%rsp), %rdi
addq $0x8, %rdi
movzbl 0x3f(%rsp), %eax
movl %eax, %esi
callq 0x13c90
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movzbl 0x3f(%rsp), %ecx
movq 0x8(%rax,%rcx,8), %rdx
movq 0x40(%rsp), %rax
movzbl 0x3f(%rsp), %ecx
movq %rdx, 0x8(%rax,%rcx,8)
movq 0x40(%rsp), %rdx
movq 0x30(%rsp), %rax
movzbl 0x3f(%rsp), %ecx
movq %rdx, 0x8(%rax,%rcx,8)
jmp 0x13b9c
movq 0x28(%rsp), %rdi
addq $0x8, %rdi
movzbl 0x3f(%rsp), %eax
movl %eax, %esi
callq 0x13cc0
movq 0x28(%rsp), %rdi
movq (%rax), %rdx
movq 0x40(%rsp), %rax
movzbl 0x3f(%rsp), %ecx
movq %rdx, 0x8(%rax,%rcx,8)
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
addq $0x8, %rdi
movzbl 0x3f(%rsp), %eax
movl %eax, %esi
callq 0x13cc0
movq 0x8(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x13b9e
movb 0x3f(%rsp), %al
addb $0x1, %al
movb %al, 0x3f(%rsp)
jmp 0x13ad0
movq 0x28(%rsp), %rax
movq 0x50(%rsp), %rcx
addq 0x210(%rax), %rcx
movq %rcx, 0x210(%rax)
movq 0x208(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x208(%rax)
movb $0x1, 0x297(%rsp)
movb 0x297(%rsp), %al
andb $0x1, %al
addq $0x298, %rsp            # imm = 0x298
retq