// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: spopCommand
void spopCommand(redisClient *c) {
    robj *set, *ele, *aux;
    int64_t llele;
    int encoding;

    // 取出集合
    if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
        checkType(c,set,REDIS_SET)) return;

    // 从集合中随机取出一个元素
    encoding = setTypeRandomElement(set,&ele,&llele);

    // 将被取出元素从集合中删除
    if (encoding == REDIS_ENCODING_INTSET) {
        ele = createStringObjectFromLongLong(llele);
        set->ptr = intsetRemove(set->ptr,llele,NULL);
    } else {
        incrRefCount(ele);
        setTypeRemove(set,ele);
    }

    // 发送事件通知
    notifyKeyspaceEvent(REDIS_NOTIFY_SET,"spop",c->argv[1],c->db->id);

    /* Replicate/AOF this command as an SREM operation */
    // 将这个命令当作 SREM 来传播，防止产生有害的随机性，导致数据不一致
    // （不同的服务器随机删除不同的元素）
    aux = createStringObject("SREM",4);
    rewriteClientCommandVector(c,3,aux,c->argv[1],ele);
    decrRefCount(ele);
    decrRefCount(aux);

    // 返回回复
    addReplyBulk(c,ele);

    // 如果集合已经为空，那么从数据库中删除它
    if (setTypeSize(set) == 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++;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rsi
leaq 0xc851d(%rip), %rax     # 0x114150
movq 0x50(%rax), %rdx
callq 0x3c110
movq %rax, -0x10(%rbp)
cmpq $0x0, %rax
je 0x4bc5d
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x2, %edx
callq 0x3abb0
cmpl $0x0, %eax
je 0x4bc62
jmp 0x4bdca
movq -0x10(%rbp), %rdi
leaq -0x18(%rbp), %rsi
leaq -0x28(%rbp), %rdx
callq 0x4b400
movl %eax, -0x2c(%rbp)
cmpl $0x6, -0x2c(%rbp)
jne 0x4bcab
movq -0x28(%rbp), %rdi
callq 0x3a330
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x28(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x678d0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x4bcc1
movq -0x18(%rbp), %rdi
callq 0x3a3f0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x4b020
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 $0x20, %edi
leaq 0x926b8(%rip), %rsi     # 0xde39c
callq 0x814a0
leaq 0x9756b(%rip), %rdi     # 0xe325b
movl $0x4, %esi
callq 0x3a2e0
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %r8
movl $0x3, %esi
movb $0x0, %al
callq 0x38860
movq -0x18(%rbp), %rdi
callq 0x3aaa0
movq -0x20(%rbp), %rdi
callq 0x3aaa0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x36620
movq -0x10(%rbp), %rdi
callq 0x4b4b0
cmpq $0x0, %rax
jne 0x4bd91
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 0x92779(%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 0xc7b47(%rip), %rax     # 0x1138f8
movq 0x560(%rax), %rcx
addq $0x1, %rcx
leaq 0xc7b35(%rip), %rax     # 0x1138f8
movq %rcx, 0x560(%rax)
addq $0x30, %rsp
popq %rbp
retq