// File: /workspace/github_cpp_makefile_star2_O1/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 0x11ea0
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x20d8a
movq (%rbx), %rcx
movl 0x3c(%rcx), %ecx
movl %ecx, %ebp
subl %eax, %ebp
je 0x10702
incl %r14d
cmpl %ebp, %r14d
ja 0x10702
movl %eax, %eax
cvtsi2sd %rax, %xmm0
movl %ecx, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
ucomisd 0x123bc(%rip), %xmm0    # 0x22988
ja 0x10702
movl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %ebp, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x1239d(%rip), %xmm1    # 0x22990
subsd %xmm0, %xmm1
movq 0x10(%rbx), %rax
movsd %xmm1, 0x10(%rsp)
ucomisd 0x28(%rax), %xmm1
jbe 0x10702
leaq 0x18(%rsp), %r12
movq 0x10(%rbx), %rax
movsd 0x10(%rsp), %xmm0
ucomisd 0x30(%rax), %xmm0
jbe 0x10702
cmpl $0x2, %ebp
jb 0x10702
movq %rsp, %rdi
callq 0xe40a
movl $0x0, 0x20(%rsp)
xorl %ecx, %ecx
movq %rcx, 0x28(%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %rax, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
movq (%rbx), %rdi
movq 0x10(%rbx), %rax
movsd 0x20(%rax), %xmm0
movq %r12, %rsi
callq 0x20d9e
cmpq $0x0, 0x40(%rsp)
setne %al
cmpl %ebp, %r14d
setbe %r15b
andb %al, %r15b
je 0x106e9
movq %rbx, %rdi
movq %r12, %rsi
callq 0x100a8
movq %r12, %rdi
callq 0x10ba8
movq 0x8(%rbx), %rdi
callq 0x11ea0
xorl %edx, %edx
divq %r13
movq %rax, %r14
movq (%rbx), %rdi
callq 0x20d94
movl %eax, %ebp
movq %rsp, %rdi
callq 0xe446
incl %r14d
movl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %ebp, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x122b3(%rip), %xmm1    # 0x22990
subsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
jmp 0x106f1
movq %rsp, %rdi
callq 0xe446
movq %r12, %rdi
callq 0x10b5e
testb %r15b, %r15b
jne 0x10611
movq %rsp, %rdi
callq 0xdf86
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1071d
jmp 0x1071d
movq %rax, %rbx
jmp 0x10731
jmp 0x10724
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x10b5e
movq %rsp, %rdi
callq 0xdf86
movq %rbx, %rdi
callq 0x6680
nop