Files
oceanbase/src/storage/ob_macro_meta_replay_map.cpp
2021-06-15 14:52:44 +08:00

180 lines
5.6 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX STORAGE
#include "ob_macro_meta_replay_map.h"
using namespace oceanbase::common;
using namespace oceanbase::blocksstable;
using namespace oceanbase::storage;
ObMacroBlockKey::ObMacroBlockKey() : table_key_(), macro_block_id_()
{}
ObMacroBlockKey::ObMacroBlockKey(const ObITable::TableKey& table_key, const blocksstable::MacroBlockId& macro_block_id)
: table_key_(table_key), macro_block_id_(macro_block_id)
{}
uint64_t ObMacroBlockKey::hash() const
{
uint64_t hash_val = table_key_.hash();
uint64_t hash_macro_block_id = macro_block_id_.hash();
hash_val = common::murmurhash2(&hash_macro_block_id, sizeof(hash_macro_block_id), hash_val);
return hash_val;
}
bool ObMacroBlockKey::operator==(const ObMacroBlockKey& other) const
{
bool bret = table_key_ == other.table_key_ && macro_block_id_ == other.macro_block_id_;
return bret;
}
ObMacroMetaReplayMap::ObMacroMetaReplayMap() : map_(), map_lock_(), is_inited_(false)
{}
ObMacroMetaReplayMap::~ObMacroMetaReplayMap()
{
destroy();
}
int ObMacroMetaReplayMap::init()
{
int ret = OB_SUCCESS;
const char* label = "MacroMetaReplay";
if (OB_UNLIKELY(is_inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("ObMacroMetaReplayMap has been inited twice", K(ret));
} else if (OB_FAIL(map_.create(REPLAY_BUCKET_CNT, label))) {
LOG_WARN("fail to create macro meta map", K(ret));
} else if (OB_FAIL(allocator_.init(OB_MALLOC_BIG_BLOCK_SIZE, label))) {
LOG_WARN("fail to init allocator", K(ret));
} else {
is_inited_ = true;
}
return ret;
}
int ObMacroMetaReplayMap::set(const ObMacroBlockKey& key, ObMacroBlockMetaV2& meta, const bool overwrite)
{
int ret = OB_SUCCESS;
ObMacroBlockMetaV2* new_meta = nullptr;
lib::ObMutexGuard guard(map_lock_);
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObMacroMetaReplayMap has not been inited", K(ret));
} else if (OB_FAIL(meta.deep_copy(new_meta, allocator_))) {
LOG_WARN("fail to deep copy macro meta", K(ret));
} else if (OB_FAIL(map_.set_refactored(key, new_meta))) {
if (OB_HASH_EXIST == ret) {
ret = OB_SUCCESS;
if (overwrite) {
ObMacroBlockMetaV2* delete_meta = nullptr;
if (OB_FAIL(map_.erase_refactored(key, &delete_meta))) {
LOG_WARN("fail to erase from map", K(ret), K(key));
} else if (OB_FAIL(map_.set_refactored(key, new_meta))) {
LOG_WARN("fail to overwrite map", K(ret), K(key), K(overwrite), K(meta));
} else {
new_meta = nullptr;
delete_meta->~ObMacroBlockMetaV2();
allocator_.free(delete_meta);
delete_meta = nullptr;
LOG_INFO("succeed to overwrite replay macro meta", K(key), KP(new_meta), K(key.hash()));
}
}
} else {
LOG_WARN("fail to set map", K(ret), K(key), K(overwrite), K(meta));
}
} else {
new_meta = nullptr;
LOG_INFO("succeed to set replay macro meta", K(key), KP(new_meta), K(key.hash()));
}
if (nullptr != new_meta) {
new_meta->~ObMacroBlockMetaV2();
new_meta = nullptr;
}
return ret;
}
int ObMacroMetaReplayMap::get(const ObMacroBlockKey& key, ObMacroBlockMetaV2*& meta)
{
int ret = OB_SUCCESS;
meta = nullptr;
lib::ObMutexGuard guard(map_lock_);
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObMacroMetaReplayMap has not been inited", K(ret));
} else if (OB_FAIL(map_.get_refactored(key, meta))) {
if (OB_HASH_NOT_EXIST == ret) {
ret = OB_ENTRY_NOT_EXIST;
} else {
LOG_WARN("fail to get from hashmap", K(ret), K(key));
}
}
return ret;
}
int ObMacroMetaReplayMap::remove(const ObITable::TableKey& table_key, const blocksstable::MacroBlockId& block_id)
{
int ret = OB_SUCCESS;
ObMacroBlockKey macro_key;
macro_key.table_key_ = table_key;
macro_key.macro_block_id_ = block_id;
ObMacroBlockMetaV2* meta = nullptr;
lib::ObMutexGuard guard(map_lock_);
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObMacroMetaReplayMap has not been inited", K(ret));
} else if (OB_FAIL(map_.erase_refactored(macro_key, &meta))) {
LOG_WARN("fail to erase from map", K(ret), K(macro_key));
} else {
meta->~ObMacroBlockMetaV2();
allocator_.free(meta);
meta = nullptr;
}
return ret;
}
int ObMacroMetaReplayMap::remove(
const ObITable::TableKey& table_key, const common::ObIArray<blocksstable::MacroBlockId>& block_ids)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObMacroMetaReplayMap has not been inited", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < block_ids.count(); ++i) {
if (OB_FAIL(remove(table_key, block_ids.at(i)))) {
LOG_WARN("fail to remove macro key", K(ret), K(table_key));
}
}
}
return ret;
}
void ObMacroMetaReplayMap::destroy()
{
if (is_inited_) {
for (MAP::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
ObMacroBlockMetaV2* meta = iter->second;
if (nullptr != meta) {
meta->~ObMacroBlockMetaV2();
allocator_.free(meta);
meta = nullptr;
}
}
map_.destroy();
allocator_.destroy();
is_inited_ = false;
}
}