当前位置: 首页 > news >正文

2022-09-02 mysql/stonedb-读取Pack数据流程记录

目录

摘要:

逻辑建模:

动态结构-时序图:

加载字符类型的列:

调用堆栈:

核心函数:

Descriptor::LockSourcePacks

VirtualColumn::LockSourcePacks

VCPackGuardian::LockPackrow

RCAttr::LockPackForUse

DataCache::GetOrFetchObject

RCAttr::Fetch

PackStr::PackStr

PackStr::LoadDataFromFile

PackStr::LoadCompressed


摘要:

本文主要记录在查询过程中,数据的获取过程。

涉及从物理层到逻辑层的数据处理。

逻辑建模:

动态结构-时序图:

读取字符串类型的列

静态结构-类图

 

加载字符类型的列:

调用堆栈:

(gdb) bt
#0  Tianmu::core::PackStr::LoadDataFromFile (this=0x7ef154069870, f=0x7f14c1780df0) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/pack_str.cpp:99
#1  0x00000000030a8199 in Tianmu::core::PackStr::PackStr (this=0x7ef154069870, dpn=0x7ef14d9ff140, pc=..., s=0x7ef154030da0)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/pack_str.cpp:57
#2  0x00000000030e0bad in __gnu_cxx::new_allocator<Tianmu::core::PackStr>::construct<Tianmu::core::PackStr<Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> > (this=0x7f14c1780fc7, __p=0x7ef154069870, __args#0=@0x7f14c17811f8: 0x7ef14d9ff140, __args#1=..., 
    __args#2=@0x7ef15403eb18: 0x7ef154030da0) at /opt/rh/devtoolset-7/root/usr/include/c++/7/ext/new_allocator.h:136
#3  0x00000000030dfd38 in std::allocator_traits<std::allocator<Tianmu::core::PackStr> >::construct<Tianmu::core::PackStr<Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> > (__a=..., __p=0x7ef154069870, __args#0=@0x7f14c17811f8: 0x7ef14d9ff140, __args#1=..., 
    __args#2=@0x7ef15403eb18: 0x7ef154030da0) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/alloc_traits.h:475
#4  0x00000000030de2e2 in std::_Sp_counted_ptr_inplace<Tianmu::core::PackStr, std::allocator<Tianmu::core::PackStr>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (this=0x7ef154069860, __a=...)
    at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:526
#5  0x00000000030dc0df in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Tianmu::core::PackStr, std::allocator<Tianmu::core::PackStr>, Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (this=0x7f14c1781208, __a=...)
    at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:637
#6  0x00000000030d9dfa in std::__shared_ptr<Tianmu::core::PackStr, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Tianmu::core::PackStr>, Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (this=0x7f14c1781200, __tag=..., __a=...)
    at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:1295
#7  0x00000000030d8473 in std::shared_ptr<Tianmu::core::PackStr>::shared_ptr<std::allocator<Tianmu::core::PackStr>, Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (this=0x7f14c1781200, __tag=..., __a=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr.h:344
#8  0x00000000030d6eff in std::allocate_shared<Tianmu::core::PackStr, std::allocator<Tianmu::core::PackStr>, Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (__a=..., __args#0=@0x7f14c17811f8: 0x7ef14d9ff140, __args#1=..., __args#2=@0x7ef15403eb18: 0x7ef154030da0)
    at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr.h:691
#9  0x00000000030d4ef5 in std::make_shared<Tianmu::core::PackStr, Tianmu::core::DPN*&, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty> const&, Tianmu::core::ColumnShare*&> (__args#0=@0x7f14c17811f8: 0x7ef14d9ff140, __args#1=..., __args#2=@0x7ef15403eb18: 0x7ef154030da0)
    at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr.h:707
