// File: /workspace/github_c_makefile_star2_O2/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, 0x10(%rsp)
callq 0x2340
movq %rax, %rdi
callq 0x22c0
leaq 0x4eb0(%rip), %r12      # 0x9290
leaq 0x4fc9(%rip), %r13      # 0x93b0
leaq 0x4fea(%rip), %r15      # 0x93d8
movq %r12, %rdi
callq 0x3613
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x2170
movslq 0x4e78(%rip), %rcx      # 0x9284
testq %rcx, %rcx
jle 0x4481
movq 0x38(%rsp), %rdx
subq 0xd8(%rbx), %rdx
leaq 0xf4240(%rdx), %rax
testq %rdx, %rdx
cmovnsq %rdx, %rax
movq 0x30(%rsp), %rsi
subq 0xd0(%rbx), %rsi
sarq $0x3f, %rdx
addq %rsi, %rdx
imulq $0x3e8, %rdx, %rsi      # imm = 0x3E8
cqto
movl $0x3e8, %edi            # imm = 0x3E8
idivq %rdi
addq %rsi, %rax
cmpq %rcx, %rax
jle 0x4481
movq %rbx, %rdi
leaq 0x19a1(%rip), %rsi      # 0x5e02
callq 0x3f10
movq %r13, %rdi
callq 0x2460
incl 0x4f34(%rip)            # 0x93a8
movq %r13, %rdi
callq 0x22a0
jmp 0x4820
movq 0xc8(%rbx), %r15
movq %r15, %rdi
leaq 0x1985(%rip), %rsi      # 0x5e17
callq 0x2210
testl %eax, %eax
je 0x4565
movq %r15, %rdi
leaq 0x1a62(%rip), %rsi      # 0x5f0b
callq 0x2210
testl %eax, %eax
je 0x478e
movq %r15, %rdi
leaq 0x1a5f(%rip), %rsi      # 0x5f1f
pushq $0x5
popq %rdx
callq 0x2070
testl %eax, %eax
je 0x46ee
movq %r15, %rdi
leaq 0x1a43(%rip), %rsi      # 0x5f1d
pushq $0x7
popq %rdx
callq 0x2070
testl %eax, %eax
je 0x46ee
movq %r15, %rdi
leaq 0x1a9f(%rip), %rsi      # 0x5f93
pushq $0x7
popq %rdx
callq 0x2070
testl %eax, %eax
je 0x47cd
movq %r15, %rdi
leaq 0x1a8d(%rip), %rsi      # 0x5f9b
pushq $0x6
popq %rdx
callq 0x2070
testl %eax, %eax
je 0x486d
movq %r15, %rdi
leaq 0x1a8b(%rip), %rsi      # 0x5fb3
pushq $0x4
popq %r14
movq %r14, %rdx
callq 0x2070
testl %eax, %eax
je 0x488d
movq %r15, %rdi
leaq 0x1a72(%rip), %rsi      # 0x5fb8
movq %r14, %rdx
callq 0x2070
testl %eax, %eax
je 0x48fd
movq %rbx, %rdi
leaq 0x1ab8(%rip), %rsi      # 0x6018
jmp 0x47bf
callq 0x2100
movl %eax, %r14d
movq %r12, %rdi
callq 0x36d9
movl %eax, %r15d
movq %r13, %rdi
callq 0x2460
leaq 0x60(%rsp), %r13
movq %r13, %rdi
leaq 0x188e(%rip), %rsi      # 0x5e1d
movl %r14d, %edx
xorl %eax, %eax
callq 0x23e0
cltq
leaq (%rsp,%rax), %r14
addq $0x60, %r14
movq 0x4df6(%rip), %rdx      # 0x93a0
movq %r14, %rdi
leaq 0x1877(%rip), %rsi      # 0x5e2b
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r12
addq %r14, %r12
movl 0x4dc1(%rip), %edx      # 0x9388
decl %edx
movq %r12, %rdi
leaq 0x186b(%rip), %rsi      # 0x5e3e
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r14
addq %r12, %r14
movl 0x4da6(%rip), %edx      # 0x938c
movq %r14, %rdi
leaq 0x1869(%rip), %rsi      # 0x5e59
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r12
addq %r14, %r12
movl 0x4d8d(%rip), %edx      # 0x9390
movq %r12, %rdi
leaq 0x186c(%rip), %rsi      # 0x5e79
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r14
addq %r12, %r14
movl 0x4d74(%rip), %edx      # 0x9394
movq %r14, %rdi
leaq 0x1861(%rip), %rsi      # 0x5e8b
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r12
addq %r14, %r12
movl 0x4d5b(%rip), %edx      # 0x9398
movq %r12, %rdi
leaq 0x1857(%rip), %rsi      # 0x5e9e
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r14
addq %r12, %r14
movl 0x4c22(%rip), %edx      # 0x927c
movq %r14, %rdi
leaq 0x184f(%rip), %rsi      # 0x5eb3
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r12
addq %r14, %r12
movl 0x4d31(%rip), %edx      # 0x93a8
movq %r12, %rdi
leaq 0x1844(%rip), %rsi      # 0x5ec5
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r14
addq %r12, %r14
leaq 0x4bfb(%rip), %r12      # 0x9290
movq %r14, %rdi
leaq 0x1839(%rip), %rsi      # 0x5ed8
movl %r15d, %edx
xorl %eax, %eax
callq 0x23e0
movslq %eax, %r15
addq %r14, %r15
movl 0x4cf7(%rip), %edx      # 0x93ac
movq %r15, %rdi
leaq 0x1834(%rip), %rsi      # 0x5ef3
xorl %eax, %eax
callq 0x23e0
cltq
movl $0x444e45, (%rax,%r15)  # imm = 0x444E45
leaq 0x4cd9(%rip), %rdi      # 0x93b0
callq 0x22a0
movq %rbx, %rdi
movq %r13, %rsi
leaq 0x4cc7(%rip), %r13      # 0x93b0
jmp 0x47bf
movq %r15, %rdi
leaq 0x182d(%rip), %rsi      # 0x5f25
leaq 0x60(%rsp), %rdx
xorl %eax, %eax
callq 0x22d0
leaq 0x1825(%rip), %rsi      # 0x5f30
cmpl $0x1, %eax
leaq 0x4cc3(%rip), %r15      # 0x93d8
jne 0x4818
cmpb $0x0, 0x60(%rsp)
leaq 0x1809(%rip), %rsi      # 0x5f30
je 0x4818
movq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x2d53
leaq 0x1812(%rip), %rsi      # 0x5f55
testl %eax, %eax
je 0x4818
movl %eax, %r14d
cmpl $0x0, 0x4b2b(%rip)      # 0x9280
jg 0x4b6f
leaq 0x1818(%rip), %rsi      # 0x5f7a
cmpl $-0x1, %r14d
jne 0x4818
movq %r13, %rdi
callq 0x2460
incl 0x4c32(%rip)            # 0x93ac
movq %r13, %rdi
callq 0x22a0
leaq 0x17f1(%rip), %rsi      # 0x5f7a
jmp 0x4818
movq %r13, %rdi
callq 0x2460
andq $0x0, 0x4bf2(%rip)      # 0x9390
andl $0x0, 0x4bf3(%rip)      # 0x9398
andq $0x0, 0x4bfb(%rip)      # 0x93a8
movq %r13, %rdi
callq 0x22a0
movq %rbx, %rdi
leaq 0x1758(%rip), %rsi      # 0x5f17
callq 0x3f10
leaq 0x4c0d(%rip), %r15      # 0x93d8
jmp 0x4820
movq %r15, %rdi
leaq 0x174e(%rip), %rsi      # 0x5f25
leaq 0x60(%rsp), %rdx
xorl %eax, %eax
callq 0x22d0
leaq 0x1746(%rip), %rsi      # 0x5f30
cmpl $0x1, %eax
leaq 0x4be4(%rip), %r15      # 0x93d8
jne 0x4818
cmpb $0x0, 0x60(%rsp)
leaq 0x172e(%rip), %rsi      # 0x5f30
je 0x4818
movq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x2c65
jmp 0x473c
movq %rbx, %rdi
callq 0x3f10
leaq 0x4ad9(%rip), %rdi      # 0x9300
movq %rbx, %rsi
callq 0x35b7
movq %r15, %rdi
callq 0x2460
movl 0x4b37(%rip), %edi      # 0x9374
leaq 0x17d3(%rip), %rsi      # 0x6017
pushq $0x1
popq %rdx
callq 0x20f0
cmpq $0x1, %rax
jne 0x485f
movq %r15, %rdi
callq 0x22a0
jmp 0x43ee
leaq 0x17b8(%rip), %rdi      # 0x601e
callq 0x2380
jmp 0x4852
leaq 0x6(%r15), %rsi
addq $0x7, %r15
xorl %edx, %edx
movzbl -0x1(%r15), %eax
testl %eax, %eax
je 0x48d5
cmpl $0x20, %eax
je 0x48af
incq %r15
incq %rdx
jmp 0x4877
movq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %r14
movq %r14, %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0x2f8f
movq %rbx, %rdi
movq %r14, %rsi
jmp 0x47bf
leaq 0x60(%rsp), %r14
movq %r14, %rdi
callq 0x2050
movq %r15, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x23b0
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movl %eax, %edx
jmp 0x48dc
movq 0x10(%rsp), %rdi
xorl %edx, %edx
callq 0x2e91
testl %eax, %eax
leaq 0x16bf(%rip), %rsi      # 0x5fa9
leaq 0x16b1(%rip), %rax      # 0x5fa2
cmovgq %rax, %rsi
movq %rbx, %rdi
jmp 0x47bf
addq $0x4, %r15
andl $0x0, 0xbc(%rbx)
leaq 0x60(%rsp), %r13
movq %r15, %rdi
leaq 0x16a6(%rip), %rsi      # 0x5fbd
movq %r13, %rdx
leaq 0x1c(%rsp), %rcx
xorl %eax, %eax
callq 0x22d0
testl %eax, %eax
jle 0x4b32
movslq 0x1c(%rsp), %r12
leaq 0x4a76(%rip), %r14      # 0x93b0
movq %r14, %rdi
callq 0x2460
incl 0x4a48(%rip)            # 0x9390
movq %r14, %rdi
callq 0x22a0
movq %r13, %rdi
pushq $0x2d
popq %rsi
callq 0x2140
movq %r13, %rdx
testq %rax, %rax
leaq 0x40(%rsp), %rbp
je 0x497f
movq %rax, %r14
movb $0x0, (%rax)
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2090
incq %r14
movq %r14, %rdx
addq %r12, %r15
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
leaq 0x20(%rsp), %rcx
leaq 0xc(%rsp), %r8
leaq 0x28(%rsp), %r9
callq 0x2a6f
movl %eax, %r14d
leaq 0x4a08(%rip), %r12      # 0x93b0
movq %r12, %rdi
callq 0x2460
testl %r14d, %r14d
je 0x4b1f
incl 0x49d5(%rip)            # 0x9394
movq %r12, %rdi
callq 0x22a0
movl 0xc(%rsp), %ecx
cmpl $0x31fff, %ecx          # imm = 0x31FFF
leaq 0x60(%rsp), %r13
ja 0x490d
movl 0xb8(%rbx), %r14d
movl 0xbc(%rbx), %eax
movl %r14d, %edx
subl %eax, %edx
addl $0x200, %ecx            # imm = 0x200
cmpl %ecx, %edx
jae 0x4a49
addl %r14d, %r14d
movl %r14d, %edx
subl %eax, %edx
cmpl %ecx, %edx
jae 0x4a18
addl %ecx, %eax
cltd
movl $0x2000, %ecx           # imm = 0x2000
idivl %ecx
movl %eax, %r14d
shll $0xd, %r14d
addl %ecx, %r14d
movq 0xa8(%rbx), %rdi
movslq %r14d, %rsi
callq 0x2300
testq %rax, %rax
je 0x4a3c
movq %rax, 0xa8(%rbx)
movl %r14d, 0xb8(%rbx)
jmp 0x4a49
cmpl $0x0, 0x483d(%rip)      # 0x9280
jg 0x4afe
movslq 0xbc(%rbx), %rdi
addq 0xa8(%rbx), %rdi
movl 0xc(%rsp), %r8d
leaq 0x1583(%rip), %rsi      # 0x5fe6
movq %r13, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x23e0
movl %eax, %r14d
movq 0x28(%rsp), %rdi
movslq 0xbc(%rbx), %rax
addq 0xa8(%rbx), %rax
movslq %r14d, %rsi
addq %rax, %rsi
movl 0xc(%rsp), %edx
movq 0x20(%rsp), %rcx
callq 0x2a65
movl 0xc(%rsp), %ecx
cmpl %ecx, %eax
je 0x4aaa
cmpl $0x0, 0x47d8(%rip)      # 0x9280
jg 0x4adc
addl 0xbc(%rbx), %r14d
addl %ecx, %r14d
movl %r14d, 0xbc(%rbx)
movq 0xa8(%rbx), %rax
movslq %r14d, %rcx
movb $0x0, 0x2(%rax,%rcx)
movw $0xa0d, (%rax,%rcx)     # imm = 0xA0D
addl $0x2, 0xbc(%rbx)
jmp 0x490d
movq 0x4515(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
leaq 0x150a(%rip), %rdi      # 0x5ff7
pushq $0x1a
popq %rsi
pushq $0x1
popq %rdx
callq 0x2400
movl 0xc(%rsp), %ecx
jmp 0x4aaa
movq 0x44f3(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
leaq 0x14b7(%rip), %rdi      # 0x5fc6
pushq $0x1f
popq %rsi
pushq $0x1
popq %rdx
callq 0x2400
jmp 0x4a49
incl 0x4873(%rip)            # 0x9398
movq %r12, %rdi
callq 0x22a0
jmp 0x4908
movq 0xa8(%rbx), %rax
movslq 0xbc(%rbx), %rcx
movw $0xa, 0x4(%rax,%rcx)
movl $0xd444e45, (%rax,%rcx) # imm = 0xD444E45
addl $0x5, 0xbc(%rbx)
leaq 0x4734(%rip), %r12      # 0x9290
leaq 0x4875(%rip), %r15      # 0x93d8
leaq 0x4846(%rip), %r13      # 0x93b0
jmp 0x4820
movq 0x4482(%rip), %rax      # 0x8ff8
movq (%rax), %rdi
leaq 0x13dc(%rip), %rsi      # 0x5f5c
leaq 0x60(%rsp), %rdx
movl %r14d, %ecx
xorl %eax, %eax
callq 0x2230
jmp 0x475b