// File: /workspace/github_c_makefile_star2_O3/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 0x4c72(%rip), %r15      # 0x9290
leaq 0x4d8b(%rip), %r12      # 0x93b0
leaq 0x4dac(%rip), %rbx      # 0x93d8
leaq 0x60(%rsp), %r14
leaq 0x40(%rsp), %r13
movq %r15, %rdi
callq 0x3909
movq %rax, %rbp
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x2170
movslq 0x4c30(%rip), %rcx      # 0x9284
testq %rcx, %rcx
jle 0x46de
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 0x46de
movq %rbp, %rdi
leaq 0x1744(%rip), %rsi      # 0x5e02
callq 0x41b3
movq %r12, %rdi
callq 0x2470
incl 0x4cd7(%rip)            # 0x93a8
movq %r12, %rdi
callq 0x22b0
jmp 0x4ae3
movq 0xc8(%rbp), %rbx
movq %rbx, %rdi
leaq 0x1728(%rip), %rsi      # 0x5e17
callq 0x2220
testl %eax, %eax
je 0x47ca
movq %rbx, %rdi
leaq 0x1805(%rip), %rsi      # 0x5f0b
callq 0x2220
testl %eax, %eax
je 0x49da
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x17fd(%rip), %rsi      # 0x5f1f
callq 0x2070
testl %eax, %eax
je 0x4947
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x17df(%rip), %rsi      # 0x5f1d
callq 0x2070
testl %eax, %eax
je 0x4947
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x1839(%rip), %rsi      # 0x5f93
callq 0x2070
testl %eax, %eax
je 0x4a13
movl $0x6, %edx
movq %rbx, %rdi
leaq 0x1825(%rip), %rsi      # 0x5f9b
callq 0x2070
testl %eax, %eax
je 0x4a5b
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x1821(%rip), %rsi      # 0x5fb3
callq 0x2070
testl %eax, %eax
je 0x4a7a
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x180a(%rip), %rsi      # 0x5fb8
callq 0x2070
testl %eax, %eax
je 0x4b32
movq %rbp, %rdi
leaq 0x1853(%rip), %rsi      # 0x6018
jmp 0x4ad7
callq 0x2100
movl %eax, %r14d
movq %r15, %rdi
callq 0x39dd
movl %eax, %ebx
movq %r12, %rdi
callq 0x2470
leaq 0x60(%rsp), %rdi
leaq 0x162d(%rip), %rsi      # 0x5e1d
movl %r14d, %edx
xorl %eax, %eax
callq 0x23f0
cltq
leaq (%rsp,%rax), %r14
addq $0x60, %r14
movq 0x4b95(%rip), %rdx      # 0x93a0
movq %r14, %rdi
leaq 0x1616(%rip), %rsi      # 0x5e2b
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4b60(%rip), %edx      # 0x9388
decl %edx
movq %r15, %rdi
leaq 0x160a(%rip), %rsi      # 0x5e3e
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x4b45(%rip), %edx      # 0x938c
movq %r14, %rdi
leaq 0x1608(%rip), %rsi      # 0x5e59
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4b2c(%rip), %edx      # 0x9390
movq %r15, %rdi
leaq 0x160b(%rip), %rsi      # 0x5e79
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x4b13(%rip), %edx      # 0x9394
movq %r14, %rdi
leaq 0x1600(%rip), %rsi      # 0x5e8b
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4afa(%rip), %edx      # 0x9398
movq %r15, %rdi
leaq 0x15f6(%rip), %rsi      # 0x5e9e
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
movl 0x49c1(%rip), %edx      # 0x927c
movq %r14, %rdi
leaq 0x15ee(%rip), %rsi      # 0x5eb3
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r15
addq %r14, %r15
movl 0x4ad0(%rip), %edx      # 0x93a8
movq %r15, %rdi
leaq 0x15e3(%rip), %rsi      # 0x5ec5
xorl %eax, %eax
callq 0x23f0
movslq %eax, %r14
addq %r15, %r14
leaq 0x499a(%rip), %r15      # 0x9290
movq %r14, %rdi
leaq 0x15d8(%rip), %rsi      # 0x5ed8
movl %ebx, %edx
xorl %eax, %eax
callq 0x23f0
movslq %eax, %rbx
addq %r14, %rbx
leaq 0x60(%rsp), %r14
movl 0x4a92(%rip), %edx      # 0x93ac
movq %rbx, %rdi
leaq 0x15cf(%rip), %rsi      # 0x5ef3
xorl %eax, %eax
callq 0x23f0
cltq
movl $0x444e45, (%rax,%rbx)  # imm = 0x444E45
movq %r12, %rdi
callq 0x22b0
movq %rbp, %rdi
movq %r14, %rsi
jmp 0x4ad7
movq %rbx, %rdi
leaq 0x15d4(%rip), %rsi      # 0x5f25
movq %r14, %rdx
xorl %eax, %eax
callq 0x22e0
leaq 0x15ce(%rip), %rsi      # 0x5f30
cmpl $0x1, %eax
jne 0x4ad4
cmpb $0x0, 0x60(%rsp)
leaq 0x15b9(%rip), %rsi      # 0x5f30
je 0x4ad4
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x302e
leaq 0x15c4(%rip), %rsi      # 0x5f55
testl %eax, %eax
je 0x4ad4
movl %eax, %ebx
cmpl $0x0, 0x48de(%rip)      # 0x9280
jg 0x4daa
leaq 0x15cb(%rip), %rsi      # 0x5f7a
cmpl $-0x1, %ebx
jne 0x4ad4
movq %r12, %rdi
callq 0x2470
incl 0x49e6(%rip)            # 0x93ac
movq %r12, %rdi
callq 0x22b0
leaq 0x15a5(%rip), %rsi      # 0x5f7a
jmp 0x4ad4
movq %r12, %rdi
callq 0x2470
xorl %eax, %eax
movq %rax, 0x49a5(%rip)      # 0x9390
movl $0x0, 0x49a3(%rip)      # 0x9398
movq %rax, 0x49ac(%rip)      # 0x93a8
movq %r12, %rdi
callq 0x22b0
movq %rbp, %rdi
leaq 0x1509(%rip), %rsi      # 0x5f17
jmp 0x4ad7
movq %rbx, %rdi
leaq 0x1508(%rip), %rsi      # 0x5f25
movq %r14, %rdx
xorl %eax, %eax
callq 0x22e0
leaq 0x1502(%rip), %rsi      # 0x5f30
cmpl $0x1, %eax
jne 0x4ad4
cmpb $0x0, 0x60(%rsp)
leaq 0x14ed(%rip), %rsi      # 0x5f30
je 0x4ad4
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x2f36
jmp 0x498a
leaq 0x6(%rbx), %rsi
addq $0x7, %rbx
xorl %edx, %edx
movzbl -0x1(%rbx), %eax
testl %eax, %eax
je 0x4ab4
cmpl $0x20, %eax
je 0x4a91
incq %rbx
incq %rdx
jmp 0x4a65
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0x3292
jmp 0x493c
movq %r14, %rdi
callq 0x2050
movq %rbx, %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x23c0
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movl %eax, %edx
jmp 0x4abb
movq 0x8(%rsp), %rdi
xorl %edx, %edx
callq 0x3183
testl %eax, %eax
leaq 0x14e0(%rip), %rsi      # 0x5fa9
leaq 0x14d2(%rip), %rax      # 0x5fa2
cmovgq %rax, %rsi
movq %rbp, %rdi
callq 0x41b3
leaq 0x48f5(%rip), %rbx      # 0x93d8
leaq 0x4816(%rip), %rdi      # 0x9300
movq %rbp, %rsi
callq 0x38aa
movq %rbx, %rdi
callq 0x2470
movl 0x4874(%rip), %edi      # 0x9374
movl $0x1, %edx
leaq 0x150b(%rip), %rsi      # 0x6017
callq 0x20f0
cmpq $0x1, %rax
jne 0x4b24
movq %rbx, %rdi
callq 0x22b0
jmp 0x4636
leaq 0x14f3(%rip), %rdi      # 0x601e
callq 0x2390
jmp 0x4b17
addq $0x4, %rbx
movl $0x0, 0xbc(%rbp)
movq %rbx, %rdi
leaq 0x1473(%rip), %rsi      # 0x5fbd
movq %r14, %rdx
leaq 0x14(%rsp), %rcx
xorl %eax, %eax
callq 0x22e0
testl %eax, %eax
jle 0x4d7b
movslq 0x14(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r12, %rdi
callq 0x2470
incl 0x4817(%rip)            # 0x9390
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 0x4bb3
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 0x2d1d
movl %eax, %r14d
movq %r15, %r12
movq %r15, %rdi
callq 0x2470
testl %r14d, %r14d
je 0x4c71
incl 0x47a8(%rip)            # 0x9394
movq %r12, %rdi
callq 0x22b0
movl 0x4(%rsp), %eax
cmpl $0x31fff, %eax          # imm = 0x31FFF
leaq 0x60(%rsp), %r14
ja 0x4d26
movl 0xb8(%rbp), %r14d
movl 0xbc(%rbp), %ecx
movl %r14d, %edx
subl %ecx, %edx
addl $0x200, %eax            # imm = 0x200
cmpl %eax, %edx
jae 0x4c91
addl %r14d, %r14d
movl %r14d, %edx
subl %ecx, %edx
cmpl %eax, %edx
jae 0x4c4d
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 0x4c84
movq %rax, 0xa8(%rbp)
movl %r14d, 0xb8(%rbp)
jmp 0x4c91
incl 0x4721(%rip)            # 0x9398
movq %r12, %rdi
callq 0x22b0
jmp 0x4d21
cmpl $0x0, 0x45f5(%rip)      # 0x9280
jg 0x4d56
movslq 0xbc(%rbp), %rdi
addq 0xa8(%rbp), %rdi
movl 0x4(%rsp), %r8d
leaq 0x133b(%rip), %rsi      # 0x5fe6
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 0x2d13
movl 0x4(%rsp), %ecx
cmpl %ecx, %eax
je 0x4cf4
cmpl $0x0, 0x458e(%rip)      # 0x9280
jg 0x4d30
addl 0xbc(%rbp), %r14d
addl %ecx, %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 0x4b40
movq 0x42c1(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
movl $0x1a, %esi
movl $0x1, %edx
leaq 0x12ac(%rip), %rdi      # 0x5ff7
callq 0x2410
movl 0x4(%rsp), %ecx
jmp 0x4cf4
movq 0x429b(%rip), %rax      # 0x8ff8
movq (%rax), %rcx
movl $0x1f, %esi
movl $0x1, %edx
leaq 0x1255(%rip), %rdi      # 0x5fc6
callq 0x2410
jmp 0x4c91
movq 0xa8(%rbp), %rax
movslq 0xbc(%rbp), %rcx
movw $0xa, 0x4(%rax,%rcx)
movl $0xd444e45, (%rax,%rcx) # imm = 0xD444E45
addl $0x5, 0xbc(%rbp)
leaq 0x44eb(%rip), %r15      # 0x9290
jmp 0x4adc
movq 0x4247(%rip), %rax      # 0x8ff8
movq (%rax), %rdi
leaq 0x11a1(%rip), %rsi      # 0x5f5c
movq %r14, %rdx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x2240
jmp 0x49a8