[SCN] adjust ObBatchCreateTabletArg

This commit is contained in:
obdev
2022-11-28 02:40:26 +00:00
committed by ob-robot
parent 4c49f6e7c5
commit c538314fd7
62 changed files with 391 additions and 1828 deletions

View File

@ -121,7 +121,7 @@ target_link_libraries(oblib_base_base_base
${DEP_DIR}/lib/libssl.a
${DEP_DIR}/lib/libcrypto.a
${LGPL_DEPS}
${DEP_DIR}/lib/libunwind.a
$<$<STREQUAL:"${ARCHITECTURE}","x86_64">:${DEP_DIR}/lib/libunwind.a>
${DEP_DIR}/lib/libz.a
-L${DEP_DIR}/var/usr/lib64
-L${DEP_DIR}/var/usr/lib

View File

@ -119,21 +119,6 @@ public:
size_ = 0;
}
int shrink_size(int64_t size)
{
LockGuard guard(lock_);
int ret = OB_SUCCESS;
if (size <= 0 || size > capacity_) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid argument", K(size), K_(capacity));
} else if (size * 2 <= capacity_) {
capacity_ = size * 2;
} else {
capacity_ = size;
}
return ret;
}
void print() const
{
COMMON_LOG(INFO, "array_hash dump begin:", K(this));

View File

@ -1,307 +0,0 @@
/**
* 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.
*/
#ifndef OCEANBASE_LIB_HASH_OB_EXT_ITER_HASHSET_H__
#define OCEANBASE_LIB_HASH_OB_EXT_ITER_HASHSET_H__
#include "lib/hash/ob_iteratable_hashset.h" // ObIteratableHashSet
#include "lib/utility/ob_print_utils.h"
namespace oceanbase
{
namespace common
{
namespace hash
{
template <class K, uint64_t N, class Allocator> class ObExtIterHashSet;
///////////////////////////////////// ObExtIterHashSet Iterator /////////////////////////////////////
template <class HashSet>
class ObExtIterHashSetConstIterator
{
public:
typedef typename HashSet::const_key_ref_t const_key_ref_t;
typedef ObExtIterHashSetConstIterator<HashSet> SelfType;
typedef typename HashSet::HashSetBucket BucketType;
typedef typename HashSet::InnerHashSetIter InnerIter;
public:
ObExtIterHashSetConstIterator(const HashSet *set, const BucketType *bucket, const InnerIter &iter)
: hash_set_(set), bucket_(bucket), iter_(iter)
{}
ObExtIterHashSetConstIterator(const SelfType &other)
: hash_set_(other.hash_set_), bucket_(other.bucket_), iter_(other.iter_)
{}
~ObExtIterHashSetConstIterator()
{}
public:
ObExtIterHashSetConstIterator &operator=(const SelfType &other)
{
if (this != &other) {
hash_set_ = other.hash_set_;
bucket_ = other.bucket_;
iter_ = other.iter_;
}
return *this;
}
ObExtIterHashSetConstIterator &operator=(SelfType &&other) = default;
bool operator==(const SelfType &other) const
{
return other.hash_set_ == hash_set_ && other.bucket_ == bucket_ && other.iter_ == iter_;
}
bool operator!=(const SelfType &other) const
{
return other.hash_set_ != hash_set_ || other.bucket_ != bucket_ || other.iter_ != iter_;
}
SelfType &operator++()
{
if (NULL == hash_set_ || NULL == bucket_) {
LIB_LOG(ERROR, "err hash set, iter or bucket", K(hash_set_), K(bucket_));
} else {
// if current bucket is not null, fetch next one.
if (iter_ != bucket_->hash_set_.end()) {
++iter_;
}
// if reach end of current bucket, step to the next bucket.
if (iter_ == bucket_->hash_set_.end() && NULL != bucket_->next_) {
bucket_ = bucket_->next_;
iter_ = bucket_->hash_set_.begin();
}
}
return *this;
}
const_key_ref_t operator*() const
{
if (NULL == hash_set_ || NULL == bucket_) {
LIB_LOG(ERROR, "err hash set, iter or bucket", K(hash_set_), K(bucket_));
}
return *iter_;
}
private:
const HashSet *hash_set_;
const BucketType *bucket_;
InnerIter iter_;
};
///////////////////////////////////// ObExtIterHashSet /////////////////////////////////////
template <class K, uint64_t N = 1031, class Allocator = ObIAllocator>
class ObExtIterHashSet
{
public:
typedef const K &const_key_ref_t;
typedef ObIteratableHashSet<K, N> BaseHashSet;
typedef ObExtIterHashSet<K, N, Allocator> SelfType;
typedef ObExtIterHashSetConstIterator<SelfType> const_iterator_t;
typedef typename BaseHashSet::const_iterator_t InnerHashSetIter;
struct HashSetBucket
{
BaseHashSet hash_set_;
HashSetBucket *next_;
HashSetBucket() : hash_set_(), next_(NULL) {}
~HashSetBucket() {}
void reset()
{
hash_set_.reset();
next_ = NULL;
}
};
public:
explicit ObExtIterHashSet(Allocator &allocator);
virtual ~ObExtIterHashSet();
public:
/**
* @retval OB_SUCCESS insert successfully
* @retval OB_HASH_EXIST key exists
* @retval other ret failed
*/
int set_refactored(const K &key);
/**
* @retval OB_HASH_EXIST key exists
* @retval OB_HASH_NOT_EXIST key not exists
*/
int exist_refactored(const K &key) const { return is_exist_(key) ? OB_HASH_EXIST : OB_HASH_NOT_EXIST; }
void reset();
void clear() { reset(); }
const_iterator_t begin() const
{
return const_iterator_t(this, &buckets_, buckets_.hash_set_.begin());
}
const_iterator_t end() const
{
return const_iterator_t(this, buckets_tail_, buckets_tail_->hash_set_.end());
}
int64_t count() const { return count_; }
public:
DECLARE_TO_STRING;
private:
bool is_exist_(const K &key) const;
bool is_full_() const { return count_ >= bucket_num_ * static_cast<int64_t>(N); }
int add_bucket_();
private:
int64_t count_; // count of object
int64_t bucket_num_; // count of bucket
Allocator &allocator_; // allocator
HashSetBucket buckets_; // bucket lists
HashSetBucket *buckets_tail_; // bucket lists tail
private:
template <class HashSet>
friend class ObExtIterHashSetConstIterator;
private:
DISALLOW_COPY_AND_ASSIGN(ObExtIterHashSet);
};
template <class K, uint64_t N, class Allocator>
ObExtIterHashSet<K, N, Allocator>::ObExtIterHashSet(Allocator &allocator) :
count_(0),
bucket_num_(1),
allocator_(allocator),
buckets_(),
buckets_tail_(&buckets_)
{}
template <class K, uint64_t N, class Allocator>
ObExtIterHashSet<K, N, Allocator>::~ObExtIterHashSet()
{
reset();
}
template <class K, uint64_t N, class Allocator>
int ObExtIterHashSet<K, N, Allocator>::set_refactored(const K &key)
{
int ret = OB_SUCCESS;
bool exist = is_exist_(key);
if (exist) {
ret = OB_HASH_EXIST;
} else if (is_full_() && OB_FAIL(add_bucket_())) {
LIB_LOG(WARN, "add_bucket_ fail", K(ret));
} else {
// keep inserting successful
if (NULL == buckets_tail_) {
ret = OB_ERR_UNEXPECTED;
LIB_LOG(WARN, "err bucket tail", K(ret));
} else if (OB_FAIL(buckets_tail_->hash_set_.set_refactored(key))) {
LIB_LOG(WARN, "set key into hash set fail", K(ret));
} else {
count_++;
}
}
return ret;
}
template <class K, uint64_t N, class Allocator>
bool ObExtIterHashSet<K, N, Allocator>::is_exist_(const K &key) const
{
bool exist = false;
const HashSetBucket *item = &buckets_;
while (! exist && NULL != item) {
if (OB_HASH_EXIST == item->hash_set_.exist_refactored(key)) {
exist = true;
break;
} else {
item = item->next_;
}
}
return exist;
}
template <class K, uint64_t N, class Allocator>
int ObExtIterHashSet<K, N, Allocator>::add_bucket_()
{
int ret = OB_SUCCESS;
HashSetBucket *bucket = (HashSetBucket *)allocator_.alloc(sizeof(HashSetBucket));
if (NULL == bucket) {
LIB_LOG(WARN, "allocate memory for bucket fail", "bucket_size", sizeof(HashSetBucket));
ret = OB_ALLOCATE_MEMORY_FAILED;
} else {
new(bucket) HashSetBucket();
bucket->next_ = NULL;
buckets_tail_->next_ = bucket;
buckets_tail_ = bucket;
bucket_num_++;
LIB_LOG(DEBUG, "add bucket", K(bucket_num_), K(count_), K(bucket));
}
return ret;
}
template <class K, uint64_t N, class Allocator>
void ObExtIterHashSet<K, N, Allocator>::reset()
{
HashSetBucket *bucket = buckets_.next_;
while (NULL != bucket) {
HashSetBucket *next = bucket->next_;
bucket->~HashSetBucket();
allocator_.free((void*)bucket);
bucket = next;
}
bucket = NULL;
buckets_.reset();
buckets_tail_ = &buckets_;
bucket_num_ = 1;
count_ = 0;
}
template <class K, uint64_t N, class Allocator>
int64_t ObExtIterHashSet<K, N, Allocator>::to_string(char *buf, const int64_t buf_len) const
{
int64_t pos = 0;
J_ARRAY_START();
const_iterator_t beg = begin();
for (const_iterator_t it = beg;
it != end();
++it) {
if (it != beg) {
J_COMMA();
}
BUF_PRINTO(*it);
}
J_ARRAY_END();
return pos;
}
} // namespace hash
} // namespace common
} // namespace oceanbase
#endif

View File

@ -1,164 +0,0 @@
/**
* 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.
*/
#ifndef OCEANBASE_HASH_OB_FIXED_HASH_H_
#define OCEANBASE_HASH_OB_FIXED_HASH_H_
#include "lib/ob_define.h"
#include "lib/queue/ob_link.h"
#include "lib/hash/ob_hash.h"
namespace oceanbase
{
namespace common
{
template<typename key_t>
class FixedHash
{
public:
typedef ObLink Link;
struct node_t: public Link
{
node_t(): hash_(0), key_() {}
explicit node_t(key_t key): key_(key) {
hash_ = hash_map_calc_hash(key_);
}
~node_t() {}
static uint64_t hash_map_calc_hash(key_t key)
{
return calc_hash(key) | 1;
}
node_t* set(key_t key)
{
hash_ = hash_map_calc_hash(key);
key_ = key;
return this;
}
bool is_dummy_node() {
return 0 == (hash_ & 1);
}
int compare(node_t* that)
{
int ret = 0;
if (this->hash_ > that->hash_) {
ret = 1;
} else if (this->hash_ < that->hash_) {
ret = -1;
} else if (this->is_dummy_node()) {
ret = 0;
} else {
ret = common::compare(this->key_, that->key_);
}
return ret;
}
node_t* set_as_bucket(uint64_t idx)
{
hash_ = bitrev(idx);
return this;
}
uint64_t get_spk() { return bitrev(hash_); }
uint64_t hash_;
key_t key_;
};
FixedHash(void* buf, int64_t size):
nodes_((node_t*)buf), limit_(last2n(size/sizeof(node_t))) {
init_buckets(nodes_, limit_);
}
~FixedHash() {}
int insert(key_t key, node_t* node) {
node_t key_node(key);
return ol_insert(get_pre(&key_node), node->set(key));
}
int del(key_t key, node_t*& node) {
node_t key_node(key);
return ol_del(get_pre(&key_node), &key_node, node);
}
int get(key_t key, node_t*& node) {
node_t key_node(key);
return ol_get(get_pre(&key_node), &key_node, node);
}
node_t* next(node_t* node) {
while(NULL != (node = next_node(node))
&& node->is_dummy_node())
;
return node;
}
private:
node_t* next_node(node_t* node) {
node_t* next = NULL;
if (NULL == node) {
next = nodes_;
} else if (is_last_bit_set((uint64_t)(next = (node_t*)ATOMIC_LOAD(&node->next_)))) {
next = get_pre(node);
}
return next;
}
static uint64_t last2n(const uint64_t x)
{
return x == 0? 0 : (1UL << 63) >> (__builtin_clzll(x));
}
static uint64_t bitrev(uint64_t x)
{
x = (((x & 0xaaaaaaaaaaaaaaaaUL) >> 1) | ((x & 0x5555555555555555UL) << 1));
x = (((x & 0xccccccccccccccccUL) >> 2) | ((x & 0x3333333333333333UL) << 2));
x = (((x & 0xf0f0f0f0f0f0f0f0UL) >> 4) | ((x & 0x0f0f0f0f0f0f0f0fUL) << 4));
x = (((x & 0xff00ff00ff00ff00UL) >> 8) | ((x & 0x00ff00ff00ff00ffUL) << 8));
x = (((x & 0xffff0000ffff0000UL) >> 16) | ((x & 0x0000ffff0000ffff) << 16));
return((x >> 32) | (x << 32));
}
static uint64_t get_idx(uint64_t spk, uint64_t bcnt)
{
return bcnt == 0? 0 : (spk & (bcnt - 1));
}
node_t* get_pre(node_t* key_node)
{
return nodes_ + get_idx(key_node->get_spk(), limit_);
}
static uint64_t get_bucket_pre_idx(uint64_t idx) {
return idx & ~last2n(idx);
}
static int init_buckets(node_t* nodes, int64_t limit) {
int err = 0;
new(nodes)node_t[limit];
nodes[0].set_as_bucket(0);
for(int64_t i = 1; 0 == err && i < limit; i++) {
node_t* node = nodes + i;
node->set_as_bucket(i);
err = ol_insert(nodes + get_bucket_pre_idx(i), node);
}
return err;
}
private:
node_t* nodes_;
int64_t limit_;
};
}; // end namespace common
}; // end namespace oceanbase
#endif /* OCEANBASE_HASH_OB_FIXED_HASH_H_ */

View File

@ -1,379 +0,0 @@
/**
* 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.
*/
#ifndef SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_
#define SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_
#include "lib/ob_define.h"
#include "lib/hash/ob_hashutils.h"
#include "lib/atomic/ob_atomic.h"
#include "lib/utility/ob_print_utils.h"
#include "lib/container/ob_array.h"
#include "lib/lock/ob_bucket_lock.h"
namespace oceanbase
{
namespace common
{
namespace hash
{
// ObMemLessLinkHashMap is convenient for reuse of node.
// there is a simple allocator in the map.
// memory of node should be pre-allocated.
// use of storage of table and meta block.
template <class KEY, class ITEM>
struct ObPreAllocLinkHashNode
{
explicit ObPreAllocLinkHashNode(ITEM &item): item_(item) {}
virtual ~ObPreAllocLinkHashNode() { }
virtual OB_INLINE bool equals(const ObPreAllocLinkHashNode &node) { return equals(node.get_key()); }
virtual OB_INLINE bool equals(const KEY &key) { return get_key() == key; }
//derived class should override static uint64_t hash(const uint64_t &key);
virtual const KEY &get_key() const = 0;
VIRTUAL_TO_STRING_KV(KP(this), K_(item));
ITEM &item_;
};
template <class KEY, class ITEM, class NODE, class ITEM_PROTECTOR>
class ObPreAllocLinkHashMap
{
public:
class ForeachFunctor
{
public:
virtual int operator()(ITEM &item, bool &is_full) = 0;
};
class EraseChecker
{
public:
virtual int operator()(ITEM &item) = 0;
};
class GetFunctor
{
public:
virtual int operator()(ITEM &item) = 0;
};
class Iterator
{
public:
explicit Iterator(ObPreAllocLinkHashMap &map)
: items_(),
item_idx_(0),
bucket_pos_(0),
map_(map)
{
}
virtual ~Iterator() { release_items(); }
int get_next(ITEM *&item)
{
int ret = OB_SUCCESS;
item = NULL;
while (OB_SUCC(ret)) {
if (item_idx_ < items_.count()) {
item = items_.at(item_idx_);
++item_idx_;
break;
} else if (bucket_pos_ >= map_.buckets_count_) {
ret = OB_ITER_END;
} else {
item_idx_ = 0;
release_items();
ObBucketRLockGuard guard(map_.buckets_lock_, bucket_pos_);
if (NULL != map_.buckets_[bucket_pos_]) {
NODE *node = map_.buckets_[bucket_pos_];
while (OB_SUCC(ret) && NULL != node) {
ITEM_PROTECTOR::hold(node->item_);
if (OB_FAIL(items_.push_back(&node->item_))) {
COMMON_LOG(WARN, "Failed to add item", K(ret));
ITEM_PROTECTOR::release(node->item_);
} else {
node = node->next_;
}
}
}
++bucket_pos_;
}
}
return ret;
}
private:
void release_items()
{
for (int64_t i = 0; i < items_.count(); ++i) {
ITEM_PROTECTOR::release(*items_.at(i));
}
items_.reuse();
}
common::ObArray<ITEM *> items_;
int64_t item_idx_;
int64_t bucket_pos_;
ObPreAllocLinkHashMap &map_;
DISALLOW_COPY_AND_ASSIGN(Iterator);
};
ObPreAllocLinkHashMap()
: is_inited_(false),
buckets_lock_(),
count_(),
buckets_(NULL),
buckets_count_(1),
allocator_()
{
}
virtual ~ObPreAllocLinkHashMap()
{
destroy();
}
void destroy()
{
for (uint64_t bucket_pos = 0; NULL != buckets_ && bucket_pos < buckets_count_; ++bucket_pos) {
ObBucketRLockGuard bucket_guard(buckets_lock_, bucket_pos);
NODE *cur = buckets_[bucket_pos];
NODE *next = NULL;
while (NULL != cur) {
next = cur->next_;
free_node(cur);
cur = next;
}
}
is_inited_ = false;
buckets_lock_.destroy();
count_ = 0;
ob_free(buckets_);
buckets_ = NULL;
buckets_count_ = 1;
}
int init(const int64_t buckets_count, const uint32_t latch_id, const lib::ObLabel &label)
{
int ret = OB_SUCCESS;
ObMemAttr mem_attr(OB_SERVER_TENANT_ID, label);
const int64_t real_buckets_count = hash::cal_next_prime(buckets_count);
if (is_inited_) {
ret = OB_INIT_TWICE;
COMMON_LOG(WARN, "cannot init twice", K(ret));
} else if (real_buckets_count <= 0 || buckets_count <= 0) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid bucket count", K(ret), K(real_buckets_count), K(buckets_count));
} else if (OB_FAIL(buckets_lock_.init(real_buckets_count, latch_id, label))) {
COMMON_LOG(WARN, "failed to init buckets lock", K(ret));
} else if (OB_ISNULL(buckets_ = reinterpret_cast<NODE**>(
ob_malloc(sizeof(NODE*) * real_buckets_count, mem_attr)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
COMMON_LOG(WARN, "failed to alloc buckets", K(ret), K(real_buckets_count));
} else {
allocator_.set_label(label);
MEMSET(buckets_, 0, sizeof(NODE*) * real_buckets_count);
COMMON_LOG(INFO, "init hashmap", K(buckets_count), K(real_buckets_count),
"buf_size", sizeof(NODE*) * real_buckets_count, K(latch_id), K(label));
count_ = 0;
buckets_count_ = real_buckets_count;
is_inited_ = true;
}
return ret;
}
uint64_t get_count() const { return ATOMIC_LOAD(&count_); }
uint64_t get_buckets_count() const { return buckets_count_; }
NODE *alloc_node(ITEM &item)
{
return allocator_.alloc(item);
}
void free_node(NODE *&node)
{
allocator_.free(node);
node = NULL;
}
int put(NODE &node)
{
int ret = OB_SUCCESS;
if (!is_inited_) {
ret = OB_NOT_INIT;
COMMON_LOG(WARN, "not inited", K(ret));
} else {
const uint64_t bucket_pos = NODE::hash(node.get_key()) % buckets_count_;
ObBucketWLockGuard bucket_guard(buckets_lock_, bucket_pos);
NODE *cur = buckets_[bucket_pos];
while (NULL != cur) {
if (cur->equals(node)) {
break;
} else {
cur = cur->next_;
}
}
if (NULL != cur) {
ret = OB_HASH_EXIST;
} else {
node.next_ = buckets_[bucket_pos];
buckets_[bucket_pos] = &node;
ATOMIC_INC(&count_);
}
}
return ret;
}
// delete node which has common key
int erase(const KEY &key, ITEM *&del_item, EraseChecker *checker = NULL)
{
int ret = OB_SUCCESS;
del_item = NULL;
if (!is_inited_) {
ret = OB_NOT_INIT;
COMMON_LOG(WARN, "not inited", K(ret));
} else {
const uint64_t bucket_pos = NODE::hash(key) % buckets_count_;
ObBucketWLockGuard bucket_guard(buckets_lock_, bucket_pos);
NODE *cur = buckets_[bucket_pos];
NODE *prev = NULL;
while (NULL != cur) {
if (cur->equals(key)) {
break;
} else {
prev = cur;
cur = cur->next_;
}
}
if (NULL == cur) {
ret = OB_HASH_NOT_EXIST;
} else if (NULL != checker && OB_FAIL((*checker)(cur->item_))) {
// cannot erase now
} else {
if (NULL != prev) {
prev->next_ = cur->next_;
} else {
buckets_[bucket_pos] = cur->next_;
}
cur->next_ = NULL;
del_item = &cur->item_;
free_node(cur);
ATOMIC_DEC(&count_);
}
}
return ret;
}
// delete node which has common key
int erase(const KEY &key)
{
int ret = OB_SUCCESS;
ITEM *del_item = NULL;
if (OB_FAIL(erase(key, del_item))) {
COMMON_LOG(WARN, "failed to erase ndoe", K(ret), K(key));
}
return ret;
}
int exist(const KEY &key)
{
ITEM *item = NULL;
int ret = get(key, item);
if (OB_SUCCESS == ret) {
ret = OB_HASH_EXIST;
}
return ret;
}
int get(const KEY &key, GetFunctor &functor)
{
ITEM *item = NULL;
return get(key, item, &functor);
}
int get(const KEY &key, ITEM *&item, GetFunctor *functor = NULL)
{
int ret = OB_SUCCESS;
item = NULL;
if (!is_inited_) {
ret = OB_NOT_INIT;
COMMON_LOG(WARN, "not inited", K(ret));
} else {
const uint64_t bucket_pos = NODE::hash(key) % buckets_count_;
ObBucketRLockGuard bucket_guard(buckets_lock_, bucket_pos);
NODE *cur = buckets_[bucket_pos];
while (NULL != cur) {
if (cur->equals(key)) {
break;
} else {
cur = cur->next_;
}
}
if (NULL == cur) {
ret = OB_HASH_NOT_EXIST;
} else if (NULL != functor && OB_FAIL((*functor)(cur->item_))) {
COMMON_LOG(WARN, "failed to do get functor", K(ret), K(*cur));
} else {
item = &cur->item_;
}
}
return ret;
}
int foreach(ForeachFunctor &functor)
{
int ret = OB_SUCCESS;
bool is_full = false;
if (!is_inited_) {
ret = OB_NOT_INIT;
COMMON_LOG(WARN, "not inited", K(ret));
} else {
for (uint64_t bucket_pos = 0; OB_SUCC(ret) && !is_full && bucket_pos < buckets_count_; ++bucket_pos) {
ObBucketRLockGuard bucket_guard(buckets_lock_, bucket_pos);
NODE *cur = buckets_[bucket_pos];
while (OB_SUCC(ret) && NULL != cur && !is_full) {
if (OB_FAIL(functor(cur->item_, is_full))) {
COMMON_LOG(WARN, "failed to do foreach functor", K(ret));
} else {
cur = cur->next_;
}
}
}
}
return ret;
}
private:
bool is_inited_;
mutable common::ObBucketLock buckets_lock_;
uint64_t count_;
NODE **buckets_;
uint64_t buckets_count_;
SimpleAllocer<NODE> allocator_;
DISALLOW_COPY_AND_ASSIGN(ObPreAllocLinkHashMap);
};
} // hash
} // common
} // oceanbase
#endif /* SRC_LIBRARY_SRC_LIB_HASH_OB_MEMLESS_LINK_HASHMAP_H_ */

View File

@ -10,6 +10,7 @@
* See the Mulan PubL v2 for more details.
*/
#ifdef __x86_64__
#include "lib/signal/ob_libunwind.h"
#include "lib/signal/safe_snprintf.h"
#define UNW_LOCAL_ONLY
@ -106,3 +107,4 @@ int8_t get_frame_info(unw_cursor_t *cursor, uintptr_t *ip)
*ip = uip - (r == 0);
return 1;
}
#endif

View File

@ -157,7 +157,9 @@ void coredump_cb(int sig, siginfo_t *si, void *context)
// backtrace
char bt[256];
int64_t len = 0;
#ifdef __x86_64__
safe_backtrace(bt, sizeof(bt) - 1, &len);
#endif
bt[len++] = '\0';
// extra
const ObFatalErrExtraInfoGuard *extra_info = nullptr; // TODO: May deadlock, ObFatalErrExtraInfoGuard::get_thd_local_val_ptr();

View File

@ -65,7 +65,9 @@ int ObSigBTOnlyProcessor::prepare()
int64_t count = 0;
count = safe_snprintf(buf_ + pos_, len - pos_, "tid: %ld, tname: %s, lbt: ", tid, tname);
pos_ += count;
#ifdef __x86_64__
safe_backtrace(buf_ + pos_, len - pos_, &count);
#endif
pos_ += count;
buf_[pos_++] = '\n';
return ret;

View File

@ -44,7 +44,9 @@ void crash_restore_handler(int sig, siginfo_t *s, void *p)
if (SIGSEGV == sig || SIGABRT == sig ||
SIGBUS == sig || SIGFPE == sig) {
int64_t len = 0;
#ifdef __x86_64__
safe_backtrace(crash_restore_buffer, 255, &len);
#endif
crash_restore_buffer[len++] = '\0';
siglongjmp(*g_jmp, 1);
} else {

View File

@ -33,6 +33,7 @@ bool g_inited = false;
int send_request_and_wait(ObSigRequestCode code, int exclude_tid)
{
int ret = OB_SUCCESS;
#ifdef __x86_64__
DTraceId trace_id = DTraceId::gen_trace_id();
DTraceIdGuard trace_guard(trace_id);
ObSigRequest req;
@ -93,6 +94,7 @@ int send_request_and_wait(ObSigRequestCode code, int exclude_tid)
}
}
}
#endif
return ret;
}