// File: /workspace/github_c_makefile_star2_O2/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 0x1803
movq %rax, 0x8(%rsp)
movq 0x2c59(%rip), %rax      # 0x3fd8
movq (%rax), %r14
movq 0x2c6f(%rip), %rbx      # 0x3ff8
movq (%rbx), %rcx
leaq 0xc71(%rip), %rdi       # 0x2004
pushq $0x14
popq %rsi
pushq $0x1
popq %rdx
callq 0x1160
cmpl $0x2, 0x2d23(%rip)      # 0x40c8
jl 0x13ba
movq (%rbx), %rdi
leaq 0xc68(%rip), %rsi       # 0x2019
xorl %edx, %edx
xorl %eax, %eax
callq 0x10e0
leaq 0x10(%rsp), %r12
pushq $0x6
popq %rbp
movl $0x186a0, %r13d         # imm = 0x186A0
xorl %r15d, %r15d
movq %r14, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x143c
movq %r12, %rdi
movq %r14, %rsi
callq 0x1825
testl %eax, %eax
jne 0x13cb
movq %r12, %rdi
leaq 0xc40(%rip), %rsi       # 0x2030
movq %rbp, %rdx
callq 0x1120
testl %eax, %eax
je 0x162b
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x12a6
incq %r15
movq %r15, %rax
xorl %edx, %edx
divq %r13
testq %rdx, %rdx
jne 0x13cb
cmpl $0x2, 0x2ca4(%rip)      # 0x40c8
jl 0x13cb
movq (%rbx), %rdi
leaq 0xc8e(%rip), %rsi       # 0x20be
movq %r15, %rdx
xorl %eax, %eax
callq 0x10e0
jmp 0x13cb
cmpl $0x2, 0x2c85(%rip)      # 0x40c8
jl 0x1459
movq (%rbx), %rdi
leaq 0xc81(%rip), %rsi       # 0x20d0
movq %r15, %rdx
xorl %eax, %eax
callq 0x10e0
movl $0x30d40, %edi          # imm = 0x30D40
callq 0x1100
movq %rax, %r14
movl $0x30d4, %r12d          # imm = 0x30D4
xorl %ebx, %ebx
xorl %r13d, %r13d
cmpq $0x100000, %r13         # imm = 0x100000
je 0x14d8
movq 0x8(%rsp), %rax
leaq (%rax,%r13,8), %rbp
movq %rbx, %r15
shlq $0x4, %r15
orq $0x8, %r15
movq (%rbp), %rbp
testq %rbp, %rbp
je 0x14d3
movq (%rbp), %rax
movq %rax, -0x8(%r14,%r15)
movq 0x8(%rbp), %rax
movq %rax, (%r14,%r15)
incq %rbx
cmpq %r12, %rbx
jl 0x14c9
addq $0x9c4, %r12            # imm = 0x9C4
movq %r12, %rsi
shlq $0x4, %rsi
movq %r14, %rdi
callq 0x1130
movq %rax, %r14
addq $0x10, %rbp
addq $0x10, %r15
jmp 0x148e
incq %r13
jmp 0x1471
cmpl $0x2, 0x2be9(%rip)      # 0x40c8
jl 0x14fc
movq 0x2b10(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xbfa(%rip), %rsi       # 0x20ec
movq %rbx, %rdx
xorl %eax, %eax
callq 0x10e0
movq 0x2bdd(%rip), %rax      # 0x40e0
testq %rax, %rax
setg %cl
cmpq %rbx, %rax
setl %al
andb %cl, %al
cmpb $0x1, %al
jne 0x1533
leaq -0x28d(%rip), %rcx      # 0x128f
pushq $0x10
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1070
movq 0x2baf(%rip), %rsi      # 0x40e0
jmp 0x153d
movq %rbx, 0x2ba6(%rip)      # 0x40e0
movq %rbx, %rsi
leaq -0x2d8(%rip), %rcx      # 0x126c
pushq $0x10
popq %rdx
movq %r14, %rdi
callq 0x1070
leaq 0x8(%r14), %r15
leaq 0xbd8(%rip), %r13       # 0x2132
xorl %r12d, %r12d
movq 0x2b7c(%rip), %rcx      # 0x40e0
cmpq %rcx, %r12
jge 0x15ba
movq (%r15), %rax
movq 0x2b5d(%rip), %rdx      # 0x40d0
cmpq %rdx, %rax
jl 0x1592
movq -0x8(%r15), %rsi
movq %r13, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x10b0
incq %r12
addq $0x10, %r15
jmp 0x155d
cmpl $0x0, 0x2b2f(%rip)      # 0x40c8
jle 0x15ba
movq 0x2a56(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xb5c(%rip), %rsi       # 0x2108
xorl %eax, %eax
callq 0x10e0
movq 0x2b26(%rip), %rcx      # 0x40e0
cmpq %r12, %rcx
jne 0x15e8
cmpq %rbx, %r12
jge 0x15e8
cmpl $0x0, 0x2afd(%rip)      # 0x40c8
jle 0x15e8
movq 0x2a24(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xb5d(%rip), %rsi       # 0x213b
movq %r12, %rdx
xorl %eax, %eax
callq 0x10e0
movq 0x2a09(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xb67(%rip), %rsi       # 0x2160
xorl %ebp, %ebp
movq %r12, %rdx
xorl %eax, %eax
callq 0x10e0
movq 0x8(%rsp), %rdi
callq 0x196b
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 0xa01(%rip), %rdi       # 0x2036
pushq $0x1
popq %rdx
movl $0x87, %esi
callq 0x1160
movq 0x8(%rsp), %rdi
callq 0x196b
pushq $0x1
popq %rbp
jmp 0x1617