// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: ltrimCommand
void ltrimCommand(redisClient *c) {
    robj *o;
    long start, end, llen, j, ltrim, rtrim;
    list *list;
    listNode *ln;

    // 取出索引值 start 和 end
    if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
        (getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;

    // 取出列表对象
    if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL ||
        checkType(c,o,REDIS_LIST)) return;

    // 列表长度
    llen = listTypeLength(o);

    /* convert negative indexes */
    // 将负数索引转换成正数索引
    if (start < 0) start = llen+start;
    if (end < 0) end = llen+end;
    if (start < 0) start = 0;

    /* Invariant: start >= 0, so this test will be true when end < 0.
     * The range is empty when start > end or start >= length. */
    if (start > end || start >= llen) {
        /* Out of range start or start > end result in empty list */
        ltrim = llen;
        rtrim = 0;
    } else {
        if (end >= llen) end = llen-1;
        ltrim = start;
        rtrim = llen-end-1;
    }

    /* Remove list elements to perform the trim */
    // 删除指定列表两端的元素

    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        // 删除左端元素
        o->ptr = ziplistDeleteRange(o->ptr,0,ltrim);
        // 删除右端元素
        o->ptr = ziplistDeleteRange(o->ptr,-rtrim,rtrim);

    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
        list = o->ptr;
        // 删除左端元素
        for (j = 0; j < ltrim; j++) {
            ln = listFirst(list);
            listDelNode(list,ln);
        }
        // 删除右端元素
        for (j = 0; j < rtrim; j++) {
            ln = listLast(list);
            listDelNode(list,ln);
        }

    } else {
        redisPanic("Unknown list encoding");
    }

    // 发送通知
    notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"ltrim",c->argv[1],c->db->id);

    // 如果列表已经为空，那么删除它
    if (listTypeLength(o) == 0) {
        dbDelete(c->db,c->argv[1]);
        notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
    }

    signalModifiedKey(c->db,c->argv[1]);

    server.dirty++;

    addReply(c,shared.ok);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x10(%rax), %rsi
leaq -0x18(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x3b960
cmpl $0x0, %eax
jne 0x49a30
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x18(%rax), %rsi
leaq -0x20(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x3b960
cmpl $0x0, %eax
je 0x49a35
jmp 0x49ce6
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rsi
leaq 0xca704(%rip), %rax     # 0x114150
movq 0x8(%rax), %rdx
callq 0x3c110
movq %rax, -0x10(%rbp)
cmpq $0x0, %rax
je 0x49a76
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x1, %edx
callq 0x3abb0
cmpl $0x0, %eax
je 0x49a7b
jmp 0x49ce6
movq -0x10(%rbp), %rdi
callq 0x480f0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x18(%rbp)
jge 0x49a9b
movq -0x28(%rbp), %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x20(%rbp)
jge 0x49aae
movq -0x28(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
jge 0x49abd
movq $0x0, -0x18(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
jg 0x49ad1
movq -0x18(%rbp), %rax
cmpq -0x28(%rbp), %rax
jl 0x49ae3
movq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
jmp 0x49b11
movq -0x20(%rbp), %rax
cmpq -0x28(%rbp), %rax
jl 0x49af9
movq -0x28(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
subq -0x20(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x5, %eax
jne 0x49b6d
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x38(%rbp), %rax
movl %eax, %edx
xorl %esi, %esi
callq 0x339c0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %eax, %eax
subq -0x40(%rbp), %rax
movl %eax, %esi
movq -0x40(%rbp), %rax
movl %eax, %edx
callq 0x339c0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x49c21
movq -0x10(%rbp), %rax
movl (%rax), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
jne 0x49bfd
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
jge 0x49bc2
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x20170
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x49b92
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x40(%rbp), %rax
jge 0x49bfb
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x20170
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x49bca
jmp 0x49c1f
leaq 0x98f48(%rip), %rdi     # 0xe2b4c
leaq 0x99426(%rip), %rsi     # 0xe3031
movl $0x3a1, %edx            # imm = 0x3A1
callq 0x63d40
movl $0x1, %edi
callq 0x1f3b0
jmp 0x49c21
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rdx
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x30(%rax), %ecx
movl $0x10, %edi
leaq 0x94733(%rip), %rsi     # 0xde377
callq 0x814a0
movq -0x10(%rbp), %rdi
callq 0x480f0
cmpq $0x0, %rax
jne 0x49c99
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rsi
callq 0x3c4f0
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rdx
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x30(%rax), %ecx
movl $0x4, %edi
leaq 0x94871(%rip), %rsi     # 0xde505
callq 0x814a0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rsi
callq 0x3c3d0
leaq 0xc9c3f(%rip), %rax     # 0x1138f8
movq 0x560(%rax), %rcx
addq $0x1, %rcx
leaq 0xc9c2d(%rip), %rax     # 0x1138f8
movq %rcx, 0x560(%rax)
movq -0x8(%rbp), %rdi
leaq 0xca473(%rip), %rax     # 0x114150
movq 0x8(%rax), %rsi
callq 0x35a70
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)