// File: /workspace/github_c_makefile_star2_O3/stanfordnlp[P]GloVe/src/vocab_count.c
// Function: get_counts
int get_counts(void) {
    long long i = 0, j = 0, vocab_size = 12500;
    // char format[20];
    char str[MAX_STRING_LENGTH + 1];
    HASHREC **vocab_hash = inithashtable();
    HASHREC *htmp;
    VOCAB *vocab;
    FILE *fid = stdin;
    
    fprintf(stderr, "BUILDING VOCABULARY\n");
    if (verbose > 1) fprintf(stderr, "Processed %lld tokens.", i);
    // sprintf(format,"%%%ds",MAX_STRING_LENGTH);
    while ( ! feof(fid)) {
        // Insert all tokens into hashtable
        int nl = get_word(str, fid);
        if (nl) continue; // just a newline marker or feof
        if (strcmp(str, "<unk>") == 0) {
            fprintf(stderr, "\nError, <unk> vector found in corpus.\nPlease remove <unk>s from your corpus (e.g. cat text8 | sed -e 's/<unk>/<raw_unk>/g' > text8.new)");
            free_table(vocab_hash);
            return 1;
        }
        hashinsert(vocab_hash, str);
        if (((++i)%100000) == 0) if (verbose > 1) fprintf(stderr,"\033[11G%lld tokens.", i);
    }
    if (verbose > 1) fprintf(stderr, "\033[0GProcessed %lld tokens.\n", i);
    vocab = malloc(sizeof(VOCAB) * vocab_size);
    for (i = 0; i < TSIZE; i++) { // Migrate vocab to array
        htmp = vocab_hash[i];
        while (htmp != NULL) {
            vocab[j].word = htmp->word;
            vocab[j].count = htmp->num;
            j++;
            if (j>=vocab_size) {
                vocab_size += 2500;
                vocab = (VOCAB *)realloc(vocab, sizeof(VOCAB) * vocab_size);
            }
            htmp = htmp->next;
        }
    }
    if (verbose > 1) fprintf(stderr, "Counted %lld unique words.\n", j);
    if (max_vocab > 0 && max_vocab < j)
        // If the vocabulary exceeds limit, first sort full vocab by frequency without alphabetical tie-breaks.
        // This results in pseudo-random ordering for words with same frequency, so that when truncated, the words span whole alphabet
        qsort(vocab, j, sizeof(VOCAB), CompareVocab);
    else max_vocab = j;
    qsort(vocab, max_vocab, sizeof(VOCAB), CompareVocabTie); //After (possibly) truncating, sort (possibly again), breaking ties alphabetically
    
    for (i = 0; i < max_vocab; i++) {
        if (vocab[i].count < min_count) { // If a minimum frequency cutoff exists, truncate vocabulary
            if (verbose > 0) fprintf(stderr, "Truncating vocabulary at min count %lld.\n",min_count);
            break;
        }
        printf("%s %lld\n",vocab[i].word,vocab[i].count);
    }
    
    if (i == max_vocab && max_vocab < j) if (verbose > 0) fprintf(stderr, "Truncating vocabulary at size %lld.\n", max_vocab);
    fprintf(stderr, "Using vocabulary of size %lld.\n\n", i);
    free_table(vocab_hash);
    free(vocab);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x408, %rsp            # imm = 0x408
callq 0x1920
movq %rax, 0x8(%rsp)
movq 0x2e26(%rip), %rax      # 0x3fd8
movq (%rax), %r14
movq 0x2e3c(%rip), %rbx      # 0x3ff8
movq (%rbx), %rcx
leaq 0xe3e(%rip), %rdi       # 0x2004
pushq $0x14
popq %rsi
pushq $0x1
popq %rdx
callq 0x1170
cmpl $0x2, 0x2ef8(%rip)      # 0x40d0
jl 0x11ed
movq (%rbx), %rdi
leaq 0xe35(%rip), %rsi       # 0x2019
xorl %edx, %edx
xorl %eax, %eax
callq 0x10f0
movq %r14, %rdi
callq 0x1100
testl %eax, %eax
jne 0x1281
leaq 0x10(%rsp), %r12
pushq $0x6
popq %rbp
movl $0x186a0, %r13d         # imm = 0x186A0
xorl %r15d, %r15d
movq %r12, %rdi
movq %r14, %rsi
callq 0x192f
testl %eax, %eax
jne 0x125d
movq %r12, %rdi
leaq 0xe09(%rip), %rsi       # 0x2030
movq %rbp, %rdx
callq 0x1130
testl %eax, %eax
je 0x1493
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x16f6
incq %r15
movq %r15, %rax
cqto
idivq %r13
testq %rdx, %rdx
jne 0x125d
cmpl $0x2, 0x2e75(%rip)      # 0x40d0
jge 0x126b
movq %r14, %rdi
callq 0x1100
testl %eax, %eax
je 0x120e
jmp 0x1284
movq (%rbx), %rdi
leaq 0xe49(%rip), %rsi       # 0x20be
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
jmp 0x125d
xorl %r15d, %r15d
cmpl $0x2, 0x2e45(%rip)      # 0x40d0
jl 0x12a1
movq (%rbx), %rdi
leaq 0xe39(%rip), %rsi       # 0x20d0
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
movl $0x30d40, %edi          # imm = 0x30D40
callq 0x1110
movq %rax, %r14
movl $0x30d4, %r12d          # imm = 0x30D4
xorl %r13d, %r13d
xorl %ebx, %ebx
movq 0x8(%rsp), %rax
movq (%rax,%r13,8), %rbp
testq %rbp, %rbp
je 0x1311
movq %rbx, %r15
shlq $0x4, %r15
orq $0x8, %r15
movq (%rbp), %rax
movq %rax, -0x8(%r14,%r15)
movq 0x8(%rbp), %rax
movq %rax, (%r14,%r15)
incq %rbx
cmpq %r12, %rbx
jl 0x1304
addq $0x9c4, %r12            # imm = 0x9C4
movq %r12, %rsi
shlq $0x4, %rsi
movq %r14, %rdi
callq 0x1140
movq %rax, %r14
movq 0x10(%rbp), %rbp
addq $0x10, %r15
testq %rbp, %rbp
jne 0x12d2
incq %r13
cmpq $0x100000, %r13         # imm = 0x100000
jne 0x12b9
cmpl $0x2, 0x2dac(%rip)      # 0x40d0
jl 0x1341
movq 0x2ccb(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xdb5(%rip), %rsi       # 0x20ec
movq %rbx, %rdx
xorl %eax, %eax
callq 0x10f0
movq 0x2da0(%rip), %rax      # 0x40e8
testq %rax, %rax
setg %cl
cmpq %rbx, %rax
setl %al
andb %cl, %al
cmpb $0x1, %al
jne 0x1378
leaq 0x37e(%rip), %rcx       # 0x16df
pushq $0x10
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1070
movq 0x2d72(%rip), %rsi      # 0x40e8
jmp 0x1382
movq %rbx, 0x2d69(%rip)      # 0x40e8
movq %rbx, %rsi
leaq 0x333(%rip), %rcx       # 0x16bc
pushq $0x10
popq %rdx
movq %r14, %rdi
callq 0x1070
movq 0x2d4d(%rip), %rdx      # 0x40e8
testq %rdx, %rdx
jle 0x13b5
movq 0x8(%r14), %rcx
movq 0x2d2d(%rip), %rax      # 0x40d8
cmpq %rax, %rcx
jge 0x13ba
xorl %r12d, %r12d
jmp 0x13fa
xorl %r12d, %r12d
jmp 0x1425
leaq 0xd71(%rip), %r13       # 0x2132
movq %r14, %r15
xorl %r12d, %r12d
movq (%r15), %rsi
movq %r13, %rdi
movq %rcx, %rdx
xorl %eax, %eax
callq 0x10b0
incq %r12
movq 0x2d07(%rip), %rdx      # 0x40e8
cmpq %rdx, %r12
jge 0x1425
movq 0x18(%r15), %rcx
movq 0x2ce7(%rip), %rax      # 0x40d8
addq $0x10, %r15
cmpq %rax, %rcx
jge 0x13c7
cmpl $0x0, 0x2ccf(%rip)      # 0x40d0
jle 0x1425
movq 0x2bee(%rip), %rcx      # 0x3ff8
movq (%rcx), %rdi
leaq 0xcf4(%rip), %rsi       # 0x2108
movq %rax, %rdx
xorl %eax, %eax
callq 0x10f0
movq 0x2cc3(%rip), %rdx      # 0x40e8
cmpq %rdx, %r12
jne 0x1450
cmpq %rbx, %rdx
jge 0x1450
cmpl $0x0, 0x2c9a(%rip)      # 0x40d0
jle 0x1450
movq 0x2bb9(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xcf2(%rip), %rsi       # 0x213b
xorl %eax, %eax
callq 0x10f0
movq 0x2ba1(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xcff(%rip), %rsi       # 0x2160
xorl %ebp, %ebp
movq %r12, %rdx
xorl %eax, %eax
callq 0x10f0
movq 0x8(%rsp), %rdi
callq 0x1a92
movq %r14, %rdi
callq 0x1030
movl %ebp, %eax
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbx), %rcx
leaq 0xb99(%rip), %rdi       # 0x2036
pushq $0x1
popq %rdx
movl $0x87, %esi
callq 0x1170
movq 0x8(%rsp), %rdi
callq 0x1a92
pushq $0x1
popq %rbp
jmp 0x147f