// File: /workspace/github_c_makefile_star2_O1/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 0xa649
movq %rsi, %rbx
cmpq $0x0, 0x50(%rsi)
jne 0xa668
cmpb $-0x1, 0x1d(%rbx)
je 0xa687
cmpq $0x10000, 0x38(%rbx)    # imm = 0x10000
jae 0xa6a6
movq %rdx, %r12
movq %rdi, %r13
movq %rbx, %rdi
callq 0xa703
movq %r12, %rbp
subq %rax, %rbp
jb 0xa6c5
movq %rax, %r14
movq %r12, %rdi
callq 0x22a0
movq %rax, 0x50(%rbx)
testq %rax, %rax
je 0xa4bd
movq %rax, %r12
movq %r14, 0x10(%rsp)
movw $0x53, 0x4(%rax)
movl $0x444c564b, (%rax)     # imm = 0x444C564B
movq 0x38(%rbx), %r14
movl %r14d, %eax
rolw $0x8, %ax
movw %ax, 0x6(%r12)
movb 0x1c(%rbx), %al
movl %eax, %ecx
andb $0x10, %cl
leal (,%rcx,8), %edx
xorb 0x1d(%rbx), %dl
movb %dl, 0x8(%r12)
movb 0x1e(%rbx), %dl
movb %dl, 0x9(%r12)
testb %cl, %cl
jne 0xa4c7
addq $0xa, %r12
jmp 0xa4d7
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0xa619
movq 0x48(%r13), %rcx
bswapq %rcx
movq %rcx, 0xa(%r12)
addq $0x12, %r12
andb $0x3, %al
cmpb $0x1, %al
jne 0xa572
movq %rbp, 0x8(%rsp)
testq %r14, %r14
je 0xa525
xorl %r13d, %r13d
movq %r14, %rbp
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
decq %rbp
jne 0xa4f1
testq %r14, %r14
je 0xa5f3
movl $0x8, %r13d
movq 0x8(%rsp), %rbp
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
decq %r14
jne 0xa539
jmp 0xa5f8
testq %r14, %r14
je 0xa5ad
xorl %r13d, %r13d
movq 0x40(%rbx), %r15
movq (%r15,%r13,8), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r15,%r13,8)
movq 0x40(%rbx), %rax
movq (%rax,%r13,8), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
incq %r13
cmpq %r13, %r14
jne 0xa57a
xorl %eax, %eax
movq 0x48(%rbx), %rcx
movq (%rcx,%rax,8), %rdx
testb $0x20, 0x1c(%rdx)
jne 0xa62a
movq (%rdx), %rdx
bswapq %rdx
movq %rdx, (%r12)
movq (%rcx,%rax,8), %rdx
movq 0x8(%rdx), %rdx
bswapq %rdx
movq %rdx, 0x8(%r12)
movq (%rcx,%rax,8), %rcx
movl 0x18(%rcx), %ecx
bswapl %ecx
movl %ecx, 0x10(%r12)
addq $0x14, %r12
incq %rax
cmpq %r14, %rax
jbe 0xa5af
jmp 0xa5f8
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rax
addq 0x50(%rbx), %rax
cmpq %rax, %r12
jne 0xa6e4
xorl %ebx, %ebx
movq %r12, %rdi
xorl %esi, %esi
movq %rbp, %rdx
callq 0x21e0
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb064(%rip), %rdi      # 0x15695
leaq 0xafd0(%rip), %rsi      # 0x15608
leaq 0xafd5(%rip), %rcx      # 0x15614
movl $0x96, %edx
callq 0x21c0
leaq 0xa97b(%rip), %rdi      # 0x14fcb
leaq 0xafb1(%rip), %rsi      # 0x15608
leaq 0xafb6(%rip), %rcx      # 0x15614
movl $0x4f, %edx
callq 0x21c0
leaq 0xafda(%rip), %rdi      # 0x15649
leaq 0xaf92(%rip), %rsi      # 0x15608
leaq 0xaf97(%rip), %rcx      # 0x15614
movl $0x50, %edx
callq 0x21c0
leaq 0xafce(%rip), %rdi      # 0x1565c
leaq 0xaf73(%rip), %rsi      # 0x15608
leaq 0xaf78(%rip), %rcx      # 0x15614
movl $0x53, %edx
callq 0x21c0
leaq 0xafbf(%rip), %rdi      # 0x1566c
leaq 0xaf54(%rip), %rsi      # 0x15608
leaq 0xaf59(%rip), %rcx      # 0x15614
movl $0x56, %edx
callq 0x21c0
leaq 0xafb7(%rip), %rdi      # 0x15683
leaq 0xaf35(%rip), %rsi      # 0x15608
leaq 0xaf3a(%rip), %rcx      # 0x15614
movl $0x5c, %edx
callq 0x21c0
leaq 0xafc9(%rip), %rdi      # 0x156b4
leaq 0xaf16(%rip), %rsi      # 0x15608
leaq 0xaf1b(%rip), %rcx      # 0x15614
movl $0xa7, %edx
callq 0x21c0