// File: yangwanyuan[P]HLKVDS/src/IndexManager.cc
// Function: hlkvds::IndexManager::UpdateIndex(hlkvds::KVSlice*, bool)
bool IndexManager::UpdateIndex(KVSlice* slice, bool gc_update) {
    const Kvdb_Digest *digest = &slice->GetDigest();

    HashEntry entry = slice->GetHashEntry();
    const char* data = slice->GetData();

    uint32_t hash_index = KeyDigestHandle::Hash(digest) % htSize_;


    if (gc_update) {
        HashEntry entry_before_gc = slice->GetHashEntryBeforeGC();
        if (!IsSameInMem(entry_before_gc)) {
            dataStor_->ModifyDeathEntry(entry);
            return true;
        }
        else {
            std::lock_guard<std::mutex> l(hashtable_[hash_index].slotMtx_);
            LinkedList<HashEntry> *entry_list = hashtable_[hash_index].entryList_;

            dataStor_->ModifyDeathEntry(entry_before_gc);
            entry_list->put(entry);
            return true;
        }
    }

    std::unique_lock<std::mutex> meta_lck(mtx_, std::defer_lock);
    std::lock_guard<std::mutex> l(hashtable_[hash_index].slotMtx_);
    LinkedList<HashEntry> *entry_list = hashtable_[hash_index].entryList_;

    bool is_exist = entry_list->search(entry);
    if (!is_exist) {
        if (data) {
            //It's insert a new entry operation
            meta_lck.lock();
            if (keyCounter_ == htSize_) {
                __WARN("UpdateIndex Failed, because the hashtable is full!");
                return false;
            }
            meta_lck.unlock();

            entry_list->put(entry);

            meta_lck.lock();
            keyCounter_++;
            dataTheorySize_ += SizeOfDataHeader() + slice->GetDataLen();
            meta_lck.unlock();

            __DEBUG("UpdateIndex request, because this entry is not exist! Now dataTheorySize_ is %ld", dataTheorySize_);
        }
        else {
            //It's a invalid delete operation
            dataStor_->ModifyDeathEntry(entry);
            __DEBUG("Ignore the UpdateIndex request, because this is a delete operation but not exist in Memory");
        }
    }
    else {
        HashEntry *entry_inMem = entry_list->getRef(entry);
        HashEntry::LogicStamp *lts = entry.GetLogicStamp();
        HashEntry::LogicStamp *lts_inMem = entry_inMem->GetLogicStamp();

        if ( *lts < *lts_inMem) {
            dataStor_->ModifyDeathEntry(entry);
            __DEBUG("Ignore the UpdateIndex request, because request is expired!");
        }
        else {
            //this operation is need to do
            dataStor_->ModifyDeathEntry(*entry_inMem);

            uint16_t data_size = entry.GetDataSize() ;
            uint16_t data_inMem_size = entry_inMem->GetDataSize();

            meta_lck.lock();
            if (data_size == 0) {
                dataTheorySize_ -= (uint64_t)(SizeOfDataHeader() + data_inMem_size);
            }
            else {
                dataTheorySize_ += ( data_size > data_inMem_size? 
                        ((uint64_t)(data_size - data_inMem_size)) : 
                        -((uint64_t)(data_inMem_size - data_size)) );
            }
            meta_lck.unlock();

            entry_list->put(entry);

            __DEBUG("UpdateIndex request, because request is new than in memory!Now dataTheorySize_ is %ld", dataTheorySize_);
        }
        return true;
    }

    __DEBUG("Update Index: key:%s, data_len:%u, seg_id:%u, data_offset:%u",
            slice->GetKeyStr().c_str(), slice->GetDataLen(),
            slice->GetSegId(), slice->GetHashEntry().GetDataOffsetInSeg());

    return true;
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movb %dl, %al
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
andb $0x1, %al
movb %al, 0x14f(%rsp)
movq 0x158(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x150(%rsp), %rdi
callq 0x16d90
movq %rax, 0x140(%rsp)
movq 0x150(%rsp), %rdi
callq 0x116b0
movq %rax, %rsi
leaq 0x128(%rsp), %rdi
callq 0x252e0
movq 0x150(%rsp), %rdi
callq 0x23a40
movq %rax, 0x70(%rsp)
jmp 0x25f35
movq 0x70(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x140(%rsp), %rdi
callq 0x2a0b0
movl %eax, 0x64(%rsp)
jmp 0x25f55
movq 0x68(%rsp), %rcx
movl 0x64(%rsp), %eax
xorl %edx, %edx
divl 0x8(%rcx)
movl %edx, 0x110(%rsp)
testb $0x1, 0x14f(%rsp)
je 0x26113
movq 0x150(%rsp), %rdi
callq 0x27b70
movq %rax, 0x58(%rsp)
jmp 0x25f8c
movq 0x58(%rsp), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x252e0
jmp 0x25fa0
movq 0x68(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x26610
movb %al, 0x57(%rsp)
jmp 0x25fb8
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x2602b
jmp 0x25fc2
movq 0x68(%rsp), %rax
movq 0x30(%rax), %rdi
movq (%rdi), %rax
movq 0xa0(%rax), %rax
leaq 0x128(%rsp), %rsi
callq *%rax
jmp 0x25fe1
movb $0x1, 0x167(%rsp)
movl $0x1, 0xf4(%rsp)
jmp 0x260ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x265e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x26101
movq 0x68(%rsp), %rax
movq (%rax), %rax
movl 0x110(%rsp), %ecx
leaq (%rcx,%rcx,2), %rcx
shlq $0x4, %rcx
leaq 0x8(%rax,%rcx), %rsi
leaq 0xe8(%rsp), %rdi
callq 0xb5f0
jmp 0x26056
movq 0x68(%rsp), %rax
movq (%rax), %rcx
movl 0x110(%rsp), %edx
leaq (%rdx,%rdx,2), %rdx
shlq $0x4, %rdx
movq (%rcx,%rdx), %rcx
movq %rcx, 0xe0(%rsp)
movq 0x30(%rax), %rdi
movq (%rdi), %rax
movq 0xa0(%rax), %rax
leaq 0xf8(%rsp), %rsi
callq *%rax
jmp 0x26093
movq 0xe0(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x279d0
jmp 0x260aa
movb $0x1, 0x167(%rsp)
movl $0x1, 0xf4(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0xb830
jmp 0x260ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0xb830
jmp 0x26101
leaq 0xf8(%rsp), %rdi
callq 0x253b0
jmp 0x265cb
leaq 0xf8(%rsp), %rdi
callq 0x253b0
jmp 0x265e9
movq 0x68(%rsp), %rsi
addq $0x48, %rsi
leaq 0xd0(%rsp), %rdi
callq 0x16db0
movq 0x68(%rsp), %rax
movq (%rax), %rax
movl 0x110(%rsp), %ecx
leaq (%rcx,%rcx,2), %rcx
shlq $0x4, %rcx
leaq 0x8(%rax,%rcx), %rsi
leaq 0xc0(%rsp), %rdi
callq 0xb5f0
jmp 0x26154
movq 0x68(%rsp), %rax
movq (%rax), %rax
movl 0x110(%rsp), %ecx
leaq (%rcx,%rcx,2), %rcx
shlq $0x4, %rcx
movq (%rax,%rcx), %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x27b80
movb %al, 0x56(%rsp)
jmp 0x26192
movb 0x56(%rsp), %al
andb $0x1, %al
movb %al, 0xb7(%rsp)
testb $0x1, 0xb7(%rsp)
jne 0x26351
cmpq $0x0, 0x120(%rsp)
je 0x2632b
leaq 0xd0(%rsp), %rdi
callq 0x16dd0
jmp 0x261cb
movq 0x68(%rsp), %rcx
movl 0x18(%rcx), %eax
cmpl 0x8(%rcx), %eax
jne 0x26298
jmp 0x261de
movq 0x4adf3(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x48(%rsp)
callq 0x8480
movq 0x48(%rsp), %rdi
movq %rax, %rdx
leaq 0x2cafc(%rip), %rsi     # 0x52cfd
leaq 0x2cb15(%rip), %rcx     # 0x52d1d
leaq 0x2ca0f(%rip), %r8      # 0x52c1e
movl $0x118, %r9d            # imm = 0x118
movb $0x0, %al
callq 0x86f0
movq 0x4adb5(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x2cafc(%rip), %rsi     # 0x52d29
movb $0x0, %al
callq 0x86f0
movq 0x4ad9d(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x2cb80(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
jmp 0x2624e
movb $0x0, 0x167(%rsp)
movl $0x1, 0xf4(%rsp)
jmp 0x26593
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x265bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x265af
leaq 0xd0(%rsp), %rdi
callq 0x16e30
jmp 0x262a7
movq 0xb8(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x279d0
jmp 0x262be
leaq 0xd0(%rsp), %rdi
callq 0x16dd0
jmp 0x262cd
movq 0x68(%rsp), %rax
movl 0x18(%rax), %ecx
incl %ecx
movl %ecx, 0x18(%rax)
callq 0x238d0
movq %rax, 0x40(%rsp)
jmp 0x262e6
movq 0x150(%rsp), %rdi
callq 0x163a0
movw %ax, 0x3e(%rsp)
jmp 0x262fa
movq 0x68(%rsp), %rax
movq 0x40(%rsp), %rdx
movw 0x3e(%rsp), %cx
movzwl %cx, %ecx
addq %rcx, %rdx
movq 0x20(%rax), %rcx
addq %rdx, %rcx
movq %rcx, 0x20(%rax)
leaq 0xd0(%rsp), %rdi
callq 0x16e30
jmp 0x26329
jmp 0x2634c
movq 0x68(%rsp), %rax
movq 0x30(%rax), %rdi
movq (%rdi), %rax
movq 0xa0(%rax), %rax
leaq 0x128(%rsp), %rsi
callq *%rax
jmp 0x2634a
jmp 0x2634c
jmp 0x26580
movq 0xb8(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x252e0
jmp 0x26375
movq 0x30(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x27be0
movq %rax, 0x28(%rsp)
jmp 0x2638e
leaq 0x90(%rsp), %rdi
callq 0x253b0
movq 0x28(%rsp), %rax
movq %rax, 0xa8(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x27c50
movq %rax, 0x20(%rsp)
jmp 0x263bc
movq 0x20(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0xa8(%rsp), %rdi
callq 0x27c50
movq %rax, 0x18(%rsp)
jmp 0x263dd
movq 0x18(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x27c60
movb %al, 0x17(%rsp)
jmp 0x26405
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x2640f
jmp 0x26459
movq 0x68(%rsp), %rax
movq 0x30(%rax), %rdi
movq (%rdi), %rax
movq 0xa0(%rax), %rax
leaq 0x128(%rsp), %rsi
callq *%rax
jmp 0x2642e
jmp 0x2656b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x253b0
jmp 0x265af
movq 0x68(%rsp), %rax
movq 0x30(%rax), %rdi
movq 0xa8(%rsp), %rsi
movq (%rdi), %rax
movq 0xa0(%rax), %rax
callq *%rax
jmp 0x26478
leaq 0x128(%rsp), %rdi
callq 0x16580
movw %ax, 0x14(%rsp)
jmp 0x2648c
movw 0x14(%rsp), %ax
movw %ax, 0x7e(%rsp)
movq 0xa8(%rsp), %rdi
callq 0x16580
movw %ax, 0x12(%rsp)
jmp 0x264aa
movw 0x12(%rsp), %ax
movw %ax, 0x7c(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x16dd0
jmp 0x264c3
movzwl 0x7e(%rsp), %eax
cmpl $0x0, %eax
jne 0x264f8
callq 0x238d0
movq %rax, 0x8(%rsp)
jmp 0x264d9
movq 0x68(%rsp), %rax
movq 0x8(%rsp), %rdx
movzwl 0x7c(%rsp), %ecx
addq %rcx, %rdx
movq 0x20(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x20(%rax)
jmp 0x26543
movzwl 0x7e(%rsp), %eax
movzwl 0x7c(%rsp), %ecx
cmpl %ecx, %eax
jle 0x2651a
movzwl 0x7e(%rsp), %eax
movzwl 0x7c(%rsp), %ecx
subl %ecx, %eax
cltq
movq %rax, (%rsp)
jmp 0x26532
movzwl 0x7c(%rsp), %eax
movzwl 0x7e(%rsp), %ecx
subl %ecx, %eax
movslq %eax, %rcx
xorl %eax, %eax
subq %rcx, %rax
movq %rax, (%rsp)
movq 0x68(%rsp), %rax
movq (%rsp), %rcx
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
leaq 0xd0(%rsp), %rdi
callq 0x16e30
jmp 0x26552
movq 0xb8(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x279d0
jmp 0x26569
jmp 0x2656b
movb $0x1, 0x167(%rsp)
movl $0x1, 0xf4(%rsp)
jmp 0x26593
movb $0x1, 0x167(%rsp)
movl $0x1, 0xf4(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0xb830
leaq 0xd0(%rsp), %rdi
callq 0x15c30
jmp 0x265cb
leaq 0xc0(%rsp), %rdi
callq 0xb830
leaq 0xd0(%rsp), %rdi
callq 0x15c30
jmp 0x265e9
leaq 0x128(%rsp), %rdi
callq 0x253b0
movb 0x167(%rsp), %al
andb $0x1, %al
addq $0x168, %rsp            # imm = 0x168
retq
leaq 0x128(%rsp), %rdi
callq 0x253b0
movq 0x118(%rsp), %rdi
callq 0x8820
nopw %cs:(%rax,%rax)