#10 0x00000000030cd7fd in Tianmu::core::RCAttr::Fetch (this=0x7ef15403e980, pc=...) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/rc_attr.cpp:793
#11 0x00000000030d4a97 in Tianmu::core::DataCache::GetOrFetchObject<Tianmu::core::Pack, Tianmu::core::ObjectId<(Tianmu::core::COORD_TYPE)0, 3, Tianmu::core::object_id_helper::empty>, Tianmu::core::RCAttr> (this=0x67412c0, coord_=..., fetcher_=0x7ef15403e980) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/data_cache.h:232
#12 0x00000000030ccfdc in Tianmu::core::RCAttr::LockPackForUse (this=0x7ef15403e980, pn=5)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/rc_attr.cpp:737
#13 0x0000000002db5694 in Tianmu::core::RCTable::LockPackForUse (this=0x7ef15403b770, attr=3, pack_no=5)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/rc_table.cpp:207
#14 0x00000000030a5349 in Tianmu::core::VCPackGuardian::LockPackrow (this=0x7ef154055d08, mit=...)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/pack_guardian.cpp:75
#15 0x0000000002d8a41a in Tianmu::vcolumn::VirtualColumn::LockSourcePacks (this=0x7ef154055c30, mit=...)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/vc/virtual_column.h:45
#16 0x000000000305d76a in Tianmu::core::Descriptor::LockSourcePacks (this=0x7ef154062850, mit=...)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/descriptor.cpp:786
#17 0x000000000305dd4a in Tianmu::core::Descriptor::EvaluatePack (this=0x7ef154062850, mit=...)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/descriptor.cpp:866
#18 0x00000000030bfd87 in Tianmu::core::ParameterizedFilter::ApplyDescriptor (this=0x7ef1540549a0, desc_number=0, limit=-1)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/parameterized_filter.cpp:1373
#19 0x00000000030be329 in Tianmu::core::ParameterizedFilter::UpdateMultiIndex (this=0x7ef1540549a0, count_only=false, limit=-1)
---Type <return> to continue, or q <return> to quit---
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/parameterized_filter.cpp:1092
#20 0x0000000002d80377 in Tianmu::core::Query::Preexecute (this=0x7f14c1782800, qu=..., sender=0x7ef154054760, display_now=true)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/query.cpp:777
#21 0x0000000002d51b76 in Tianmu::core::Engine::Execute (this=0x6741050, thd=0x7ef154002bd0, lex=0x7ef154004ef8, result_output=0x7ef15401fc70, unit_for_union=0x0)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/engine_execute.cpp:421
#22 0x0000000002d50e04 in Tianmu::core::Engine::HandleSelect (this=0x6741050, thd=0x7ef154002bd0, lex=0x7ef154004ef8, result=@0x7f14c1782d18: 0x7ef15401fc70, setup_tables_done_option=0, 
    res=@0x7f14c1782d14: 0, optimize_after_tianmu=@0x7f14c1782d0c: 1, tianmu_free_join=@0x7f14c1782d10: 1, with_insert=0)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/core/engine_execute.cpp:232
#23 0x0000000002e39861 in Tianmu::dbhandler::TIANMU_HandleSelect (thd=0x7ef154002bd0, lex=0x7ef154004ef8, result=@0x7f14c1782d18: 0x7ef15401fc70, setup_tables_done_option=0, 
    res=@0x7f14c1782d14: 0, optimize_after_tianmu=@0x7f14c1782d0c: 1, tianmu_free_join=@0x7f14c1782d10: 1, with_insert=0)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/tianmu/handler/ha_rcengine.cpp:82
#24 0x00000000024793ba in execute_sqlcom_select (thd=0x7ef154002bd0, all_tables=0x7ef15401ca50) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/sql_parse.cc:5182
#25 0x000000000247273e in mysql_execute_command (thd=0x7ef154002bd0, first_level=true) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/sql_parse.cc:2831
#26 0x000000000247a383 in mysql_parse (thd=0x7ef154002bd0, parser_state=0x7f14c1783eb0) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/sql_parse.cc:5621
#27 0x000000000246f61b in dispatch_command (thd=0x7ef154002bd0, com_data=0x7f14c1784650, command=COM_QUERY)
    at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/sql_parse.cc:1495
#28 0x000000000246e547 in do_command (thd=0x7ef154002bd0) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/sql_parse.cc:1034
#29 0x00000000025a1147 in handle_connection (arg=0x10f92fc0) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/sql/conn_handler/connection_handler_per_thread.cc:313
#30 0x0000000002c8757c in pfs_spawn_thread (arg=0xbf73e40) at /home/jenkins/workspace/stonedb5.7-zsl-centos7.9-30-119-20220805/storage/perfschema/pfs.cc:2197
#31 0x00007f14cbca7ea5 in start_thread () from /lib64/libpthread.so.0
#32 0x00007f14c987cb0d in clone () from /lib64/libc.so.6

