// File: /workspace/github_cpp_makefile_star2_O1/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, %r14
movq %rdi, %rbp
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
leaq 0x30(%rsp), %r12
movq %r12, 0x8(%r12)
movq %r12, (%r12)
movq %rax, 0x10(%r12)
leaq 0x48(%rsp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
movq %rax, 0x10(%rcx)
movl $0x50, %edi
callq 0x6420
movq %rax, %r15
movq (%rbp), %rsi
movq 0x8(%rbp), %rdx
movq %rax, %rdi
callq 0x1c9e0
movq 0x18(%r14), %r13
addq $0x8, %r14
cmpq %r14, %r13
je 0x1023a
movl $0x0, 0xc(%rsp)
movl $0x0, 0x4(%rsp)
movq %r14, 0x60(%rsp)
movl 0x24(%r13), %esi
movl %esi, (%rsp)
movq %rbp, %rbx
movq %rbp, %rdi
movq %r12, %rdx
callq 0x10846
movl $0x4, %ebp
testb %al, %al
je 0x10216
movq 0x30(%rsp), %r14
cmpq %r12, %r14
je 0x101cf
movq 0x10(%r14), %rbp
movq %r15, %rdi
movq %rbp, %rsi
callq 0x1be30
movl %eax, %r12d
testb %al, %al
je 0x101bf
movq %r15, %rdi
movq %rbp, %rsi
callq 0x1be4a
movl $0x18, %edi
callq 0x6420
movq 0x10(%r14), %rcx
movq %rcx, 0x10(%rax)
movq %rax, %rdi
leaq 0x48(%rsp), %rsi
callq 0x6080
incq 0x58(%rsp)
movq (%r14), %rbp
decq 0x40(%rsp)
movq %r14, %rdi
callq 0x6620
movq %r14, %rdi
callq 0x6400
movq %rbp, %r14
jmp 0x101c5
movb $0x1, %al
movl %eax, 0x4(%rsp)
testb %r12b, %r12b
leaq 0x30(%rsp), %r12
jne 0x10158
testb $0x1, 0x4(%rsp)
movq 0x60(%rsp), %r14
je 0x101e9
movl $0x2, %ebp
movl (%rsp), %eax
movl %eax, 0xc(%rsp)
jmp 0x10216
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x10207
movl (%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x18(%rsp)
xorl %ebp, %ebp
jmp 0x10216
xorl %ebp, %ebp
leaq 0x10(%rsp), %rdi
movq %rsp, %rdx
callq 0x10bd6
testb $0x3, %bpl
movq %rbx, %rbp
jne 0x10233
movq %r13, %rdi
callq 0x62e0
movq %rax, %r13
cmpq %r14, %rax
jne 0x10131
movl 0xc(%rsp), %r13d
jmp 0x10245
movl $0x0, 0x4(%rsp)
xorl %r13d, %r13d
movq (%rbp), %rdi
movq %rsp, %rsi
callq 0x20db2
movl (%rsp), %eax
movl %eax, (%r15)
movq %r15, %rdi
callq 0x1bf16
testb %al, %al
je 0x103db
movl 0x18(%r15), %edx
subl 0x14(%r15), %edx
movq (%rbp), %rdi
movl (%rsp), %esi
callq 0x20dd0
movq %r15, %rdi
callq 0x1ca1a
movq 0x10(%rsp), %r14
cmpq 0x18(%rsp), %r14
je 0x102a1
movq (%rbp), %rdi
movl (%r14), %esi
callq 0x20dc6
addq $0x4, %r14
jmp 0x10288
movq %r15, %rdi
callq 0x1bd18
movq %r15, %rdi
callq 0x6400
leaq 0x48(%rsp), %rsi
callq 0x108dc
movq 0x18(%rsp), %r12
subq 0x10(%rsp), %r12
shrq $0x2, %r12
decl %r12d
testb $0x1, 0x4(%rsp)
je 0x1037c
movl $0x50, %edi
callq 0x6420
movq %rax, %r15
movq (%rbp), %rsi
movq 0x8(%rbp), %rdx
movq %rax, %rdi
callq 0x1c9e0
movq (%rbp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x20db2
leaq 0x30(%rsp), %rbx
movq (%rbx), %rbx
leaq 0x30(%rsp), %rax
cmpq %rax, %rbx
je 0x10322
movq 0x10(%rbx), %rsi
movq %r15, %rdi
callq 0x1be4a
jmp 0x10307
movl 0x8(%rsp), %eax
movl %eax, (%r15)
movq %r15, %rdi
callq 0x1bf16
testb %al, %al
je 0x10466
movl 0x18(%r15), %edx
subl 0x14(%r15), %edx
movq (%rbp), %rdi
movl 0x8(%rsp), %esi
callq 0x20dd0
movq %r15, %rdi
callq 0x1ca1a
movq (%rbp), %rdi
movl %r13d, %esi
callq 0x20dc6
movq %r15, %rdi
callq 0x1bd18
movq %r15, %rdi
callq 0x6400
leaq 0x30(%rsp), %rsi
callq 0x108dc
movq 0x48(%rsp), %rdi
leaq 0x48(%rsp), %r14
cmpq %r14, %rdi
je 0x1039b
movq (%rdi), %rbx
callq 0x6400
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0x1038b
movq 0x30(%rsp), %rdi
leaq 0x30(%rsp), %r14
cmpq %r14, %rdi
je 0x103ba
movq (%rdi), %rbx
callq 0x6400
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0x103aa
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x103c9
callq 0x6400
movl %r12d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x23bf6(%rip), %rbx     # 0x33fd8
movq (%rbx), %r14
callq 0x63d0
leaq 0x11ed4(%rip), %rsi     # 0x222c5
leaq 0x125a0(%rip), %rcx     # 0x22998
leaq 0x125a1(%rip), %r8      # 0x229a0
xorl %r12d, %r12d
movq %r14, %rdi
movq %rax, %rdx
movl $0xb7, %r9d
xorl %eax, %eax
callq 0x6570
movq (%rbx), %rcx
leaq 0x12592(%rip), %rdi     # 0x229b1
movl $0x38, %esi
movl $0x1, %edx
callq 0x6740
movq (%rbx), %rsi
movl $0xa, %edi
callq 0x64d0
movq %r15, %rdi
callq 0x1bd18
movq %r15, %rdi
callq 0x6400
movq (%rbp), %rdi
movl (%rsp), %esi
callq 0x20dbc
leaq 0x48(%rsp), %rsi
callq 0x108dc
jmp 0x10372
movq 0x23b6b(%rip), %rbx     # 0x33fd8
movq (%rbx), %r14
callq 0x63d0
leaq 0x11e49(%rip), %rsi     # 0x222c5
leaq 0x12515(%rip), %rcx     # 0x22998
leaq 0x12516(%rip), %r8      # 0x229a0
movq %r14, %rdi
movq %rax, %rdx
movl $0xe0, %r9d
xorl %eax, %eax
callq 0x6570
movq (%rbx), %rdi
leaq 0x12543(%rip), %rsi     # 0x229ea
movl %r12d, %edx
xorl %eax, %eax
callq 0x6570
movq (%rbx), %rsi
movl $0xa, %edi
callq 0x64d0
movq %r15, %rdi
callq 0x1bd18
movq %r15, %rdi
callq 0x6400
movq (%rbp), %rdi
movl 0x8(%rsp), %esi
callq 0x20dbc
jmp 0x10372
jmp 0x104e4
jmp 0x104ff
movq %rax, %r14
movq %r15, %rdi
callq 0x6400
jmp 0x10502
jmp 0x104ff
jmp 0x104ff
jmp 0x104ff
jmp 0x104ff
jmp 0x104ff
jmp 0x104ff
jmp 0x104ff
movq %rax, %r14
movq 0x48(%rsp), %rdi
leaq 0x48(%rsp), %r12
cmpq %r12, %rdi
leaq 0x30(%rsp), %r15
je 0x10526
movq (%rdi), %rbx
callq 0x6400
movq %rbx, %rdi
cmpq %r12, %rbx
jne 0x10516
movq 0x30(%rsp), %rdi
cmpq %r15, %rdi
je 0x10540
movq (%rdi), %rbx
callq 0x6400
movq %rbx, %rdi
cmpq %r15, %rbx
jne 0x10530
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x1054f
callq 0x6400
movq %r14, %rdi
callq 0x6680
nop