// File: /workspace/github_c_makefile_star2_O2/Tarsnap[P]kivaloo/kvlds/serialize.c
// Function: serialize
int
serialize(struct btree * T, struct node * N, size_t buflen)
{
	size_t pagelen;
	uint8_t * p;
	size_t i;

	/* Sanity check: This node should be dirty and have no page buffer. */
	assert(N->state == NODE_STATE_DIRTY);
	assert(N->pagebuf == NULL);

	/* Sanity check: The node must have a height (incl. 0). */
	assert(N->height != -1);

	/* Sanity check: We can only store 2 bytes of nkeys. */
	assert(N->nkeys <= UINT16_MAX);

	/* Get the page length.  This also sets N->pagelen. */
	pagelen = serialize_size(N);

	/* Sanity check: The page should fit into the buffer. */
	assert(pagelen <= buflen);

	/* Allocate a page buffer. */
	if ((N->pagebuf = malloc(buflen)) == NULL)
		goto err0;
	p = N->pagebuf;

	/* Copy magic. */
	memcpy(p, "KVLDS\0", 6);
	p += 6;

	/* Write out the number of keys. */
	be16enc(p, (uint16_t)N->nkeys);
	p += 2;

	/* Write height and rootedness. */
	if (N->root)
		*p = (uint8_t)(0x80 + N->height);
	else
		*p = (uint8_t)N->height;
	p += 1;

	/* Write the matching prefix length. */
	*p = N->mlen_t;
	p += 1;

	/* If this is a root, write the size of the tree. */
	if (N->root) {
		be64enc(p, T->nnodes);
		p += 8;
	}

	/* Write out node data. */
	if (N->type == NODE_TYPE_LEAF) {
		/* Write out the keys. */
		for (i = 0; i < N->nkeys; i++) {
			kvldskey_serialize(N->u.pairs[i].k, p);
			N->u.pairs[i].k = (struct kvldskey *)p;
			p += kvldskey_serial_size(N->u.pairs[i].k);
		}

		/* Write out the values. */
		for (i = 0; i < N->nkeys; i++) {
			kvldskey_serialize(N->u.pairs[i].v, p);
			N->u.pairs[i].v = (struct kvldskey *)p;
			p += kvldskey_serial_size(N->u.pairs[i].v);
		}
	} else {
		/* Write out the keys. */
		for (i = 0; i < N->nkeys; i++) {
			kvldskey_serialize(N->u.keys[i], p);
			N->u.keys[i] = (struct kvldskey *)p;
			p += kvldskey_serial_size(N->u.keys[i]);
		}

		/* Write out the child structures. */
		for (i = 0; i <= N->nkeys; i++) {
			/* Sanity check: Merging should be complete. */
			assert(N->v.children[i]->merging == 0);

			/* Page number of child. */
			be64enc(p, N->v.children[i]->pagenum);
			p += 8;

			/* Page number of child's oldest leaf. */
			be64enc(p, N->v.children[i]->oldestleaf);
			p += 8;

			/* Page size of leaf. */
			be32enc(p, N->v.children[i]->pagesize);
			p += 4;
		}
	}

	/* Sanity-check: Make sure we computed the size correctly. */
	assert(p == N->pagebuf + pagelen);

	/* Zero the remaining space. */
	memset(p, 0, buflen - pagelen);

	/* Success! */
	return (0);

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movb 0x1c(%rsi), %al
andb $0xc, %al
cmpb $0x8, %al
jne 0x8dab
movq %rsi, %rbx
cmpq $0x0, 0x50(%rsi)
jne 0x8dc4
cmpb $-0x1, 0x1d(%rbx)
je 0x8ddd
cmpq $0x10000, 0x38(%rbx)    # imm = 0x10000
jae 0x8df6
movq %rdx, %r12
movq %rdi, %r13
movq %rbx, %rdi
callq 0x8e4b
movq %r12, %r14
subq %rax, %r14
jb 0x8e0f
movq %rax, %r15
movq %r12, %rdi
callq 0x22a0
movq %rax, 0x50(%rbx)
testq %rax, %rax
je 0x8c1e
movq %rax, %r12
movq %r15, (%rsp)
movq %r14, 0x10(%rsp)
movq %rax, %rcx
movw $0x53, 0x4(%r12)
movl $0x444c564b, (%r12)     # imm = 0x444C564B
movq 0x38(%rbx), %r14
movl %r14d, %eax
rolw $0x8, %ax
movw %ax, 0x6(%r12)
movb 0x1c(%rbx), %bpl
movb 0x1d(%rbx), %al
testb $0x10, %bpl
movq %r12, 0x8(%rsp)
jne 0x8c26
movb %al, 0x8(%rcx)
movb 0x1e(%rbx), %al
movb %al, 0x9(%rcx)
pushq $0xa
jmp 0x8c41
pushq $-0x1
popq %rbx
jmp 0x8d7b
addb $-0x80, %al
movb %al, 0x8(%rcx)
movb 0x1e(%rbx), %al
movb %al, 0x9(%rcx)
leaq 0xa(%r12), %rdi
movq 0x48(%r13), %rsi
callq 0x8f08
pushq $0x12
popq %rax
addq %rax, %r12
andb $0x3, %bpl
cmpb $0x1, %bpl
jne 0x8c8c
xorl %r13d, %r13d
movq %r14, %rbp
subq $0x1, %rbp
jb 0x8cca
movq 0x40(%rbx), %r15
movq (%r15,%r13), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r15,%r13)
movq 0x40(%rbx), %rax
movq (%rax,%r13), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
addq $0x10, %r13
jmp 0x8c55
xorl %r15d, %r15d
movq (%rsp), %rbp
cmpq %r15, %r14
je 0x8d09
movq 0x40(%rbx), %r13
movq (%r13,%r15,8), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r13,%r15,8)
movq 0x40(%rbx), %rax
movq (%rax,%r15,8), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
incq %r15
jmp 0x8c93
pushq $0x8
popq %r13
movq (%rsp), %rbp
subq $0x1, %r14
jb 0x8d53
movq 0x40(%rbx), %r15
movq (%r15,%r13), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r15,%r13)
movq 0x40(%rbx), %rax
movq (%rax,%r13), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
addq $0x10, %r13
jmp 0x8cd2
movq 0x48(%rbx), %r15
xorl %r13d, %r13d
cmpq %r14, %r13
ja 0x8d5a
movq (%r15,%r13,8), %rax
testb $0x20, 0x1c(%rax)
jne 0x8d8c
movq (%rax), %rsi
movq %r12, %rdi
callq 0x8f08
leaq 0x8(%r12), %rdi
movq (%r15,%r13,8), %rax
movq 0x8(%rax), %rsi
callq 0x8f08
movq (%r15,%r13,8), %rax
movl 0x18(%rax), %eax
bswapl %eax
movl %eax, 0x10(%r12)
addq $0x14, %r12
incq %r13
jmp 0x8d10
movq 0x8(%rsp), %rax
jmp 0x8d5e
movq 0x50(%rbx), %rax
addq %rbp, %rax
cmpq %rax, %r12
movq 0x10(%rsp), %rdx
jne 0x8e2c
xorl %ebx, %ebx
movq %r12, %rdi
xorl %esi, %esi
callq 0x21e0
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x98dd(%rip), %rdi      # 0x12670
leaq 0x9849(%rip), %rsi      # 0x125e3
leaq 0x984e(%rip), %rcx      # 0x125ef
movl $0x96, %edx
callq 0x21c0
leaq 0x91f4(%rip), %rdi      # 0x11fa6
leaq 0x982a(%rip), %rsi      # 0x125e3
leaq 0x982f(%rip), %rcx      # 0x125ef
pushq $0x4f
jmp 0x8e26
leaq 0x9859(%rip), %rdi      # 0x12624
leaq 0x9811(%rip), %rsi      # 0x125e3
leaq 0x9816(%rip), %rcx      # 0x125ef
pushq $0x50
jmp 0x8e26
leaq 0x9853(%rip), %rdi      # 0x12637
leaq 0x97f8(%rip), %rsi      # 0x125e3
leaq 0x97fd(%rip), %rcx      # 0x125ef
pushq $0x53
jmp 0x8e26
leaq 0x984a(%rip), %rdi      # 0x12647
leaq 0x97df(%rip), %rsi      # 0x125e3
leaq 0x97e4(%rip), %rcx      # 0x125ef
pushq $0x56
jmp 0x8e26
leaq 0x9848(%rip), %rdi      # 0x1265e
leaq 0x97c6(%rip), %rsi      # 0x125e3
leaq 0x97cb(%rip), %rcx      # 0x125ef
pushq $0x5c
popq %rdx
callq 0x21c0
leaq 0x985c(%rip), %rdi      # 0x1268f
leaq 0x97a9(%rip), %rsi      # 0x125e3
leaq 0x97ae(%rip), %rcx      # 0x125ef
movl $0xa7, %edx
callq 0x21c0