int TsFileIOReader::load_tsfile_meta()

in cpp/src/file/tsfile_io_reader.cc [131:212]


int TsFileIOReader::load_tsfile_meta() {
  const int32_t TSFILE_READ_IO_SIZE = 1024; // TODO make it configurable
  const int32_t TAIL_MAGIC_AND_META_SIZE_SIZE =
      10;                  // magic(6B) + meta_size(4B)
  ASSERT(file_size() > 0); // > 13

  int ret = E_OK;
  uint32_t tsfile_meta_size = 0;
  int32_t read_offset = 0;
  int32_t ret_read_len = 0;

  // Step 1: reader the tsfile_meta_size
  // 1.1 prepare reader buffer
  int32_t alloc_size = UTIL_MIN(TSFILE_READ_IO_SIZE, file_size());
  char *read_buf = (char *) mem_alloc(alloc_size, MOD_TSFILE_READER);
  if (IS_NULL(read_buf)) {
    return E_OOM;
  }
  // 1.2 reader data from file
  read_offset = file_size() - alloc_size;
  ret_read_len = 0;
  if (RET_FAIL(read_file_->read(read_offset, read_buf, alloc_size,
                                ret_read_len))) {
  } else if (ret_read_len != alloc_size) {
    ret = E_FILE_READ_ERR;
    // log_err("do not reader enough data from tsfile, want-size=%d,
    // reader-size=%d, file=%s", alloc_size, ret_read_len,
    // get_file_path().c_str());
  }
  // 1.3 deserialize tsfile_meta_size
  if (IS_SUCC(ret)) {
    // deserialize tsfile_meta_size
    char *size_buf = read_buf + alloc_size - TAIL_MAGIC_AND_META_SIZE_SIZE;
    tsfile_meta_size = SerializationUtil::read_ui32(size_buf);
    ASSERT(tsfile_meta_size > 0 && tsfile_meta_size <= (1ll << 20));
  }

  // Step 2: reader TsFileMeta
  if (IS_SUCC(ret)) {
    // 2.1 prepare enough buffer (use the previous buffer if can).
    char *tsfile_meta_buf = nullptr;
    if (tsfile_meta_size + TAIL_MAGIC_AND_META_SIZE_SIZE >
        (uint32_t) alloc_size) {
      // prepare buffer to re-reader from start of tsfile_meta
      char *old_read_buf = read_buf;
      read_buf = (char *) mem_realloc(read_buf, tsfile_meta_size);
      if (IS_NULL(read_buf)) {
        read_buf = old_read_buf;
        ret = E_OOM;
      } else if (RET_FAIL(read_file_->read(
          file_size() - tsfile_meta_size -
              TAIL_MAGIC_AND_META_SIZE_SIZE,
          read_buf, tsfile_meta_size, ret_read_len))) {
      } else if (tsfile_meta_size != (uint32_t) ret_read_len) {
        ret = E_FILE_READ_ERR;
        // log_err("do not reader enough data from tsfile, want-size=%d,
        // reader-size=%d, file=%s", tsfile_meta_size, ret_read_len,
        // get_file_path().c_str());
      } else {
        tsfile_meta_buf = read_buf;
      }
    } else {
      // the previous buffer has contained the TsFileMeta data
      tsfile_meta_buf = read_buf + alloc_size - tsfile_meta_size -
          TAIL_MAGIC_AND_META_SIZE_SIZE;
      // DEBUG_hex_dump_buf("tsfile_meta_buf=", tsfile_meta_buf,
      // tsfile_meta_size);
    }
    if (IS_SUCC(ret)) {
      ByteStream tsfile_meta_bs;
      tsfile_meta_bs.wrap_from(tsfile_meta_buf, tsfile_meta_size);
      if (RET_FAIL(tsfile_meta_.deserialize_from(tsfile_meta_bs))) {
      }
#if DEBUG_SE
      std::cout << "load tsfile_meta, ret=" << ret
                << ", tsfile_meta_=" << tsfile_meta_ << std::endl;
#endif
    }
  }
  mem_free(read_buf);
  return ret;
}