// File: chhylp123[P]hifiasm/htab.cpp
// Function: uidx_load(void**, ha_pt_s**, char*, ma_ug_t*)
int uidx_load(void **r_flt_tab, ha_pt_t **r_ha_idx, char* file_name, ma_ug_t *ug)
{
    char* gfa_name = (char*)malloc(strlen(file_name)+25);
    sprintf(gfa_name, "%s.uidx.bin", file_name);
    FILE* fp = fopen(gfa_name, "r");
    if (!fp) {
        free(gfa_name);
        return 0;
    }

	if(ug && (!test_dbug(ug, fp))) {
        fprintf(stderr, "[M::%s] Renew UL Index\n", __func__);
        free(gfa_name); fclose(fp);
        return 0;
    }
	// fprintf(stderr, "[M::%s]\t%s\tftell::%ld\n", __func__, file_name, ftell(fp));

    ha_pt_t *ha_idx = NULL;
    char mode = 0;
    int f_flag = 0, i;
    double index_time, index_s_time, pos_time, pos_s_time;

    
    
    f_flag += fread(&mode, 1, 1, fp);
    if(mode == 'f')
    {
        index_time = yak_realtime();

        yak_ft_load((yak_ft_t **)r_flt_tab, fp);
        
        f_flag += fread(&mode, 1, 1, fp);

        fprintf(stderr, "[M::%s::%.3f] ==> Loaded flt table\n", __func__, yak_realtime()-index_time);
    }
    ///insert using multiple threads???
    if(mode == 'h')
    {
        pos_time = index_time = 0;

        CALLOC(ha_idx, 1);
        ha_pt1_t *g;
        f_flag += fread(&ha_idx->k, sizeof(ha_idx->k), 1, fp);
        f_flag += fread(&ha_idx->pre, sizeof(ha_idx->pre), 1, fp);
        f_flag += fread(&ha_idx->tot, sizeof(ha_idx->tot), 1, fp);
        f_flag += fread(&ha_idx->tot_pos, sizeof(ha_idx->tot_pos), 1, fp);
        CALLOC(ha_idx->h, 1<<ha_idx->pre);
        for (i = 0; i < 1<<ha_idx->pre; ++i) 
        {
            index_s_time = yak_realtime();

            g = &(ha_idx->h[i]);
            yak_pt_load(&(g->h), fp);

            index_time += yak_realtime() - index_s_time;
            
            pos_s_time = yak_realtime();

            f_flag += fread(&g->n, sizeof(g->n), 1, fp);
            MALLOC(g->al, g->n);
            f_flag += fread(g->al, sizeof(ha_idxposl_t), g->n, fp);

            pos_time += yak_realtime() - pos_s_time;
        }
        (*r_ha_idx) = ha_idx;

        fprintf(stderr, "[M::%s::%.3f(index)/%.3f(pos)] ==> Loaded pos table\n", __func__, index_time, pos_time);
    }

    if(mode != 'h' && mode != 'f')
    {
        free(gfa_name);
        fclose(fp);
        return 0;
    }

    fprintf(stderr, "[M::%s] Index has been loaded.\n", __func__);

	fclose(fp);
    free(gfa_name);
    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x20a0
movq %rax, %rdi
addq $0x19, %rdi
callq 0x2270
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rdx
leaq 0x1ff719(%rip), %rsi    # 0x38af7c
movb $0x0, %al
callq 0x2050
movq -0x30(%rbp), %rdi
leaq 0x204b61(%rip), %rsi    # 0x3903d6
callq 0x2200
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x18b89a
movq -0x30(%rbp), %rdi
callq 0x2210
movl $0x0, -0x4(%rbp)
jmp 0x18bc22
cmpq $0x0, -0x28(%rbp)
je 0x18b8f0
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x101650
cmpl $0x0, %eax
jne 0x18b8f0
movq 0x238726(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x1ff6cf(%rip), %rsi    # 0x38af93
leaq 0x1ff6e0(%rip), %rdx    # 0x38afab
movb $0x0, %al
callq 0x22a0
movq -0x30(%rbp), %rdi
callq 0x2210
movq -0x38(%rbp), %rdi
callq 0x21a0
movl $0x0, -0x4(%rbp)
jmp 0x18bc22
movq $0x0, -0x40(%rbp)
movb $0x0, -0x41(%rbp)
movl $0x0, -0x48(%rbp)
movq -0x38(%rbp), %rcx
leaq -0x41(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movsbl -0x41(%rbp), %eax
cmpl $0x66, %eax
jne 0x18b998
callq 0x1b7ca0
movsd %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x18b5a0
movq -0x38(%rbp), %rcx
leaq -0x41(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq 0x238672(%rip), %rax    # 0x3c3fe0
movq (%rax), %rax
movq %rax, -0x80(%rbp)
callq 0x1b7ca0
movq -0x80(%rbp), %rdi
subsd -0x58(%rbp), %xmm0
leaq 0x1ff567(%rip), %rsi    # 0x38aef1
leaq 0x1ff61a(%rip), %rdx    # 0x38afab
movb $0x1, %al
callq 0x22a0
movsbl -0x41(%rbp), %eax
cmpl $0x68, %eax
jne 0x18bbbd
xorps %xmm0, %xmm0
movsd %xmm0, -0x58(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x68(%rbp)
movl $0x1, %edi
movl $0x20, %esi
callq 0x2140
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
addq $0x4, %rdi
movq -0x38(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
addq $0x10, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movl 0x4(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movslq %eax, %rdi
movl $0x20, %esi
callq 0x2140
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x18(%rax)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x40(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jge 0x18bb89
callq 0x1b7ca0
movsd %xmm0, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x18b5d0
callq 0x1b7ca0
subsd -0x60(%rbp), %xmm0
addsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
callq 0x1b7ca0
movsd %xmm0, -0x70(%rbp)
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
shlq $0x4, %rdi
callq 0x2270
movq %rax, %rcx
movq -0x78(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x78(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x38(%rbp), %rcx
movl $0x10, %esi
callq 0x22e0
movq %rax, %rcx
movslq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x48(%rbp)
callq 0x1b7ca0
subsd -0x70(%rbp), %xmm0
addsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x18ba91
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq 0x238445(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movsd -0x58(%rbp), %xmm0
movsd -0x68(%rbp), %xmm1
leaq 0x1ff374(%rip), %rsi    # 0x38af23
leaq 0x1ff3f5(%rip), %rdx    # 0x38afab
movb $0x2, %al
callq 0x22a0
movsbl -0x41(%rbp), %eax
cmpl $0x68, %eax
je 0x18bbea
movsbl -0x41(%rbp), %eax
cmpl $0x66, %eax
je 0x18bbea
movq -0x30(%rbp), %rdi
callq 0x2210
movq -0x38(%rbp), %rdi
callq 0x21a0
movl $0x0, -0x4(%rbp)
jmp 0x18bc22
movq 0x2383ef(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x1ff2ab(%rip), %rsi    # 0x38aea6
leaq 0x1ff3a9(%rip), %rdx    # 0x38afab
movb $0x0, %al
callq 0x22a0
movq -0x38(%rbp), %rdi
callq 0x21a0
movq -0x30(%rbp), %rdi
callq 0x2210
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nop