// File: yangwanyuan[P]HLKVDS/src/GcManager.cc
// Function: hlkvds::GcManager::FullGC()
void GcManager::FullGC() {
    std::unique_lock < std::mutex > lck_gc(gcMtx_, std::defer_lock);

    __DEBUG("Begin do Full GC!");
    uint32_t free_before = vol_->GetTotalFreeSegs();
    uint32_t free_after = 0;
    uint32_t used_total = 0;

    uint32_t seg_num = vol_->GetNumberOfSeg();
    uint32_t total_free = 0;
    uint64_t theory_size = 0;
    uint32_t free_seg_num = 0;
    uint32_t used_seg_num = 0;
    uint64_t used_size = 0;

    while (true) {
        lck_gc.lock();
        std::multimap < uint32_t, uint32_t > cands_map;
        vol_->SortSegsByUtils(cands_map, options_.seg_full_rate);
        if (cands_map.size() < SEG_RESERVED_FOR_GC) {
            free_after = vol_->GetTotalFreeSegs();
            used_total = vol_->GetNumberOfSeg() - free_after;
            __DEBUG("End do Full GC! befor have %u segment free, after do full GC now have %u segments free, now used %u segments!", free_before, free_after, used_total);
            break;
        }

        total_free = doMerge(cands_map);
        theory_size = idxMgr_->GetDataTheorySize();
        free_seg_num = vol_->GetTotalFreeSegs();
        used_seg_num = seg_num - free_seg_num;
        used_size = (uint64_t) vol_->GetSegmentSize()
                * (uint64_t) used_seg_num;

        __DEBUG("complete once merge, and this merge free %u segments, theory_size is %lu Byte, used Segments total is %u, occur space is %lu, total seg is %u, free seg is %u", total_free, theory_size, used_seg_num, used_size, seg_num, free_seg_num);
        cands_map.clear();
        lck_gc.unlock();
    } __DEBUG("End do Full GC! total free %u segments", free_after - free_before);
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0xc0(%rsp)
movq 0xc0(%rsp), %rsi
movq %rsi, 0x30(%rsp)
addq $0x18, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x16db0
movq 0x30(%rsp), %rax
movq (%rax), %rdi
callq 0x510f0
movl %eax, 0x38(%rsp)
jmp 0x22ba0
movq 0x30(%rsp), %rax
movl 0x38(%rsp), %ecx
movl %ecx, 0xa8(%rsp)
movl $0x0, 0x98(%rsp)
movl $0x0, 0x94(%rsp)
movq (%rax), %rdi
callq 0x16d50
movl %eax, 0x2c(%rsp)
jmp 0x22bd4
movl 0x2c(%rsp), %eax
movl %eax, 0x90(%rsp)
movl $0x0, 0x8c(%rsp)
movq $0x0, 0x80(%rsp)
movl $0x0, 0x7c(%rsp)
movl $0x0, 0x78(%rsp)
movq $0x0, 0x70(%rsp)
jmp 0x22c11
leaq 0xb0(%rsp), %rdi
callq 0x16dd0
jmp 0x22c20
leaq 0x40(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x234b0
movq 0x30(%rsp), %rax
movq 0x20(%rsp), %rsi
movq (%rax), %rdi
movq 0x10(%rax), %rax
movsd 0x20(%rax), %xmm0
callq 0x51130
jmp 0x22c4c
leaq 0x40(%rsp), %rdi
callq 0x23500
cmpq $0x2, %rax
jae 0x22cec
movq 0x30(%rsp), %rax
movq (%rax), %rdi
callq 0x510f0
movl %eax, 0x1c(%rsp)
jmp 0x22c73
movq 0x30(%rsp), %rax
movl 0x1c(%rsp), %ecx
movl %ecx, 0x98(%rsp)
movq (%rax), %rdi
callq 0x16d50
movl %eax, 0x18(%rsp)
jmp 0x22c91
movl 0x18(%rsp), %eax
subl 0x98(%rsp), %eax
movl %eax, 0x94(%rsp)
movl $0x3, 0x3c(%rsp)
jmp 0x22d9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
jmp 0x22dcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x234f0
jmp 0x22dcf
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x21ee0
movl %eax, 0x14(%rsp)
jmp 0x22d01
movq 0x30(%rsp), %rax
movl 0x14(%rsp), %ecx
movl %ecx, 0x8c(%rsp)
movq 0x8(%rax), %rdi
callq 0x26fe0
movq %rax, 0x8(%rsp)
jmp 0x22d21
movq 0x30(%rsp), %rax
movq 0x8(%rsp), %rcx
movq %rcx, 0x80(%rsp)
movq (%rax), %rdi
callq 0x510f0
movl %eax, 0x4(%rsp)
jmp 0x22d41
movq 0x30(%rsp), %rax
movl 0x4(%rsp), %ecx
movl %ecx, 0x7c(%rsp)
movl 0x90(%rsp), %ecx
movl 0x7c(%rsp), %edx
subl %edx, %ecx
movl %ecx, 0x78(%rsp)
movq (%rax), %rdi
callq 0x234a0
movl %eax, (%rsp)
jmp 0x22d6c
movl (%rsp), %eax
movl %eax, %eax
movl 0x78(%rsp), %ecx
imulq %rcx, %rax
movq %rax, 0x70(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x234e0
leaq 0xb0(%rsp), %rdi
callq 0x16e30
jmp 0x22d97
movl $0x0, 0x3c(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x234f0
movl 0x3c(%rsp), %eax
testl %eax, %eax
je 0x22db5
jmp 0x22db3
jmp 0x22dba
jmp 0x22c0f
leaq 0xb0(%rsp), %rdi
callq 0x15c30
addq $0xc8, %rsp
retq
leaq 0xb0(%rsp), %rdi
callq 0x15c30
movq 0xa0(%rsp), %rdi
callq 0x8820
nopl (%rax)