// File: /workspace/github_cpp_makefile_star2_O3/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
movq 0x8(%rdi), %rax
movq 0x30(%rdi), %rcx
movq (%rax), %rax
movq (%rax), %rdi
movq %rdi, 0x10(%rbx)
movl 0x40(%rcx), %ebp
movq (%rdi), %rax
callq *0x30(%rax)
cmpq $0xfff, %rax            # imm = 0xFFF
jbe 0x1651c
movq %rax, %r15
movq $0x0, 0x38(%rbx)
movq %rbx, %rdi
callq 0x1654e
testb %al, %al
je 0x1653b
movq %r15, %rdi
shrq $0xb, %rdi
andl $-0x2, %edi
testl %ebp, %ebp
cmovnel %ebp, %edi
callq 0x12170
movl %eax, %ebp
movl %eax, %edi
callq 0x1203c
leaq 0x1000(%rax), %r13
cmpq %r13, %r15
jb 0x1652f
movq %rax, %r14
movq $0x1000, 0x40(%rbx)     # imm = 0x1000
movq %rbx, %rdi
movl %ebp, %esi
movq %rax, %rdx
callq 0x1659e
testb %al, %al
je 0x1653b
movq %r13, 0x48(%rbx)
movq %rbx, %rdi
callq 0x16602
testb %al, %al
je 0x16536
movq 0x28(%rbx), %rdi
movq (%rdi), %rax
callq *0x90(%rax)
movl %eax, %r15d
movq 0x28(%rbx), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
movq %rax, %r12
leaq (%rax,%r13), %rsi
movq %rbx, %rdi
callq 0x1667c
testb %al, %al
je 0x1653b
movq 0x30(%rbx), %rax
movl 0x3c(%rax), %eax
leaq 0x8(%rsp), %rsi
movl $0xffff0001, (%rsi)     # imm = 0xFFFF0001
movl %ebp, 0x4(%rsi)
movq $0x1000, 0x8(%rsi)      # imm = 0x1000
movq %r14, 0x10(%rsi)
movl %r15d, 0x18(%rsi)
movq %r13, 0x1c(%rsi)
movq %r12, 0x24(%rsi)
movl %eax, 0x2c(%rsi)
movl $0x0, 0x30(%rsi)
movq $0x0, 0x34(%rsi)
movb $0x0, 0x3c(%rsi)
movq 0x18(%rbx), %rdi
callq 0x1e01a
movl $0xfc3, %edi            # imm = 0xFC3
callq 0x6040
movq %rax, %r14
movq 0x28(%rbx), %rdi
movq (%rdi), %rax
movl $0xfc3, %edx            # imm = 0xFC3
movq %r14, %rsi
callq *0x60(%rax)
testb %al, %al
je 0x16523
movq 0x18(%rbx), %rdi
movl $0xfc3, %edx            # imm = 0xFC3
movq %r14, %rsi
callq 0x1e10e
movl %eax, %ebx
jmp 0x16525
callq 0x7bc8
jmp 0x1653b
xorl %ebx, %ebx
movq %r14, %rdi
callq 0x64d0
jmp 0x1653d
callq 0x7b68
jmp 0x1653b
callq 0x7b08
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq