// File: /workspace/github_c_makefile_star2_O1/desion[P]terminal/src/terminal.c
// Function: worker
static void* worker(void *arg)
{
    pthread_detach(pthread_self()); //detach the work thread

    hdb_t *hdb = (hdb_t *)arg;
    hdict_t *hdict;
    conn *c;
    while(1) {
        c = cq_pop(&REQ);

        struct timeval now;
        gettimeofday(&now, NULL);

        struct timeval tv;
        mytimesub(&now, &c->tv, &tv);
        
        if (settings.timeout > 0 && tv.tv_sec * 1000 + tv.tv_usec/1000 > settings.timeout) {    /* process timeout */
            pack_string(c, "SERVER_ERROR timeout");
            STATS_LOCK(stats);
            stats.timeouts++;
            STATS_UNLOCK(stats);
        } else if (strcmp(c->cmd, "stats") == 0) {      /* process stats command */
            char temp[1024];
            pid_t pid = getpid();
            char *pos = temp;

            uint32_t length = cq_length(&REQ);
            STATS_LOCK(stats);
            pos += sprintf(pos, "STAT pid %u\r\n", pid);
            pos += sprintf(pos, "STAT uptime %lld\r\n", (long long)stats.started);
            pos += sprintf(pos, "STAT curr_connections %u\r\n", stats.curr_conns - 1); /* ignore listening conn */
            pos += sprintf(pos, "STAT connection_structures %u\r\n", stats.conn_structs);
            pos += sprintf(pos, "STAT cmd_get %u\r\n", stats.get_cmds);
            pos += sprintf(pos, "STAT get_hits %u\r\n", stats.get_hits);
            pos += sprintf(pos, "STAT get_misses %u\r\n", stats.get_misses);
            pos += sprintf(pos, "STAT threads %u\r\n", settings.num_threads);
            pos += sprintf(pos, "STAT timeouts %u\r\n", stats.timeouts);
            pos += sprintf(pos, "STAT waiting_requests %u\r\n", length);
            pos += sprintf(pos, "STAT ialloc_failed %u\r\n", stats.ialloc_failed);
            pos += sprintf(pos, "END");
            STATS_UNLOCK(stats);
            pack_string(c, temp);
        } else if (strcmp(c->cmd, "stats reset") == 0) {    /* reset the status */
            STATS_LOCK(stats);
            stats.get_cmds = 0;
            stats.get_hits = 0;
            stats.get_misses = 0;
            stats.timeouts = 0;
            stats.ialloc_failed = 0;
            STATS_UNLOCK(stats);
            pack_string(c, "RESET");
        } else if (strncmp(c->cmd, "open ", 5) == 0 ||
            strncmp(c->cmd, "reopen ", 7) == 0) {   /* open or reopen the db */

            char path[256];
            int res = sscanf(c->cmd, "%*s %255s\n", path);
            if (res != 1 || strlen(path) == 0) {
                pack_string(c, "CLIENT_ERROR bad command line format");
            } else {
                int status = hdb_reopen(hdb, path);
                if (status == 0) {
                    pack_string(c, "OPENED");
                } else {
                    if (settings.verbose > 0)
                        fprintf(stderr, "failed to open %s, return %d\n",
                            path, status);
                    if (status == EHDICT_OUT_OF_MEMERY) {
                        STATS_LOCK(stats);
                        stats.ialloc_failed++;
                        STATS_UNLOCK(stats);
                    }
                    pack_string(c, "SERVER_ERROR open failed");
                }
            }
        } else if (strncmp(c->cmd, "append ", 7) == 0) {   /* open or reopen the db */
            char path[256];
            int res = sscanf(c->cmd, "%*s %255s\n", path);
            if (res != 1 || strlen(path) == 0) {
                pack_string(c, "CLIENT_ERROR bad command line format");
            } else {
                int status = hdb_append(hdb, path);
                if (status == 0) {
                    pack_string(c, "OPENED");
                } else {
                    if (settings.verbose > 0)
                        fprintf(stderr, "failed to open %s, return %d\n",path, status);
                    if (status == EHDICT_OUT_OF_MEMERY) {
                        STATS_LOCK(stats);
                        stats.ialloc_failed++;
                        STATS_UNLOCK(stats);
                    }
                    pack_string(c, "SERVER_ERROR open failed");
                }
            }
        } else if (strncmp(c->cmd, "close ", 6) == 0) {     /* close the db */
            char label[21];
            int res;
            const char* command = c->cmd + 6;
            int pos = find_index(command, ' ');
            if (pos < 0){
                res = hdb_close(hdb, command, 0);
            }else{
                strncpy(label, command, pos);
                uint32_t version = strtoul(command + pos + 1, NULL, 10);
                res = hdb_close(hdb, label, version); 
            }
            if (res >= 1) {
                pack_string(c, "CLOSED");
            } else {
                pack_string(c, "NOT_FOUND");
            }
        } else if (strncmp(c->cmd, "info", 4) == 0) {   /* show the hdb info */
            char temp[4096];
            hdb_info(hdb, temp, 4096);
            pack_string(c, temp);
        } else if (strncmp(c->cmd, "get ", 4) == 0) {   /* get the key from db */
            char *start = c->cmd + 4;
            char token[251];
            char label[21];
            int next;
            //uint64_t key;
            off_t off;
            uint32_t length;
            c->wbytes = 0;
            int res, nc;
            char *en_dash;
            while(sscanf(start, " %250s%n", token, &next) >= 1) {
                start += next;

                STATS_LOCK(stats);
                stats.get_cmds++;
                STATS_UNLOCK(stats);
                char *str_key;
                if ((en_dash = strchr(token, '-')) == NULL) {
                    //key = strtoull(token, NULL, 10);
                    str_key = token;
                } else {
                    *en_dash = '\0';
                    strcpy(label, token);
                    //key = strtoull(en_dash+1, NULL, 10);
                    str_key = en_dash+1;
                }
                if (hdict_search(hdb, label, str_key, &off, &length, &hdict)) {
                    STATS_LOCK(stats);
                    stats.get_hits++;
                    STATS_UNLOCK(stats);
                    if (length < HDICT_VALUE_LENGTH_MAX) {
                        if (c->wsize - c->wbytes < 512 + length) {
                            int relloc_length = c->wsize * 2;
                            if (relloc_length - c->wbytes < 512 + length) {
                                relloc_length = 512 + length + c->wbytes;
                                relloc_length = (relloc_length/DATA_BUFFER_SIZE + 1) * DATA_BUFFER_SIZE;
                            }
                            char *newbuf = (char *)realloc(c->wbuf, relloc_length);
                            if (newbuf) {
                                c->wbuf = newbuf;
                                c->wsize = relloc_length;
                            } else {
                                if (settings.verbose > 0)
                                    fprintf(stderr, "Couldn't realloc output buffer\n");
                            }
                        }

                        nc = sprintf(c->wbuf + c->wbytes, "VALUE %s %u %u\r\n", token, 0, length);
                        res = hdict_read(hdict, c->wbuf + c->wbytes + nc, length, off);
                        if (res != length) {
                            if (settings.verbose > 0)
                                fprintf(stderr, "Failed to read from hdict\n");
                        }

                        c->wbytes += nc;
                        c->wbytes += length;
                        c->wbytes += sprintf(c->wbuf + c->wbytes, "\r\n");
                    }
                } else {
                    STATS_LOCK(stats);
                    stats.get_misses++;
                    STATS_UNLOCK(stats);
                }
            }
            c->wbytes += sprintf(c->wbuf + c->wbytes, "END\r\n");
        } else {
            pack_string(c, "ERROR");
        }

        cq_push(&RSP, c);
        pthread_mutex_lock(&notify_lock);
        if (write(notify_send_fd, "", 1) != 1) {
            perror("Writing to thread notify pipe");
        }
        pthread_mutex_unlock(&notify_lock);
    }

    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1068, %rsp           # imm = 0x1068
movq %rdi, 0x8(%rsp)
callq 0x2350
movq %rax, %rdi
callq 0x22d0
leaq 0x4b32(%rip), %r15      # 0x9288
leaq 0x4c4b(%rip), %r12      # 0x93a8
leaq 0x4c6c(%rip), %rbx      # 0x93d0
leaq 0x60(%rsp), %r14
leaq 0x40(%rsp), %r13
movq %r15, %rdi
callq 0x396d
movq %rax, %rbp
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x2170
movslq 0x4af0(%rip), %rcx      # 0x927c
testq %rcx, %rcx
jle 0x4816
movq 0x38(%rsp), %rsi
subq 0xd8(%rbp), %rsi
leaq 0xf4240(%rsi), %rax
testq %rsi, %rsi
cmovnsq %rsi, %rax
movq 0x30(%rsp), %rdx
subq 0xd0(%rbp), %rdx
sarq $0x3f, %rsi
addq %rdx, %rsi
movabsq $0x20c49ba5e353f7cf, %rdx # imm = 0x20C49BA5E353F7CF
imulq %rdx
imulq $0x3e8, %rsi, %rax      # imm = 0x3E8
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x7, %rdx
addq %rsi, %rdx
addq %rax, %rdx
cmpq %rcx, %rdx
jle 0x4816
movq %rbp, %rdi
leaq 0x15e8(%rip), %rsi      # 0x5dde
callq 0x42cb
movq %r12, %rdi
callq 0x2470
incl 0x4b97(%rip)            # 0x93a0
movq %r12, %rdi
callq 0x22b0
jmp 0x4ebb
movq 0xc8(%rbp), %rbx
movq %rbx, %rdi
leaq 0x15cc(%rip), %rsi      # 0x5df3
callq 0x2220
testl %eax, %eax
je 0x4902
movq %rbx, %rdi
leaq 0x16a9(%rip), %rsi      # 0x5ee7
callq 0x2220
testl %eax, %eax
je 0x4b16
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x16a1(%rip), %rsi      # 0x5efb
callq 0x2070
testl %eax, %eax
je 0x4a7f
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x1683(%rip), %rsi      # 0x5ef9
callq 0x2070
testl %eax, %eax
je 0x4a7f
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x16dd(%rip), %rsi      # 0x5f6f
callq 0x2070
testl %eax, %eax
je 0x4b4f
movl $0x6, %edx
movq %rbx, %rdi
leaq 0x16c9(%rip), %rsi      # 0x5f77
callq 0x2070
testl %eax, %eax
je 0x4b9b
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x16c5(%rip), %rsi      # 0x5f8f
callq 0x2070
testl %eax, %eax
je 0x4bb3
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x16ae(%rip), %rsi      # 0x5f94
callq 0x2070
testl %eax, %eax
je 0x4c11
movq %rbp, %rdi
leaq 0x16f7(%rip), %rsi      # 0x5ff4
jmp 0x4eaf
callq 0x2100
movl %eax, %r14d
movq %r15, %rdi
callq 0x3a41
movl %eax, %ebx
movq %r12, %rdi
callq 0x2470
leaq 0x60(%rsp), %rdi
leaq 0x14d1(%rip), %rsi      # 0x5df9
movl %r14d, %edx
xorl %eax, %eax
callq 0x23f0
cltq
leaq (%rsp,%rax), %r14
addq $0x60, %r14
movq 0x4a55(%rip), %rdx      # 0x9398
movq %r14, %rdi
leaq 0x14ba(%rip), %rsi      # 0x5e07
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4a20(%rip), %edx      # 0x9380
decl %edx
movq %r15, %rdi
leaq 0x14ae(%rip), %rsi      # 0x5e1a
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x4a05(%rip), %edx      # 0x9384
movq %r14, %rdi
leaq 0x14ac(%rip), %rsi      # 0x5e35
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x49ec(%rip), %edx      # 0x9388
movq %r15, %rdi
leaq 0x14af(%rip), %rsi      # 0x5e55
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x49d3(%rip), %edx      # 0x938c
movq %r14, %rdi
leaq 0x14a4(%rip), %rsi      # 0x5e67
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x49ba(%rip), %edx      # 0x9390
movq %r15, %rdi
leaq 0x149a(%rip), %rsi      # 0x5e7a
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x4881(%rip), %edx      # 0x9274
movq %r14, %rdi
leaq 0x1492(%rip), %rsi      # 0x5e8f
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4990(%rip), %edx      # 0x93a0
movq %r15, %rdi
leaq 0x1487(%rip), %rsi      # 0x5ea1
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
leaq 0x485a(%rip), %r15      # 0x9288
movq %r14, %rdi
leaq 0x147c(%rip), %rsi      # 0x5eb4
movl %ebx, %edx
xorl %eax, %eax
callq 0x23f0
movslq %eax, %rbx
addq %r14, %rbx
leaq 0x60(%rsp), %r14
movl 0x4952(%rip), %edx      # 0x93a4
movq %rbx, %rdi
leaq 0x1473(%rip), %rsi      # 0x5ecf
xorl %eax, %eax
callq 0x23f0
cltq
movl $0x444e45, (%rax,%rbx)  # imm = 0x444E45
movq %r12, %rdi
callq 0x22b0
movq %rbp, %rdi
movq %r14, %rsi
jmp 0x4eaf
movq 0xc8(%rbp), %rdi
leaq 0x1474(%rip), %rsi      # 0x5f01
movq %r14, %rdx
xorl %eax, %eax
callq 0x22e0
leaq 0x146e(%rip), %rsi      # 0x5f0c
cmpl $0x1, %eax
jne 0x4eac
cmpb $0x0, 0x60(%rsp)
leaq 0x1459(%rip), %rsi      # 0x5f0c
je 0x4eac
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x3085
leaq 0x1464(%rip), %rsi      # 0x5f31
testl %eax, %eax
je 0x4eac
movl %eax, %ebx
cmpl $0x0, 0x479a(%rip)      # 0x9278
jg 0x4f0a
leaq 0x146b(%rip), %rsi      # 0x5f56
cmpl $-0x1, %ebx
jne 0x4eac
movq %r12, %rdi
callq 0x2470
incl 0x48a2(%rip)            # 0x93a4
movq %r12, %rdi
callq 0x22b0
leaq 0x1445(%rip), %rsi      # 0x5f56
jmp 0x4eac
movq %r12, %rdi
callq 0x2470
xorl %eax, %eax
movq %rax, 0x4861(%rip)      # 0x9388
movl $0x0, 0x485f(%rip)      # 0x9390
movq %rax, 0x4868(%rip)      # 0x93a0
movq %r12, %rdi
callq 0x22b0
movq %rbp, %rdi
leaq 0x13a9(%rip), %rsi      # 0x5ef3
jmp 0x4eaf
movq 0xc8(%rbp), %rdi
leaq 0x13a4(%rip), %rsi      # 0x5f01
movq %r14, %rdx
xorl %eax, %eax
callq 0x22e0
leaq 0x139e(%rip), %rsi      # 0x5f0c
cmpl $0x1, %eax
jne 0x4eac
cmpb $0x0, 0x60(%rsp)
leaq 0x1389(%rip), %rsi      # 0x5f0c
je 0x4eac
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x2f86
jmp 0x4ac6
addq $0x6, %rbx
xorl %eax, %eax
movzbl (%rbx,%rax), %ecx
testl %ecx, %ecx
je 0x4bca
cmpl $0x20, %ecx
je 0x4bcf
incq %rax
jmp 0x4ba1
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0x32e9
jmp 0x4a74
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testl %eax, %eax
js 0x4e89
movl %eax, %r14d
leaq 0x60(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2050
leaq (%rbx,%r14), %rdi
incq %rdi
leaq 0x60(%rsp), %r14
xorl %esi, %esi
movl $0xa, %edx
callq 0x23c0
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movl %eax, %edx
jmp 0x4e93
addq $0x4, %rbx
movl $0x0, 0xbc(%rbp)
movq %rbx, %rdi
leaq 0x1370(%rip), %rsi      # 0x5f99
movq %r14, %rdx
leaq 0x14(%rsp), %rcx
xorl %eax, %eax
callq 0x22e0
testl %eax, %eax
jle 0x4e5d
movslq 0x14(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r12, %rdi
callq 0x2470
incl 0x4730(%rip)            # 0x9388
movq %r12, %r15
movq %r12, %rdi
callq 0x22b0
movq %r14, %rdi
movl $0x2d, %esi
callq 0x2140
movq %r14, %rsi
movq %r14, %rdx
testq %rax, %rax
movq %r13, %r12
je 0x4c92
movq %rax, %r14
movb $0x0, (%rax)
movq %r12, %rdi
callq 0x2090
incq %r14
movq %r14, %rdx
movq 0x8(%rsp), %rdi
movq %r12, %rsi
leaq 0x20(%rsp), %rcx
leaq 0x4(%rsp), %r8
leaq 0x28(%rsp), %r9
callq 0x2d7f
movl %eax, %r14d
movq %r15, %r12
movq %r15, %rdi
callq 0x2470
testl %r14d, %r14d
je 0x4d50
incl 0x46c1(%rip)            # 0x938c
movq %r12, %rdi
callq 0x22b0
movl 0x4(%rsp), %eax
cmpl $0x31fff, %eax          # imm = 0x31FFF
leaq 0x60(%rsp), %r14
ja 0x4e0c
movl 0xb8(%rbp), %r14d
movl 0xbc(%rbp), %ecx
movl %r14d, %edx
subl %ecx, %edx
addl $0x200, %eax            # imm = 0x200
cmpl %eax, %edx
jae 0x4d70
addl %r14d, %r14d
movl %r14d, %edx
subl %ecx, %edx
cmpl %eax, %edx
jae 0x4d2c
movl %ecx, %edx
addl %eax, %edx
leal 0x1fff(%rcx,%rax), %r14d
cmovnsl %edx, %r14d
andl $0xffffe000, %r14d      # imm = 0xFFFFE000
addl $0x2000, %r14d          # imm = 0x2000
movq 0xa8(%rbp), %rdi
movslq %r14d, %rsi
callq 0x2310
testq %rax, %rax
je 0x4d63
movq %rax, 0xa8(%rbp)
movl %r14d, 0xb8(%rbp)
jmp 0x4d70
incl 0x463a(%rip)            # 0x9390
movq %r12, %rdi
callq 0x22b0
jmp 0x4e07
cmpl $0x0, 0x450e(%rip)      # 0x9278
jg 0x4e38
movslq 0xbc(%rbp), %rdi
addq 0xa8(%rbp), %rdi
movl 0x4(%rsp), %r8d
leaq 0x1238(%rip), %rsi      # 0x5fc2
leaq 0x60(%rsp), %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x23f0
movl %eax, %r14d
movq 0x28(%rsp), %rdi
movslq 0xbc(%rbp), %rax
addq 0xa8(%rbp), %rax
movslq %r14d, %rsi
addq %rax, %rsi
movl 0x4(%rsp), %edx
movq 0x20(%rsp), %rcx
callq 0x2d75
cmpl 0x4(%rsp), %eax
je 0x4dd1
cmpl $0x0, 0x44a9(%rip)      # 0x9278
jg 0x4e16
addl 0xbc(%rbp), %r14d
movl %r14d, 0xbc(%rbp)
addl 0x4(%rsp), %r14d
movl %r14d, 0xbc(%rbp)
movq 0xa8(%rbp), %rax
movslq %r14d, %rcx
movb $0x0, 0x2(%rax,%rcx)
movw $0xa0d, (%rax,%rcx)     # imm = 0xA0D
addl $0x2, 0xbc(%rbp)
leaq 0x60(%rsp), %r14
addq 0x18(%rsp), %rbx
jmp 0x4c1f
movq 0x41db(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
movl $0x1a, %esi
movl $0x1, %edx
leaq 0x11a2(%rip), %rdi      # 0x5fd3
callq 0x2410
jmp 0x4dd1
movq 0x41b9(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
movl $0x1f, %esi
movl $0x1, %edx
leaq 0x114f(%rip), %rdi      # 0x5fa2
callq 0x2410
jmp 0x4d70
movq 0xa8(%rbp), %rax
movslq 0xbc(%rbp), %rcx
movw $0xa, 0x4(%rax,%rcx)
movl $0xd444e45, (%rax,%rcx) # imm = 0xD444E45
addl $0x5, 0xbc(%rbp)
leaq 0x4401(%rip), %r15      # 0x9288
jmp 0x4eb4
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x31de
testl %eax, %eax
leaq 0x10e4(%rip), %rsi      # 0x5f85
leaq 0x10d6(%rip), %rax      # 0x5f7e
cmovgq %rax, %rsi
movq %rbp, %rdi
callq 0x42cb
leaq 0x4515(%rip), %rbx      # 0x93d0
leaq 0x4436(%rip), %rdi      # 0x92f8
movq %rbp, %rsi
callq 0x390e
movq %rbx, %rdi
callq 0x2470
movl 0x4494(%rip), %edi      # 0x936c
movl $0x1, %edx
leaq 0x110f(%rip), %rsi      # 0x5ff3
callq 0x20f0
cmpq $0x1, %rax
jne 0x4efc
movq %rbx, %rdi
callq 0x22b0
jmp 0x476e
leaq 0x10f7(%rip), %rdi      # 0x5ffa
callq 0x2390
jmp 0x4eef
movq 0x40e7(%rip), %rax      # 0x8ff8
movq (%rax), %rdi
leaq 0x101d(%rip), %rsi      # 0x5f38
movq %r14, %rdx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x2240
jmp 0x4ae4