// File: /workspace/github_cpp_makefile_star2_O3/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, 0x8(%rsp)
movb $0x0, 0x10(%rsp)
movq (%rdi), %rax
movq 0x8(%rdi), %rdi
movl 0x38(%rax), %r13d
callq 0x11fd4
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x20d3a
movq (%rbx), %rcx
movl 0x3c(%rcx), %ecx
movl %ecx, %ebp
subl %eax, %ebp
je 0x1083b
incl %r14d
cmpl %ebp, %r14d
ja 0x1083b
movl %eax, %eax
cvtsi2sd %rax, %xmm0
movl %ecx, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
ucomisd 0x12285(%rip), %xmm0    # 0x22988
ja 0x1083b
movl %r14d, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
movl %ebp, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd %xmm0, %xmm1
movsd 0x12266(%rip), %xmm0    # 0x22990
subsd %xmm1, %xmm0
movq 0x10(%rbx), %rax
ucomisd 0x28(%rax), %xmm0
jbe 0x1083b
cmpl $0x2, %ebp
jb 0x1083b
ucomisd 0x30(%rax), %xmm0
jbe 0x1083b
xorl %r15d, %r15d
leaq 0x18(%rsp), %r12
leaq 0x8(%rsp), %rdi
callq 0xe58e
movl $0x0, 0x20(%rsp)
movq %r15, 0x28(%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %rax, 0x38(%rsp)
movq %r15, 0x40(%rsp)
movq (%rbx), %rdi
movq 0x10(%rbx), %rax
movsd 0x20(%rax), %xmm0
movq %r12, %rsi
callq 0x20d4e
cmpl %ebp, %r14d
ja 0x10827
cmpq $0x0, 0x40(%rsp)
je 0x10827
movq %rbx, %rdi
movq %r12, %rsi
callq 0x10224
movq %r12, %rdi
callq 0x10cdc
movq 0x8(%rbx), %rdi
callq 0x11fd4
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x20d44
movl %eax, %ebp
leaq 0x8(%rsp), %rdi
callq 0xe5ca
movq %r12, %rdi
callq 0x10c92
cmpl $0x2, %ebp
jb 0x1083b
incl %r14d
movl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %ebp, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x1217e(%rip), %xmm1    # 0x22990
subsd %xmm0, %xmm1
movq 0x10(%rbx), %rax
ucomisd 0x30(%rax), %xmm1
ja 0x10759
jmp 0x1083b
leaq 0x8(%rsp), %rdi
callq 0xe5ca
leaq 0x18(%rsp), %rdi
callq 0x10c92
leaq 0x8(%rsp), %rdi
callq 0xe10e
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x10861
jmp 0x1085a
jmp 0x1085a
movq %rax, %rbx
jmp 0x1086e
jmp 0x10861
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x10c92
leaq 0x8(%rsp), %rdi
callq 0xe10e
movq %rbx, %rdi
callq 0x6670