// File: karel-brinda[P]ococo/ext/htslib/cram/cram_encode.c
// Function: lossy_read_names
static int lossy_read_names(cram_fd *fd, cram_container *c, cram_slice *s,
			    int bam_start) {
    int r1, r2, ret = -1;

    // Initialise cram_flags
    for (r2 = 0; r2 < s->hdr->num_records; r2++)
	s->crecs[r2].cram_flags = 0;

    if (!fd->lossy_read_names)
	return 0;

    khash_t(m_s2u64) *names = kh_init(m_s2u64);
    if (!names)
	goto fail;

    // 1: Iterate through names to count frequency
    for (r1 = bam_start, r2 = 0; r2 < s->hdr->num_records; r1++, r2++) {
	//cram_record *cr = &s->crecs[r2];
	bam_seq_t *b = c->bams[r1];
	khint_t k;
	int n;
	uint64_t e;
	union {
	    uint64_t i64;
	    struct {
		int32_t e,c; // expected & observed counts.
	    };
	} u;

	e = expected_template_count(b);
	u.e = e; u.c = 1;

	k = kh_put(m_s2u64, names, bam_name(b), &n);
	if (n == -1)
	    goto fail;

	if (n == 0) {
	    // not a new name
	    u.i64 = kh_val(names, k);
	    if (u.e != e) {
		// different expectation or already hit the max
		//fprintf(stderr, "Err computing no. %s recs\n", bam_name(b));
		kh_val(names, k) = 0;
	    } else {
		u.c++;
		if (u.e == u.c) {
		    // Reached expected count.
		    kh_val(names, k) = -1;
		} else {
		    kh_val(names, k) = u.i64;
		}
	    }
	} else {
	    // new name
	    kh_val(names, k) = u.i64;
	}
    }

    // 2: Remove names if all present (hd.i == -1)
    for (r1 = bam_start, r2 = 0; r2 < s->hdr->num_records; r1++, r2++) {
	cram_record *cr = &s->crecs[r2];
	bam_seq_t *b = c->bams[r1];
	khint_t k;

	k = kh_get(m_s2u64, names, bam_name(b));

	if (k == kh_end(names))
	    goto fail;

	if (kh_val(names, k) == -1)
	    cr->cram_flags = CRAM_FLAG_DISCARD_NAME;
    }

    ret = 0;
 fail: // ret==-1

    if (names)
	kh_destroy(m_s2u64, names);

    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x10(%rcx), %eax
jge 0x36c39
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x10(%rax)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x36c05
movq -0x10(%rbp), %rax
cmpl $0x0, 0x88fc(%rax)
jne 0x36c52
movl $0x0, -0x4(%rbp)
jmp 0x36e41
callq 0x3a900
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x36c67
jmp 0x36e2b
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x10(%rcx), %eax
jge 0x36d7f
movq -0x18(%rbp), %rax
movq 0xb8(%rax), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x3a920
cltq
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl %eax, -0x58(%rbp)
movl $0x1, -0x54(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rsi
leaq -0x48(%rbp), %rdx
callq 0x3a9c0
movl %eax, -0x44(%rbp)
cmpl $-0x1, -0x48(%rbp)
jne 0x36cde
jmp 0x36e2b
cmpl $0x0, -0x48(%rbp)
jne 0x36d53
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movslq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
je 0x36d16
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
jmp 0x36d51
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x54(%rbp), %eax
jne 0x36d3c
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movq $-0x1, (%rax,%rcx,8)
jmp 0x36d4f
movq -0x58(%rbp), %rdx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
jmp 0x36d51
jmp 0x36d66
movq -0x58(%rbp), %rdx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
jmp 0x36d68
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x36c74
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x10(%rcx), %eax
jge 0x36e24
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rax
movq 0xb8(%rax), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x68(%rbp)
movq -0x38(%rbp), %rdi
movq -0x68(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x3ad20
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movq -0x38(%rbp), %rcx
cmpl (%rcx), %eax
jne 0x36dee
jmp 0x36e2b
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x6c(%rbp), %ecx
cmpq $-0x1, (%rax,%rcx,8)
jne 0x36e0b
movq -0x60(%rbp), %rax
movl $0x80000000, 0x10(%rax) # imm = 0x80000000
jmp 0x36e0d
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x36d8c
movl $0x0, -0x30(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x36e3b
movq -0x38(%rbp), %rdi
callq 0x3ae70
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw (%rax,%rax)