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

    uint32_t seg_size = vol_->GetSegmentSize();
    uint64_t data_theory_size = idxMgr_->GetDataTheorySize();
    uint32_t theory_seg_num = data_theory_size / seg_size + 1;

    uint32_t free_seg_num = vol_->GetTotalFreeSegs();
    uint32_t total_seg_num = vol_->GetNumberOfSeg();
    uint32_t used_seg_num = total_seg_num - free_seg_num;
    if (used_seg_num == 0 || theory_seg_num > used_seg_num) {
        return;
    }

    //upper water threshold
    if ( (double)free_seg_num / (double)total_seg_num > CAPACITY_THRESHOLD_TODO_GC) {
        return;
    }

    double waste_rate = 1 - ((double) theory_seg_num / (double) used_seg_num);

    __DEBUG("Begin do Background GC! waste_rate is %f, data_theory_size = %lu", waste_rate, data_theory_size);
    if (waste_rate > options_.gc_upper_level) {
        while (waste_rate > options_.gc_lower_level && used_seg_num > 1) {
            lck_gc.lock();
            std::multimap < uint32_t, uint32_t > cands_map;
            vol_->SortSegsByUtils(cands_map, options_.seg_full_rate);

            //TODO: Maybe some bug here!!!!!
            if (cands_map.empty() || theory_seg_num > used_seg_num) {
                lck_gc.unlock();
                break;
            }
            uint32_t total_free = doMerge(cands_map);
            cands_map.clear();

            data_theory_size = idxMgr_->GetDataTheorySize();
            theory_seg_num = data_theory_size / seg_size + 1;

            used_seg_num = vol_->GetTotalUsedSegs();

            waste_rate = 1 - ((double) theory_seg_num / (double) used_seg_num);
            __DEBUG("done once backgroud GC, total free %u segments, data_theory_size = %lu, theory_seg_num = %u, used_seg_num = %u, seg_size = %u, waste_rate is %f",total_free, data_theory_size, theory_seg_num, used_seg_num, seg_size, waste_rate);
            lck_gc.unlock();
        } __DEBUG("waste_rate lower than the GC_LOWER_LEVEL, end Background GC! waste_rate = %f", waste_rate);
    } __DEBUG("Finsh do Background GC! waste_rate is %f", waste_rate);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
leaq 0x18(%rdi), %rax
movq %rax, (%rsp)
movb $0x0, 0x8(%rsp)
movq (%rdi), %rax
movq 0x8(%rdi), %rdi
movl 0x38(%rax), %r13d
callq 0xf326
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x1df3c
movq (%rbx), %rcx
movl 0x3c(%rcx), %ecx
movl %ecx, %ebp
subl %eax, %ebp
je 0xdc07
incl %r14d
cmpl %ebp, %r14d
ja 0xdc07
movl %eax, %eax
cvtsi2sd %rax, %xmm0
movl %ecx, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
ucomisd 0x11eb8(%rip), %xmm0    # 0x1f998
ja 0xdc07
movl %r14d, %eax
cvtsi2sd %rax, %xmm0
movl %ebp, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x11e9f(%rip), %xmm1    # 0x1f9a0
subsd %xmm0, %xmm1
movq 0x10(%rbx), %rax
movsd %xmm1, 0x10(%rsp)
ucomisd 0x28(%rax), %xmm1
jbe 0xdc07
leaq 0x18(%rsp), %r12
movq 0x10(%rbx), %rax
movsd 0x10(%rsp), %xmm0
ucomisd 0x30(%rax), %xmm0
jbe 0xdc07
cmpl $0x2, %ebp
jb 0xdc07
movq %rsp, %rdi
callq 0xb49c
andl $0x0, 0x20(%rsp)
andq $0x0, 0x28(%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %rax, 0x38(%rsp)
andq $0x0, 0x40(%rsp)
movq (%rbx), %rdi
movq 0x10(%rbx), %rax
movsd 0x20(%rax), %xmm0
movq %r12, %rsi
callq 0x1df50
cmpq $0x0, 0x40(%rsp)
setne %al
cmpl %ebp, %r14d
setbe %r15b
andb %al, %r15b
je 0xdbee
movq %rbx, %rdi
movq %r12, %rsi
callq 0xd6a0
movq %r12, %rdi
callq 0xe0ec
movq 0x8(%rbx), %rdi
callq 0xf326
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x1df46
movl %eax, %ebp
movq %rsp, %rdi
callq 0xb4c6
incl %r14d
movl %r14d, %eax
cvtsi2sd %rax, %xmm0
movl %ebp, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x11dbe(%rip), %xmm1    # 0x1f9a0
subsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
jmp 0xdbf6
movq %rsp, %rdi
callq 0xb4c6
movq %r12, %rdi
callq 0xe080
testb %r15b, %r15b
jne 0xdb1f
movq %rsp, %rdi
callq 0xafd0
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xdc22
jmp 0xdc22
movq %rax, %rbx
jmp 0xdc36
jmp 0xdc29
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0xe080
movq %rsp, %rdi
callq 0xafd0
movq %rbx, %rdi
callq 0x6680