核心函数:

Descriptor::LockSourcePacks

void Descriptor::LockSourcePacks(const MIIterator &mit) {
  if (tree) tree->root->PrepareToLock(0);
  if (attr.vc) attr.vc->LockSourcePacks(mit);
  if (val1.vc) val1.vc->LockSourcePacks(mit);
  if (val2.vc) val2.vc->LockSourcePacks(mit);
}

VirtualColumn::LockSourcePacks

  void LockSourcePacks(const core::MIIterator &mit) override { pguard.LockPackrow(mit); }

VCPackGuardian::LockPackrow

void VCPackGuardian::LockPackrow(const MIIterator &mit) {
  int threadId = mit.GetTaskId();
  int taskNum = mit.GetTaskNum();
  {
    std::scoped_lock g(mx_thread);
    if (!initialized) {
      Initialize(taskNum);
    }
    if (initialized && (taskNum > threads)) {
      // recheck to make sure last_pack is not overflow
      ResizeLastPack(taskNum);
    }
  }
  for (auto iter = my_vc.GetVarMap().cbegin(); iter != my_vc.GetVarMap().cend(); iter++) {
    int cur_dim = iter->dim;
    if (last_pack[cur_dim][threadId] != mit.GetCurPackrow(cur_dim)) {
      JustATable *tab = iter->GetTabPtr().get();
      if (last_pack[cur_dim][threadId] != common::NULL_VALUE_32)
        tab->UnlockPackFromUse(iter->col_ndx, last_pack[cur_dim][threadId]);
      try {
        tab->LockPackForUse(iter->col_ndx, mit.GetCurPackrow(cur_dim));
      } catch (...) {
        // unlock packs which are partially locked for this packrow
        auto it = my_vc.GetVarMap().begin();
        for (; it != iter; ++it) {
          int cur_dim = it->dim;
          if (last_pack[cur_dim][threadId] != mit.GetCurPackrow(cur_dim) &&
              last_pack[cur_dim][threadId] != common::NULL_VALUE_32)
            it->GetTabPtr()->UnlockPackFromUse(it->col_ndx, mit.GetCurPackrow(cur_dim));
        }

        for (++iter; iter != my_vc.GetVarMap().end(); ++iter) {
          int cur_dim = iter->dim;
          if (last_pack[cur_dim][threadId] != mit.GetCurPackrow(cur_dim) &&
              last_pack[cur_dim][threadId] != common::NULL_VALUE_32)
            iter->GetTabPtr()->UnlockPackFromUse(iter->col_ndx, last_pack[cur_dim][threadId]);
        }

        for (auto const &iter : my_vc.GetVarMap()) last_pack[iter.dim][threadId] = common::NULL_VALUE_32;
        throw;
      }
    }
  }
  for (auto const &iter : my_vc.GetVarMap())
    last_pack[iter.dim][threadId] = mit.GetCurPackrow(iter.dim);  // must be in a separate loop, otherwise
                                                                  // for "a + b" will not lock b
}

RCAttr::LockPackForUse

void RCAttr::LockPackForUse(common::PACK_INDEX pn) {
  auto dpn = &get_dpn(pn);
  if (dpn->IsLocal()) dpn = m_share->get_dpn_ptr(dpn->base);

  if (dpn->Trivial() && !dpn->IsLocal()) return;

  while (true) {
    if (dpn->IncRef()) return;

    // either the pack is not loaded yet or other thread is loading it

    uint64_t v = 0;
    if (dpn->CAS(v, loading_flag)) {
      // we win the chance to load data
      std::shared_ptr<Pack> sp;
      try {
        sp = ha_rcengine_->cache.GetOrFetchObject<Pack>(get_pc(pn), this);
      } catch (std::exception &e) {
        dpn->SetPackPtr(0);
        TIANMU_LOG(LogCtl_Level::ERROR, "An exception is caught: %s", e.what());
        throw e;
      } catch (...) {
        dpn->SetPackPtr(0);
        TIANMU_LOG(LogCtl_Level::ERROR, "An unknown system exception error caught.");
        throw;
      }

      uint64_t newv = reinterpret_cast<unsigned long>(sp.get()) + tag_one;
      uint64_t expected = loading_flag;
      ASSERT(dpn->CAS(expected, newv),
             "bad loading flag" + std::to_string(newv) + ". " + Path().string() + " index:" + std::to_string(pn));
      return;
    }
    // some one is loading data, wait a while and retry
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
  }
}

