// File: /workspace/github_c_makefile_star2_O3/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 0xa52d
movq %rsi, %rbx
cmpq $0x0, 0x50(%rsi)
jne 0xa54c
cmpb $-0x1, 0x1d(%rbx)
je 0xa56b
cmpq $0x10000, 0x38(%rbx)    # imm = 0x10000
jae 0xa58a
movq %rdx, %r12
movq %rdi, %r13
movq %rbx, %rdi
callq 0xa5e7
movq %r12, %rbp
subq %rax, %rbp
jb 0xa5a9
movq %rax, %r14
movq %r12, %rdi
callq 0x22a0
movq %rax, 0x50(%rbx)
testq %rax, %rax
je 0xa39a
movq %rax, %r12
movq %r14, 0x10(%rsp)
movw $0x53, 0x4(%r12)
movl $0x444c564b, (%r12)     # imm = 0x444C564B
movq 0x38(%rbx), %r15
movl %r15d, %ecx
rolw $0x8, %cx
movw %cx, 0x6(%r12)
movb 0x1c(%rbx), %cl
movb 0x1d(%rbx), %dl
testb $0x10, %cl
jne 0xa3a4
movb 0x1e(%rbx), %sil
movl $0xa, %edi
jmp 0xa3bb
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0xa4fd
addb $-0x80, %dl
movb 0x1e(%rbx), %sil
movq 0x48(%r13), %rdi
bswapq %rdi
movq %rdi, 0xa(%rax)
movl $0x12, %edi
addq %rdi, %r12
movb %dl, 0x8(%rax)
movb %sil, 0x9(%rax)
andb $0x3, %cl
cmpb $0x1, %cl
jne 0xa45d
testq %r15, %r15
je 0xa4dc
movq %rbp, 0x8(%rsp)
movq 0x40(%rbx), %r14
xorl %r13d, %r13d
movq %r15, %rbp
movq (%r14,%r13), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r14,%r13)
movq 0x40(%rbx), %r14
movq (%r14,%r13), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
addq $0x10, %r13
decq %rbp
jne 0xa3e9
movq 0x40(%rbx), %r13
movl $0x8, %r14d
movq 0x8(%rsp), %rbp
movq (%r13,%r14), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r13,%r14)
movq 0x40(%rbx), %r13
movq (%r13,%r14), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
addq $0x10, %r14
decq %r15
jne 0xa428
jmp 0xa4dc
testq %r15, %r15
je 0xa498
movq 0x40(%rbx), %r14
xorl %r13d, %r13d
movq (%r14,%r13,8), %rsi
movzbl (%rsi), %edx
incq %rdx
movq %r12, %rdi
callq 0x2280
movq %r12, (%r14,%r13,8)
movq 0x40(%rbx), %r14
movq (%r14,%r13,8), %rax
movzbl (%rax), %eax
addq %rax, %r12
incq %r12
incq %r13
cmpq %r13, %r15
jne 0xa469
xorl %eax, %eax
movq 0x48(%rbx), %rcx
movq (%rcx,%rax,8), %rdx
testb $0x20, 0x1c(%rdx)
jne 0xa50e
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 %r15, %rax
jbe 0xa49a
movq 0x10(%rsp), %rax
addq 0x50(%rbx), %rax
cmpq %rax, %r12
jne 0xa5c8
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 0xb13b(%rip), %rdi      # 0x15650
leaq 0xb0a7(%rip), %rsi      # 0x155c3
leaq 0xb0ac(%rip), %rcx      # 0x155cf
movl $0x96, %edx
callq 0x21c0
leaq 0xaa52(%rip), %rdi      # 0x14f86
leaq 0xb088(%rip), %rsi      # 0x155c3
leaq 0xb08d(%rip), %rcx      # 0x155cf
movl $0x4f, %edx
callq 0x21c0
leaq 0xb0b1(%rip), %rdi      # 0x15604
leaq 0xb069(%rip), %rsi      # 0x155c3
leaq 0xb06e(%rip), %rcx      # 0x155cf
movl $0x50, %edx
callq 0x21c0
leaq 0xb0a5(%rip), %rdi      # 0x15617
leaq 0xb04a(%rip), %rsi      # 0x155c3
leaq 0xb04f(%rip), %rcx      # 0x155cf
movl $0x53, %edx
callq 0x21c0
leaq 0xb096(%rip), %rdi      # 0x15627
leaq 0xb02b(%rip), %rsi      # 0x155c3
leaq 0xb030(%rip), %rcx      # 0x155cf
movl $0x56, %edx
callq 0x21c0
leaq 0xb08e(%rip), %rdi      # 0x1563e
leaq 0xb00c(%rip), %rsi      # 0x155c3
leaq 0xb011(%rip), %rcx      # 0x155cf
movl $0x5c, %edx
callq 0x21c0
leaq 0xb0a0(%rip), %rdi      # 0x1566f
leaq 0xafed(%rip), %rsi      # 0x155c3
leaq 0xaff2(%rip), %rcx      # 0x155cf
movl $0xa7, %edx
callq 0x21c0