// File: /workspace/github_cpp_makefile_star2_O3/yangwanyuan[P]HLKVDS/src/GcManager.cc
// Function: hlkvds::GcManager::doMerge(std::multimap<unsigned int, unsigned int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>>&)
uint32_t GcManager::doMerge(std::multimap<uint32_t, uint32_t> &cands_map) {

    bool ret;
    std::vector < uint32_t > free_seg_vec;
    uint32_t last_seg_id = 0;
    bool need_flag = false;
    uint32_t total_free = 0;

    std::list<KVSlice*> slice_list;
    std::list<KVSlice*> recycle_list;

    std::list<KVSlice*>::iterator slice_iter;

    //handle first segment
    SegForSlice *seg_first = new SegForSlice(vol_, idxMgr_);
    for (std::multimap<uint32_t, uint32_t>::iterator iter = cands_map.begin(); iter
            != cands_map.end(); ++iter) {
        uint32_t seg_id = iter->second;
        ret = loadKvList(seg_id, slice_list);
        if (!ret) {
            continue;
        }

        for (slice_iter = slice_list.begin(); slice_iter != slice_list.end();) {
            KVSlice* slice = *slice_iter;
            if (seg_first->TryPut(slice)) {
                seg_first->Put(slice);
                recycle_list.push_back(*slice_iter);
                slice_list.erase(slice_iter++);
            } else {
                need_flag = true;
                break;
            }
        }

        if (need_flag) {
            last_seg_id = seg_id;
            break;
        } else {
            free_seg_vec.push_back(seg_id);
        }
    }

    uint32_t seg_first_id;
    vol_->AllocForGC(seg_first_id);
    seg_first->SetSegId(seg_first_id);
    ret = seg_first->WriteSegToDevice();
    if (!ret) {
        __ERROR("Write First GC segment to device failed, free 0 segments");
        delete seg_first;
        vol_->FreeForFailed(seg_first_id);
        cleanKvList(recycle_list);
        cleanKvList(slice_list);
        return total_free;
    }

    uint32_t free_size = seg_first->GetFreeSize();
    vol_->Use(seg_first_id, free_size);

    seg_first->UpdateToIndex();

    //clean work for first segment
    for (std::vector<uint32_t>::iterator iter = free_seg_vec.begin(); iter
            != free_seg_vec.end(); ++iter) {
        vol_->FreeForGC(*iter);
    }
    delete seg_first;
    cleanKvList(recycle_list);

    total_free = free_seg_vec.size() - 1;

    if (!need_flag) {
        __DEBUG("All fragment segment merge to 1 segment, and free %d segments", total_free);
        return total_free;
    }

    //handle second segment
    SegForSlice *seg_second = new SegForSlice(vol_, idxMgr_);
    uint32_t seg_second_id;
    vol_->AllocForGC(seg_second_id);

    for (slice_iter = slice_list.begin(); slice_iter != slice_list.end(); ++slice_iter) {
        KVSlice* slice = *slice_iter;
        seg_second->Put(slice);
    }

    seg_second->SetSegId(seg_second_id);
    ret = seg_second->WriteSegToDevice();
    if (!ret) {
        __ERROR("Write Second GC segment to device failed, but First Segment is completed, free %d segments", total_free);
        delete seg_second;
        vol_->FreeForFailed(seg_second_id);
        cleanKvList(slice_list);
        return total_free;
    }

    free_size = seg_second->GetFreeSize();
    vol_->Use(seg_second_id, free_size);

    seg_second->UpdateToIndex();
    vol_->FreeForGC(last_seg_id);

    //clean work for second segment
    delete seg_second;
    cleanKvList(slice_list);

    __DEBUG("Multiple fragment segments merge to 2 segment, and free %d segments", total_free);

    return total_free;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r15
movq %rdi, %r14
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
leaq 0x50(%rsp), %rbx
movq %rbx, 0x8(%rbx)
movq %rbx, (%rbx)
movq %rax, 0x10(%rbx)
leaq 0x38(%rsp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
movq %rax, 0x10(%rcx)
movl $0x50, %edi
callq 0x6410
movq %rax, %r12
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq %rax, %rdi
callq 0x1ca02
movq 0x18(%r15), %r13
addq $0x8, %r15
movl $0x0, 0xc(%rsp)
cmpq %r15, %r13
je 0x10376
movq %r15, 0x30(%rsp)
movl 0x24(%r13), %esi
movl %esi, 0x4(%rsp)
movq %r14, %rdi
movq %rbx, %rdx
callq 0x1097a
testb %al, %al
je 0x10362
movq 0x50(%rsp), %r15
cmpq %rbx, %r15
je 0x1032c
movq 0x10(%r15), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0x1be5c
testb %al, %al
je 0x1037b
movq %r12, %rdi
movq %rbp, %rsi
callq 0x1be76
movl $0x18, %edi
callq 0x6410
movq 0x10(%r15), %rcx
movq %rcx, 0x10(%rax)
movq %rax, %rdi
leaq 0x38(%rsp), %rsi
callq 0x6080
incq 0x48(%rsp)
movq (%r15), %rbp
decq 0x60(%rsp)
movq %r15, %rdi
callq 0x6610
movq %r15, %rdi
callq 0x63f0
movq %rbp, %r15
cmpq %rbx, %rbp
jne 0x102c6
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x1034e
movl 0x4(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
movq 0x30(%rsp), %r15
jmp 0x10362
leaq 0x10(%rsp), %rdi
leaq 0x4(%rsp), %rdx
callq 0x10d0a
movq 0x30(%rsp), %r15
movq %r13, %rdi
callq 0x62d0
movq %rax, %r13
cmpq %r15, %rax
jne 0x102a1
movb $0x1, %bpl
jmp 0x10385
movl 0x4(%rsp), %eax
movl %eax, 0xc(%rsp)
xorl %ebp, %ebp
movq (%r14), %rdi
leaq 0x4(%rsp), %rsi
callq 0x20d62
movl 0x4(%rsp), %eax
movl %eax, (%r12)
movq %r12, %rdi
callq 0x1bf42
testb %al, %al
je 0x10512
movl 0x18(%r12), %edx
subl 0x14(%r12), %edx
movq (%r14), %rdi
movl 0x4(%rsp), %esi
callq 0x20d80
movq %r12, %rdi
callq 0x1ca3c
movq 0x10(%rsp), %r15
cmpq 0x18(%rsp), %r15
je 0x103e5
movq (%r14), %rdi
movl (%r15), %esi
callq 0x20d76
addq $0x4, %r15
jmp 0x103cd
movq %r12, %rdi
callq 0x1bd44
movq %r12, %rdi
callq 0x63f0
leaq 0x38(%rsp), %rsi
callq 0x10a10
movq 0x18(%rsp), %r15
subq 0x10(%rsp), %r15
shrq $0x2, %r15
decl %r15d
testb %bpl, %bpl
jne 0x104b8
movl $0x50, %edi
callq 0x6410
movq %rax, %r12
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq %rax, %rdi
callq 0x1ca02
movq (%r14), %rdi
leaq 0x8(%rsp), %rsi
callq 0x20d62
movq %rbx, %r13
movq (%r13), %r13
cmpq %rbx, %r13
je 0x1045c
movq 0x10(%r13), %rsi
movq %r12, %rdi
callq 0x1be76
jmp 0x10445
movl 0x8(%rsp), %eax
movl %eax, (%r12)
movq %r12, %rdi
callq 0x1bf42
testb %al, %al
je 0x105a0
movl 0x18(%r12), %edx
subl 0x14(%r12), %edx
movq (%r14), %rdi
movl 0x8(%rsp), %esi
callq 0x20d80
movq %r12, %rdi
callq 0x1ca3c
movq (%r14), %rdi
movl 0xc(%rsp), %esi
callq 0x20d76
movq %r12, %rdi
callq 0x1bd44
movq %r12, %rdi
callq 0x63f0
leaq 0x50(%rsp), %rsi
callq 0x10a10
movq 0x38(%rsp), %rdi
leaq 0x38(%rsp), %r12
cmpq %r12, %rdi
je 0x104d7
movq (%rdi), %r14
callq 0x63f0
movq %r14, %rdi
cmpq %r12, %r14
jne 0x104c7
movq 0x50(%rsp), %rdi
cmpq %rbx, %rdi
je 0x104f1
movq (%rdi), %r14
callq 0x63f0
movq %r14, %rdi
cmpq %rbx, %r14
jne 0x104e1
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x10500
callq 0x63f0
movl %r15d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x23abf(%rip), %rbp     # 0x33fd8
movq (%rbp), %r13
callq 0x63c0
leaq 0x11d9c(%rip), %rsi     # 0x222c5
leaq 0x12468(%rip), %rcx     # 0x22998
leaq 0x12469(%rip), %r8      # 0x229a0
xorl %r15d, %r15d
movq %r13, %rdi
movq %rax, %rdx
movl $0xb7, %r9d
xorl %eax, %eax
callq 0x6560
movq (%rbp), %rcx
leaq 0x12459(%rip), %rdi     # 0x229b1
movl $0x38, %esi
movl $0x1, %edx
callq 0x6730
movq (%rbp), %rsi
movl $0xa, %edi
callq 0x64c0
movq %r12, %rdi
callq 0x1bd44
movq %r12, %rdi
callq 0x63f0
movq (%r14), %rdi
movl 0x4(%rsp), %esi
callq 0x20d6c
leaq 0x38(%rsp), %rsi
callq 0x10a10
jmp 0x104ae
movq 0x23a31(%rip), %rbp     # 0x33fd8
movq (%rbp), %r13
callq 0x63c0
leaq 0x11d0e(%rip), %rsi     # 0x222c5
leaq 0x123da(%rip), %rcx     # 0x22998
leaq 0x123db(%rip), %r8      # 0x229a0
movq %r13, %rdi
movq %rax, %rdx
movl $0xe0, %r9d
xorl %eax, %eax
callq 0x6560
movq (%rbp), %rdi
leaq 0x12407(%rip), %rsi     # 0x229ea
movl %r15d, %edx
xorl %eax, %eax
callq 0x6560
movq (%rbp), %rsi
movl $0xa, %edi
callq 0x64c0
movq %r12, %rdi
callq 0x1bd44
movq %r12, %rdi
callq 0x63f0
movq (%r14), %rdi
movl 0x8(%rsp), %esi
callq 0x20d6c
jmp 0x104ae
jmp 0x10620
jmp 0x1063b
movq %rax, %r14
movq %r12, %rdi
callq 0x63f0
jmp 0x1063e
jmp 0x1063b
jmp 0x1063b
jmp 0x1063b
jmp 0x1063b
jmp 0x1063b
jmp 0x1063b
jmp 0x1063b
movq %rax, %r14
movq 0x38(%rsp), %rdi
leaq 0x38(%rsp), %r12
cmpq %r12, %rdi
je 0x1065d
movq (%rdi), %r15
callq 0x63f0
movq %r15, %rdi
cmpq %r12, %r15
jne 0x1064d
movq 0x50(%rsp), %rdi
cmpq %rbx, %rdi
je 0x10677
movq (%rdi), %r15
callq 0x63f0
movq %r15, %rdi
cmpq %rbx, %r15
jne 0x10667
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x10686
callq 0x63f0
movq %r14, %rdi
callq 0x6670