DataCache::GetOrFetchObject


  template <typename T, typename U, typename V>
  std::shared_ptr<T> GetOrFetchObject(U const &coord_, V *fetcher_) {
    auto &c(cache<U>());
    auto &w(waitIO<U>());
    auto &cond(condition<U>());
    bool waited = false;
    /* a scope for mutex lock */
    {
      /* Lock is acquired inside */
      std::unique_lock<std::recursive_mutex> m_obj_guard(mm::TraceableObject::GetLockingMutex());

      std::scoped_lock lock(m_cache_mutex);

      auto it = c.find(coord_);

      if (it != c.end()) {
        if constexpr (U::ID == COORD_TYPE::PACK) {
          it->second->Lock();
          ++m_cacheHits;
          it->second->TrackAccess();
        }
        return std::static_pointer_cast<T>(it->second);
      }

      {
        if constexpr (U::ID == COORD_TYPE::PACK) m_cacheMisses++;
        auto rit = w.find(coord_);
        while (rit != w.end()) {
          m_readWaitInProgress++;
          if (waited)
            m_falseWakeup++;
          else
            m_readWait++;

          m_cache_mutex.unlock();
          cond.wait(m_obj_guard);
          m_cache_mutex.lock();

          waited = true;
          m_readWaitInProgress--;
          rit = w.find(coord_);
        }
        it = c.find(coord_);
        if (it != c.end()) {
          if constexpr (U::ID == COORD_TYPE::PACK) {
            it->second->Lock();
            it->second->TrackAccess();
          }
          return std::static_pointer_cast<T>(it->second);
        }
        // mm::TraceableObject::GetLockingMutex().Unlock();
        // if we get here the obj has been loaded, used, unlocked
        // and pushed out of memory before we should get to it after
        // waiting
      }
      w.insert(coord_);
      m_packLoadInProgress++;
    }

    std::shared_ptr<T> obj;
    try {
      obj = fetcher_->Fetch(coord_);
    } catch (...) {
      std::scoped_lock m_obj_guard(mm::TraceableObject::GetLockingMutex());
      std::scoped_lock lock(m_cache_mutex);
      m_loadErrors++;
      m_packLoadInProgress--;
      w.erase(coord_);
      cond.notify_all();
      throw;
    }

    {
      obj->SetOwner(this);
      std::scoped_lock m_obj_guard(mm::TraceableObject::GetLockingMutex());
      std::scoped_lock lock(m_cache_mutex);
      if constexpr (U::ID == COORD_TYPE::PACK) {
        m_packLoads++;
        obj->TrackAccess();
      }
      m_packLoadInProgress--;
      DEBUG_ASSERT(c.find(coord_) == c.end());
      c.insert(std::make_pair(coord_, obj));
      w.erase(coord_);
    }
    cond.notify_all();

    return obj;
  }

RCAttr::Fetch

std::shared_ptr<Pack> RCAttr::Fetch(const PackCoordinate &pc) {
  auto dpn = m_share->get_dpn_ptr(pc_dp(pc));
  if (GetPackType() == common::PackType::STR) return std::make_shared<PackStr>(dpn, pc, m_share);
  return std::make_shared<PackInt>(dpn, pc, m_share);
}

PackStr::PackStr

PackStr::PackStr(DPN *dpn, PackCoordinate pc, ColumnShare *s) : Pack(dpn, pc, s) {
  auto t = s->ColType().GetTypeName();

  if (t == common::CT::BIN || t == common::CT::LONGTEXT)
    data.len_mode = sizeof(uint32_t);
  else
    data.len_mode = sizeof(uint16_t);

  try {
    data.index = (char **)alloc(sizeof(char *) * (1 << s->pss), mm::BLOCK_TYPE::BLOCK_UNCOMPRESSED);
    data.lens = alloc((data.len_mode * (1 << s->pss)), mm::BLOCK_TYPE::BLOCK_UNCOMPRESSED);
    std::memset(data.lens, 0, data.len_mode * (1 << s->pss));

    if (!dpn->NullOnly()) {
      system::TianmuFile f;
      f.OpenReadOnly(s->DataFile());
      f.Seek(dpn->addr, SEEK_SET);
      LoadDataFromFile(&f);
    }
  } catch (...) {
    Destroy();
    throw;
  }
}
      system::TianmuFile f;
      f.OpenReadOnly(s->DataFile());
      f.Seek(dpn->addr, SEEK_SET);
      LoadDataFromFile(&f);

