// File: yangwanyuan[P]HLKVDS/src/MetaStor.cc
// Function: hlkvds::MetaStor::CreateMetaData()
bool MetaStor::CreateMetaData() {

    verifyMetaDevice();

    uint32_t index_ht_size          = 0;
    uint64_t index_region_offset    = 0;
    uint64_t index_region_length    = 0;
    uint32_t sst_total_num          = 0;
    uint64_t sst_region_offset      = 0;
    uint64_t sst_region_length      = 0;
    uint32_t data_store_type        = 0;
    uint32_t entry_count            = 0;
    uint64_t entry_theory_data_size = 0;
    bool grace_close_flag           = false;

    index_ht_size = options_.hashtable_size;

    //Init Block Device
    uint64_t meta_device_capacity = metaDev_->GetDeviceCapacity();

    //Init Superblock region
    uint64_t sb_region_length = SuperBlockManager::SuperBlockSizeOnDevice();

    if (meta_device_capacity < sb_region_length) {
        __ERROR("The capacity of device is too small, can't store sb region");
        return false;
    }

    sbOff_ = 0;
    if (!createSuperBlock()) {
        return false;
    }

    __DEBUG("Init super block region success.");

    //Init Index region
    if (index_ht_size == 0) {
        index_ht_size = (meta_device_capacity / ALIGNED_SIZE) * 2;
    }
    index_ht_size = IndexManager::CalcHashSizeForPower2(index_ht_size);

    index_region_length = IndexManager::CalcIndexSizeOnDevice(index_ht_size);
    __DEBUG("index region size; %ld", index_region_length);

    if (meta_device_capacity < (sb_region_length + index_region_length)) {
        __ERROR("The capacity of device is too small, can't store index region");
        return false;
    }

    index_region_offset = sb_region_length;
    idxOff_ = sb_region_length;
    if (!createIndex(index_ht_size, index_region_length)) {
        return false;
    }
    
    __DEBUG("Init index region success.");

    //Init SST region
    sst_region_offset = sb_region_length + index_region_length;

    sstOff_ = sst_region_offset;
    if (!createDataStor()) {
        __ERROR("Segment region init failed.");
        return false;
    }

    __DEBUG("Init segment region success.");

    //Set zero to device.
    sst_total_num = dataStor_->GetTotalSegNum();
    sst_region_length = dataStor_->GetSSTsLengthOnDisk();
    uint64_t db_meta_region_length = sb_region_length + index_region_length + sst_region_length;

    if ( !zeroDeviceMetaRegion(db_meta_region_length) ) {
        return false;
    }

    //Init reserve region
    data_store_type = options_.datastor_type;
    grace_close_flag = 0;

    //Set SuperBlock
    DBSuperBlock sb(MAGIC_NUMBER, index_ht_size, index_region_offset, index_region_length,
                    sst_total_num, sst_region_offset, sst_region_length, data_store_type,
                    entry_count, entry_theory_data_size, grace_close_flag);
    sbMgr_->SetSuperBlock(sb);

    //Set SuperBlock reserved region
    uint64_t reserved_region_length = SuperBlockManager::ReservedRegionLength();
    char * reserved_content = new char[reserved_region_length];
    if ( !dataStor_->GetSBReservedContent(reserved_content, reserved_region_length) ) {
        delete[] reserved_content;
        return false;
    }
    if ( !sbMgr_->SetReservedContent(reserved_content, reserved_region_length) ) {
        delete[] reserved_content;
        return false;
    }

    delete[] reserved_content;
    return true;
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq 0x158(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x34170
movq 0x88(%rsp), %rax
movl $0x0, 0x154(%rsp)
movq $0x0, 0x148(%rsp)
movq $0x0, 0x140(%rsp)
movl $0x0, 0x13c(%rsp)
movq $0x0, 0x130(%rsp)
movq $0x0, 0x128(%rsp)
movl $0x0, 0x124(%rsp)
movl $0x0, 0x120(%rsp)
movq $0x0, 0x118(%rsp)
movb $0x0, 0x117(%rsp)
movq 0x30(%rax), %rcx
movl 0x40(%rcx), %ecx
movl %ecx, 0x154(%rsp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
movq %rax, 0x108(%rsp)
callq 0x117e0
movq %rax, 0x100(%rsp)
movq 0x108(%rsp), %rax
cmpq 0x100(%rsp), %rax
jae 0x345c4
jmp 0x34543
movq 0x3ca8e(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x80(%rsp)
callq 0x8480
movq 0x80(%rsp), %rdi
movq %rax, %rdx
leaq 0x1df45(%rip), %rsi     # 0x524b1
leaq 0x1ed02(%rip), %rcx     # 0x53275
leaq 0x1ecd3(%rip), %r8      # 0x5324d
movl $0x43, %r9d
movb $0x0, %al
callq 0x86f0
movq 0x3ca4a(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1ecec(%rip), %rsi     # 0x53284
movb $0x0, %al
callq 0x86f0
movq 0x3ca32(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1e815(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
movb $0x0, 0x167(%rsp)
jmp 0x34a69
movq 0x88(%rsp), %rdi
movq $0x0, 0x38(%rdi)
callq 0x34a90
testb $0x1, %al
jne 0x345ea
movb $0x0, 0x167(%rsp)
jmp 0x34a69
cmpl $0x0, 0x154(%rsp)
jne 0x3460a
movq 0x108(%rsp), %rax
shrq $0xc, %rax
shlq %rax
movl %eax, 0x154(%rsp)
movl 0x154(%rsp), %edi
callq 0x272c0
movl %eax, 0x154(%rsp)
movl 0x154(%rsp), %edi
callq 0x27070
movq %rax, 0x140(%rsp)
movq 0x108(%rsp), %rax
movq 0x100(%rsp), %rcx
addq 0x140(%rsp), %rcx
cmpq %rcx, %rax
jae 0x346cb
jmp 0x34650
movq 0x3c981(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x78(%rsp)
callq 0x8480
movq 0x78(%rsp), %rdi
movq %rax, %rdx
leaq 0x1de3e(%rip), %rsi     # 0x524b1
leaq 0x1ebfb(%rip), %rcx     # 0x53275
leaq 0x1ebcc(%rip), %r8      # 0x5324d
movl $0x58, %r9d
movb $0x0, %al
callq 0x86f0
movq 0x3c943(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1ec20(%rip), %rsi     # 0x532bf
movb $0x0, %al
callq 0x86f0
movq 0x3c92b(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1e70e(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
movb $0x0, 0x167(%rsp)
jmp 0x34a69
movq 0x88(%rsp), %rdi
movq 0x100(%rsp), %rax
movq %rax, 0x148(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x40(%rdi)
movl 0x154(%rsp), %esi
movq 0x140(%rsp), %rdx
callq 0x34bb0
testb $0x1, %al
jne 0x34714
movb $0x0, 0x167(%rsp)
jmp 0x34a69
movq 0x88(%rsp), %rdi
movq 0x100(%rsp), %rax
addq 0x140(%rsp), %rax
movq %rax, 0x130(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x48(%rdi)
callq 0x34cf0
testb $0x1, %al
jne 0x347c6
jmp 0x3474b
movq 0x3c886(%rip), %rax     # 0x70fd8
movq (%rax), %rax
movq %rax, 0x70(%rsp)
callq 0x8480
movq 0x70(%rsp), %rdi
movq %rax, %rdx
leaq 0x1dd43(%rip), %rsi     # 0x524b1
leaq 0x1eb00(%rip), %rcx     # 0x53275
leaq 0x1ead1(%rip), %r8      # 0x5324d
movl $0x69, %r9d
movb $0x0, %al
callq 0x86f0
movq 0x3c848(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1eb63(%rip), %rsi     # 0x532fd
movb $0x0, %al
callq 0x86f0
movq 0x3c830(%rip), %rax     # 0x70fd8
movq (%rax), %rdi
leaq 0x1e613(%rip), %rsi     # 0x52dc5
movb $0x0, %al
callq 0x86f0
movb $0x0, 0x167(%rsp)
jmp 0x34a69
movq 0x88(%rsp), %rax
movq 0x28(%rax), %rdi
movq (%rdi), %rax
callq *0x90(%rax)
movl %eax, %ecx
movq 0x88(%rsp), %rax
movl %ecx, 0x13c(%rsp)
movq 0x28(%rax), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
movq 0x88(%rsp), %rdi
movq %rax, 0x128(%rsp)
movq 0x100(%rsp), %rax
addq 0x140(%rsp), %rax
addq 0x128(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rsi
callq 0x34eb0
testb $0x1, %al
jne 0x34847
movb $0x0, 0x167(%rsp)
jmp 0x34a69
movq 0x88(%rsp), %rax
movq 0x30(%rax), %rax
movl 0x3c(%rax), %eax
movl %eax, 0x124(%rsp)
movb $0x0, 0x117(%rsp)
movl 0x154(%rsp), %edx
movq 0x148(%rsp), %rcx
movq 0x140(%rsp), %r8
movl 0x13c(%rsp), %r9d
movq 0x130(%rsp), %rsi
movq 0x128(%rsp), %rdi
movl 0x124(%rsp), %r10d
movl 0x120(%rsp), %r11d
movq 0x118(%rsp), %rbx
movzbl 0x117(%rsp), %ebp
andl $0x1, %ebp
movq %rsp, %rax
movl %ebp, 0x28(%rax)
movq %rbx, 0x20(%rax)
movl %r11d, 0x18(%rax)
movl %r10d, 0x10(%rax)
movq %rdi, 0x8(%rax)
movq %rsi, (%rax)
leaq 0xbb(%rsp), %rdi
movq %rdi, 0x68(%rsp)
movl $0xffff0001, %esi       # imm = 0xFFFF0001
callq 0x361a0
movq 0x88(%rsp), %rax
movq 0x68(%rsp), %rsi
movq 0x18(%rax), %rdi
callq 0x495d0
jmp 0x348ff
callq 0x116c0
movq %rax, 0x60(%rsp)
jmp 0x3490b
movq 0x60(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x8040
movq %rax, 0x58(%rsp)
jmp 0x3492c
movq 0x88(%rsp), %rax
movq 0x58(%rsp), %rcx
movq %rcx, 0x98(%rsp)
movq 0x28(%rax), %rdi
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rdx
movq (%rdi), %rax
movq 0x60(%rax), %rax
callq *%rax
movb %al, 0x57(%rsp)
jmp 0x34964
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x349c9
jmp 0x3496e
movq 0x98(%rsp), %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0x3498b
movq 0x48(%rsp), %rdi
callq 0x8610
movb $0x0, 0x167(%rsp)
movl $0x1, 0x94(%rsp)
jmp 0x34a5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb0(%rsp)
movl %eax, 0xac(%rsp)
leaq 0xbb(%rsp), %rdi
callq 0x36240
jmp 0x34a7c
movq 0x88(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rdx
callq 0x497c0
movb %al, 0x47(%rsp)
jmp 0x349f0
movb 0x47(%rsp), %al
testb $0x1, %al
jne 0x34a2c
jmp 0x349fa
movq 0x98(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, %rax
je 0x34a17
movq 0x38(%rsp), %rdi
callq 0x8610
movb $0x0, 0x167(%rsp)
movl $0x1, 0x94(%rsp)
jmp 0x34a5c
movq 0x98(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x34a49
movq 0x30(%rsp), %rdi
callq 0x8610
movb $0x1, 0x167(%rsp)
movl $0x1, 0x94(%rsp)
leaq 0xbb(%rsp), %rdi
callq 0x36240
movb 0x167(%rsp), %al
andb $0x1, %al
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %rbp
retq
movq 0xb0(%rsp), %rdi
callq 0x8820
nopl (%rax)