// File: yangwanyuan[P]HLKVDS/src/Migrate.cc
// Function: hlkvds::Migrate::doMigrate(unsigned int, unsigned int)
uint32_t Migrate::doMigrate(uint32_t mt_vol_id, uint32_t max_seg_num) {
    Volume *ft_vol = ft_->GetVolume();
    Volume *mt_vol = mt_->GetVolume(mt_vol_id);

    std::multimap < uint32_t, uint32_t > cands_map;
    ft_vol->SortSegsByTS(cands_map, max_seg_num);

    //do merge
    bool ret = false;
    std::vector <uint32_t> free_seg_vec;

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

    SegForMigrate *mig_seg = new SegForMigrate(mt_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;
        }

        if (mig_seg->TryPutList(slice_list)) {
            mig_seg->PutList(slice_list);
            free_seg_vec.push_back(seg_id);
            recycle_list.splice(recycle_list.end(), slice_list);
        }
        else {
            recycle_list.splice(recycle_list.end(), slice_list);
            break;
        }
    }
    
    //Allocate segment id from volume
    uint32_t mig_seg_id;
    if (!mt_vol->Alloc(mig_seg_id)) {
        __WARN("The Medium Tier Volume[%d] is Full, can not allocate segment", mig_seg_id);
        delete mig_seg;
        cleanKvList(recycle_list);
        return 0;
    }
    mig_seg->SetSegId(mig_seg_id);

    //Write to volume device
    ret = mig_seg->WriteSegToDevice();
    if (!ret) {
        __ERROR("Write First GC segment to device failed, free 0 segments");
        delete mig_seg;
        mt_vol->FreeForFailed(mig_seg_id);
        cleanKvList(recycle_list);
        return 0;
    }

    uint32_t free_size = mig_seg->GetFreeSize();
    mt_vol->Use(mig_seg_id, free_size);

    mig_seg->UpdateToIndex();


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

    uint32_t total_free = free_seg_vec.size();

    cands_map.clear();
    __DEBUG("Once doMigrate total free %d segments in Fast Tier!", total_free);
    return total_free;
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x168(%rsp)
movl %esi, 0x164(%rsp)
movl %edx, 0x160(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x50(%rsp)
movq (%rax), %rdi
callq 0x37250
movq %rax, %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x158(%rsp)
movq 0x8(%rax), %rdi
movl 0x164(%rsp), %esi
callq 0x4e810
movq %rax, 0x150(%rsp)
leaq 0x120(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x234b0
movq 0x58(%rsp), %rsi
movq 0x158(%rsp), %rdi
movl 0x160(%rsp), %edx
callq 0x51160
jmp 0x364d7
movb $0x0, 0x113(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x23510
leaq 0xe0(%rsp), %rdi
callq 0x23520
leaq 0xc8(%rsp), %rdi
callq 0x23520
movl $0x50, %edi
callq 0x84f0
movq %rax, 0x48(%rsp)
jmp 0x36517
movq 0x48(%rsp), %rdi
movq 0x50(%rsp), %rax
movq 0x150(%rsp), %rsi
movq 0x10(%rax), %rdx
callq 0x43410
jmp 0x36534
movq 0x48(%rsp), %rax
movq %rax, 0xc0(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x23550
movq %rax, 0xb8(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x235a0
movq %rax, 0xb0(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x23580
testb $0x1, %al
jne 0x36589
jmp 0x36729
leaq 0xb8(%rsp), %rdi
callq 0x235d0
movq 0x50(%rsp), %rdi
movl 0x4(%rax), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %esi
leaq 0xe0(%rsp), %rdx
callq 0x36b70
movb %al, 0x47(%rsp)
jmp 0x365bf
movb 0x47(%rsp), %al
andb $0x1, %al
movb %al, 0x113(%rsp)
testb $0x1, 0x113(%rsp)
jne 0x36630
jmp 0x36717
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x36ac9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x36aa2
movq 0x48(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
callq 0x84b0
jmp 0x36aa2
movq 0xc0(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x41a40
movb %al, 0x46(%rsp)
jmp 0x3664b
movb 0x46(%rsp), %al
testb $0x1, %al
jne 0x36655
jmp 0x366cc
movq 0xc0(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x41b20
jmp 0x3666c
leaq 0xf8(%rsp), %rdi
leaq 0xac(%rsp), %rsi
callq 0x236a0
jmp 0x36683
leaq 0xc8(%rsp), %rdi
callq 0x16460
movq %rax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x23680
movq 0xa0(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
leaq 0xe0(%rsp), %rdx
callq 0x37270
jmp 0x36715
leaq 0xc8(%rsp), %rdi
callq 0x16460
movq %rax, 0x88(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x23680
movq 0x90(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
leaq 0xe0(%rsp), %rdx
callq 0x37270
jmp 0x36729
jmp 0x36717
leaq 0xb8(%rsp), %rdi
callq 0x23710
jmp 0x36556
movq 0x150(%rsp), %rdi
leaq 0x84(%rsp), %rsi
callq 0x50e40
movb %al, 0x45(%rsp)
jmp 0x36744
movb 0x45(%rsp), %al
testb $0x1, %al
jne 0x36821
jmp 0x36752
jmp 0x36754
movq 0x3a87d(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x38(%rsp)
callq 0x8480
movq 0x38(%rsp), %rdi
movq %rax, %rdx
leaq 0x1c586(%rip), %rsi     # 0x52cfd
leaq 0x1cf8c(%rip), %rcx     # 0x5370a
leaq 0x1cf8f(%rip), %r8      # 0x53714
movl $0x54, %r9d
movb $0x0, %al
callq 0x86f0
movq 0x3a83f(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
movl 0x84(%rsp), %edx
leaq 0x1cf79(%rip), %rsi     # 0x53723
movb $0x0, %al
callq 0x86f0
movq 0x3a820(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1c603(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
jmp 0x367cb
movq 0xc0(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x367f2
movq 0x30(%rsp), %rdi
callq 0x433a0
movq 0x30(%rsp), %rdi
callq 0x84b0
movq 0x50(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x36c90
jmp 0x36806
movl $0x0, 0x174(%rsp)
movl $0x1, 0x80(%rsp)
jmp 0x36a5f
movq 0xc0(%rsp), %rdi
movl 0x84(%rsp), %esi
callq 0x164f0
jmp 0x36837
movq 0xc0(%rsp), %rdi
callq 0x41bb0
movb %al, 0x2f(%rsp)
jmp 0x3684a
movb 0x2f(%rsp), %al
andb $0x1, %al
movb %al, 0x113(%rsp)
testb $0x1, 0x113(%rsp)
jne 0x36943
jmp 0x36867
movq 0x3a76a(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x20(%rsp)
callq 0x8480
movq 0x20(%rsp), %rdi
movq %rax, %rdx
leaq 0x1bc27(%rip), %rsi     # 0x524b1
leaq 0x1ce79(%rip), %rcx     # 0x5370a
leaq 0x1ce7c(%rip), %r8      # 0x53714
movl $0x5e, %r9d
movb $0x0, %al
callq 0x86f0
movq 0x3a72c(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1c2d4(%rip), %rsi     # 0x52b8a
movb $0x0, %al
callq 0x86f0
movq 0x3a714(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1c4f7(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
jmp 0x368d7
movq 0xc0(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x368fe
movq 0x18(%rsp), %rdi
callq 0x433a0
movq 0x18(%rsp), %rdi
callq 0x84b0
movq 0x150(%rsp), %rdi
movl 0x84(%rsp), %esi
callq 0x511c0
jmp 0x36914
movq 0x50(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x36c90
jmp 0x36928
movl $0x0, 0x174(%rsp)
movl $0x1, 0x80(%rsp)
jmp 0x36a5f
movq 0xc0(%rsp), %rdi
callq 0x16540
movl %eax, 0x14(%rsp)
jmp 0x36956
movl 0x14(%rsp), %eax
movl %eax, 0x7c(%rsp)
movq 0x150(%rsp), %rdi
movl 0x84(%rsp), %esi
movl 0x7c(%rsp), %edx
callq 0x51220
jmp 0x36978
movq 0xc0(%rsp), %rdi
callq 0x43450
jmp 0x36987
leaq 0xf8(%rsp), %rdi
callq 0x23740
movq %rax, 0x70(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x237b0
movq %rax, 0x68(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x23770
testb $0x1, %al
jne 0x369c0
jmp 0x369f3
movq 0x158(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x237e0
movq 0x8(%rsp), %rdi
movl (%rax), %esi
callq 0x511f0
jmp 0x369e5
jmp 0x369e7
leaq 0x70(%rsp), %rdi
callq 0x237f0
jmp 0x36999
movq 0xc0(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x36a17
movq (%rsp), %rdi
callq 0x433a0
movq (%rsp), %rdi
callq 0x84b0
movq 0x50(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x36c90
jmp 0x36a2b
leaq 0xf8(%rsp), %rdi
callq 0x23810
movl %eax, 0x64(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x234e0
movl 0x64(%rsp), %eax
movl %eax, 0x174(%rsp)
movl $0x1, 0x80(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x23850
leaq 0xe0(%rsp), %rdi
callq 0x23850
leaq 0xf8(%rsp), %rdi
callq 0x23860
leaq 0x120(%rsp), %rdi
callq 0x234f0
movl 0x174(%rsp), %eax
addq $0x178, %rsp            # imm = 0x178
retq
leaq 0xc8(%rsp), %rdi
callq 0x23850
leaq 0xe0(%rsp), %rdi
callq 0x23850
leaq 0xf8(%rsp), %rdi
callq 0x23860
leaq 0x120(%rsp), %rdi
callq 0x234f0
movq 0x118(%rsp), %rdi
callq 0x8820
nopw %cs:(%rax,%rax)