PackStr::LoadDataFromFile

void PackStr::LoadDataFromFile(system::Stream *f) {
  FunctionExecutor fe([this]() { Lock(); }, [this]() { Unlock(); });

  if (IsModeNoCompression()) {
    LoadUncompressed(f);
  } else if (s->ColType().GetFmt() == common::PackFmt::TRIE) {
    LoadCompressedTrie(f);
  } else {
    LoadCompressed(f);
  }
}

PackStr::LoadCompressed


void PackStr::LoadCompressed(system::Stream *f) {
  ASSERT(IsModeCompressionApplied());

  auto compressed_buf = alloc_ptr(dpn->len + 1, mm::BLOCK_TYPE::BLOCK_COMPRESSED);
  f->ReadExact(compressed_buf.get(), dpn->len);

  dpn->synced = true;

  // if (ATI::IsBinType(s->ColType().GetTypeName())) {
  //    throw common::Exception("Compression format no longer supported.");
  //}

  // uncompress the data
  mm::MMGuard<char *> tmp_index((char **)alloc(dpn->nr * sizeof(char *), mm::BLOCK_TYPE::BLOCK_TEMPORARY), *this);

  char *cur_buf = reinterpret_cast<char *>(compressed_buf.get());

  char (*FREE_PLACE)(reinterpret_cast<char *>(-1));

  uint null_buf_size = 0;
  if (dpn->nn > 0) {
    null_buf_size = (*(ushort *)cur_buf);
    if (!IsModeNullsCompressed())  // flat null encoding
      std::memcpy(nulls.get(), cur_buf + 2, null_buf_size);
    else {
      compress::BitstreamCompressor bsc;
      CprsErr res = bsc.Decompress((char *)nulls.get(), null_buf_size, cur_buf + 2, dpn->nr, dpn->nn);
      if (res != CprsErr::CPRS_SUCCESS) {
        throw common::DatabaseException("Decompression of nulls failed for column " +
                                        std::to_string(pc_column(GetCoordinate().co.pack) + 1) + ", pack " +
                                        std::to_string(pc_dp(GetCoordinate().co.pack) + 1) + " (error " +
                                        std::to_string(static_cast<int>(res)) + ").");
      }
    }
    cur_buf += (null_buf_size + 2);

    for (uint i = 0; i < dpn->nr; i++) {
      if (IsNull(i))
        tmp_index[i] = nullptr;
      else
        tmp_index[i] = FREE_PLACE;  // special value: an object awaiting decoding
    }
  } else
    for (uint i = 0; i < dpn->nr; i++) tmp_index[i] = FREE_PLACE;

  auto comp_len_buf_size = *(uint32_t *)cur_buf;
  auto maxv = *(uint32_t *)(cur_buf + 4);

  if (maxv != 0) {
    compress::NumCompressor<uint> nc;
    mm::MMGuard<uint> cn_ptr((uint *)alloc((1 << s->pss) * sizeof(uint), mm::BLOCK_TYPE::BLOCK_TEMPORARY), *this);
    CprsErr res = nc.Decompress(cn_ptr.get(), (char *)(cur_buf + 8), comp_len_buf_size - 8, dpn->nr - dpn->nn, maxv);
    if (res != CprsErr::CPRS_SUCCESS) {
      std::stringstream msg_buf;
      msg_buf << "Decompression of lengths of std::string values failed for column "
              << (pc_column(GetCoordinate().co.pack) + 1) << ", pack " << (pc_dp(GetCoordinate().co.pack) + 1)
              << " (error " << static_cast<int>(res) << ").";
      throw common::DatabaseException(msg_buf.str());
    }

    int oid = 0;
    for (uint o = 0; o < dpn->nr; o++)
      if (!IsNull(int(o))) SetSize(o, (uint)cn_ptr[oid++]);
  } else {
    for (uint o = 0; o < dpn->nr; o++)
      if (!IsNull(int(o))) SetSize(o, 0);
  }
  cur_buf += comp_len_buf_size;

  auto dlen = *(uint32_t *)cur_buf;
  cur_buf += sizeof(dlen);
  data.sum_len = *(uint32_t *)cur_buf;
  cur_buf += sizeof(uint32_t);

  ASSERT(cur_buf + dlen == dpn->len + reinterpret_cast<char *>(compressed_buf.get()),
         std::to_string(data.sum_len) + "/" + std::to_string(dpn->len) + "/" + std::to_string(dlen));

  int zlo = 0;
  for (uint obj = 0; obj < dpn->nr; obj++)
    if (!IsNull(obj) && GetSize(obj) == 0) zlo++;
  int objs = dpn->nr - dpn->nn - zlo;

  if (objs) {
    mm::MMGuard<uint> tmp_len((uint *)alloc(objs * sizeof(uint), mm::BLOCK_TYPE::BLOCK_TEMPORARY), *this);
    for (uint tmp_id = 0, id = 0; id < dpn->nr; id++)
      if (!IsNull(id) && GetSize(id) != 0) tmp_len[tmp_id++] = GetSize(id);

    if (dlen) {
      data.v.push_back({(char *)alloc(data.sum_len, mm::BLOCK_TYPE::BLOCK_UNCOMPRESSED), data.sum_len, 0});
      compress::TextCompressor tc;
      CprsErr res =
          tc.Decompress(data.v.front().ptr, data.sum_len, cur_buf, dlen, tmp_index.get(), tmp_len.get(), objs);
      if (res != CprsErr::CPRS_SUCCESS) {
        std::stringstream msg_buf;
        msg_buf << "Decompression of std::string values failed for column " << (pc_column(GetCoordinate().co.pack) + 1)
                << ", pack " << (pc_dp(GetCoordinate().co.pack) + 1) << " (error " << static_cast<int>(res) << ").";
        throw common::DatabaseException(msg_buf.str());
      }
    }
  }

  for (uint tmp_id = 0, id = 0; id < dpn->nr; id++) {
    if (!IsNull(id) && GetSize(id) != 0)
      SetPtr(id, (char *)tmp_index[tmp_id++]);
    else {
      SetSize(id, 0);
      SetPtr(id, 0);
    }
  }
}

相关文章:

  • 在线搭建自己的网课答案公众号题库系统
  • 计算机毕业设计springboot+vue基本微信小程序的考试系统
  • 在线搭建网课查题公众号
  • 计算机毕业设计springboot+vue基本微信小程序的家装公司管理系统小程序
  • 77.组合 | 40.组合总和II | 39.组合总和
  • 代码坏味道与重构之全局变量
  • 伪原创-伪原创软件-免费伪原创软件
  • Vue - 插值 - 指令 - 过滤器 - 计算属性与监听属性 - 购物车案例
  • 自己的思考
  • 电脑无线5g网卡发现不了网件R7000的Wifi 5g网络
  • 刷题记录:牛客NC201628纸牌游戏
  • 线性表与链表的详解
  • 常量指针、指针常量,指针数组、数组指针,函数指针、指针函数
  • java基于ssm+vue+elementui楼盘房屋销售系统 前后端分离
  • FastAPI 学习之路(三十三)操作数据库
  • 07.Android之多媒体问题
  • 4个实用的微服务测试策略
  • Apache的基本使用
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • EventListener原理
  • Flannel解读
  • Golang-长连接-状态推送
  • linux安装openssl、swoole等扩展的具体步骤
  • SpiderData 2019年2月25日 DApp数据排行榜
  • SSH 免密登录
  • text-decoration与color属性
  • 编写符合Python风格的对象
  • 高度不固定时垂直居中
  • 如何学习JavaEE,项目又该如何做?
  • 小程序 setData 学问多
  • RDS-Mysql 物理备份恢复到本地数据库上
  • ​如何在iOS手机上查看应用日志
  • (9)STL算法之逆转旋转
  • (Git) gitignore基础使用
  • (二)c52学习之旅-简单了解单片机
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (三)mysql_MYSQL(三)
  • (五)网络优化与超参数选择--九五小庞
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • (转)重识new
  • ../depcomp: line 571: exec: g++: not found
  • .NET Micro Framework初体验
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .net反编译的九款神器
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .NET中GET与SET的用法
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [17]JAVAEE-HTTP协议
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [CSDN首发]鱿鱼游戏的具体玩法详细介绍