Files
oceanbase/deps/oblib/src/common/ob_store_range.h
wangzelin.wzl 93a1074b0c patch 4.0
2022-10-24 17:57:12 +08:00

314 lines
10 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.
*/
#ifndef OCEANBASE_COMMON_OB_STORE_RANGE_H_
#define OCEANBASE_COMMON_OB_STORE_RANGE_H_
#include <stdint.h>
#include "lib/oblog/ob_log.h"
#include "lib/ob_define.h"
#include "common/ob_range.h"
#include "common/rowkey/ob_store_rowkey.h"
namespace oceanbase
{
namespace common
{
// Only used in storage layer.
// No compare semantics except for the special whole_range is provided.
// Note that one cannot judge if an ObStoreRange object is empty based on that object alone
// because the comparison of the start_key_ and end_key_ of the range requires additional
// (column order) information.
class ObStoreRange
{
public:
ObStoreRange() { reset(); }
~ObStoreRange() { }
inline void reset()
{
table_id_ = OB_INVALID_ID;
border_flag_.set_data(0);
start_key_.reset();
end_key_.reset();
group_idx_ = 0;
}
inline void assign(const ObNewRange &range)
{
table_id_ = range.table_id_;
border_flag_ = range.border_flag_;
start_key_.get_rowkey() = range.start_key_;
end_key_.get_rowkey() = range.end_key_;
}
inline void to_new_range(ObNewRange &range) const
{
range.table_id_ = table_id_;
range.border_flag_ = border_flag_;
range.start_key_ = start_key_.get_rowkey();
range.end_key_ = end_key_.get_rowkey();
}
void change_boundary(const ObStoreRowkey &store_rowkey, bool is_reverse, bool exclusive = false);
uint64_t get_table_id() const { return table_id_; }
const ObBorderFlag& get_border_flag() const { return border_flag_; }
ObBorderFlag& get_border_flag() { return border_flag_; }
const ObStoreRowkey& get_start_key() const { return start_key_; }
ObStoreRowkey &get_start_key() { return start_key_; }
const ObStoreRowkey& get_end_key() const { return end_key_; }
ObStoreRowkey &get_end_key() { return end_key_; }
void set_table_id(uint64_t table_id) { table_id_ = table_id; }
void set_border_flag(ObBorderFlag flag) { border_flag_ = flag; }
void set_start_key(const ObStoreRowkey &start_key) { start_key_ = start_key; }
void set_end_key(const ObStoreRowkey &end_key) { end_key_ = end_key; }
void set_group_idx(const int64_t group_idx) { group_idx_ = group_idx; }
int64_t get_group_idx() const { return group_idx_; }
bool is_left_open() const { return !border_flag_.inclusive_start(); }
bool is_left_closed() const { return border_flag_.inclusive_start(); }
bool is_right_open() const { return !border_flag_.inclusive_end(); }
bool is_right_closed() const { return border_flag_.inclusive_end(); }
void set_left_open() { border_flag_.unset_inclusive_start(); }
void set_left_closed() { border_flag_.set_inclusive_start(); }
void set_right_open() { border_flag_.unset_inclusive_end(); }
void set_right_closed() { border_flag_.set_inclusive_end(); }
inline int build_range(uint64_t table_id, ObStoreRowkey store_rowkey);
// a valid ObStoreRange need NOT refer to a specific, valid table
inline bool is_valid() const
{
//return start_key_.is_valid() && end_key_.is_valid();
// FiXME-yangsuli: temporally using this to preserve semantics with ObNewRange
// eventually caller need to call empty() with the column order passed in
// or a simpler is_valid() check based on there need
return !empty();
}
inline int compare_with_startkey(const ObStoreRange &r, int &cmp) const;
// return true if the range is a single key value(but not min or max); false otherwise
inline bool is_single_rowkey() const;
int64_t to_plain_string(char *buffer, const int64_t length) const;
NEED_SERIALIZE_AND_DESERIALIZE;
int deserialize(ObIAllocator &allocator, const char *buf, const int64_t buf_len, int64_t &pos);
int deep_copy(ObIAllocator &allocator, ObStoreRange &dst) const;
inline int get_common_store_rowkey(ObStoreRowkey &store_rowkey) const;
TO_STRING_KV(K_(table_id), K_(border_flag), K_(start_key), K_(end_key));
private:
uint64_t table_id_;
ObBorderFlag border_flag_;
ObStoreRowkey start_key_;
ObStoreRowkey end_key_;
int64_t group_idx_;
//FIXME-yangsuli: remove interfaces below after changing code that calls below methods
//ObStoreRange should NOT provide compare semantics
public:
inline void set_whole_range();
inline bool is_whole_range() const
{
return (start_key_.is_min()) && (end_key_.is_max());
}
inline bool include(const ObStoreRange &r) const
{
return (table_id_ == r.table_id_)
&& (compare_with_startkey2(r) <= 0)
&& (compare_with_endkey2(r) >= 0);
}
inline int compare_with_endkey2(const ObStoreRange &r) const
{
int cmp = 0;
if (end_key_.is_max()) {
if (!r.end_key_.is_max()) {
cmp = 1;
}
} else if (r.end_key_.is_max()) {
cmp = -1;
} else {
cmp = end_key_.compare(r.end_key_);
if (0 == cmp) {
if (border_flag_.inclusive_end() && !r.border_flag_.inclusive_end()) {
cmp = 1;
} else if (!border_flag_.inclusive_end() && r.border_flag_.inclusive_end()) {
cmp = -1;
}
}
}
return cmp;
}
inline int compare_with_startkey2(const ObStoreRange &r) const
{
int cmp = 0;
if (start_key_.is_min()) {
if (!r.start_key_.is_min()) {
cmp = -1;
}
} else if (r.start_key_.is_min()) {
cmp = 1;
} else {
cmp = start_key_.compare(r.start_key_);
if (0 == cmp) {
if (border_flag_.inclusive_start() && !r.border_flag_.inclusive_start()) {
cmp = -1;
} else if (!border_flag_.inclusive_start() && r.border_flag_.inclusive_start()) {
cmp = 1;
}
}
}
return cmp;
}
inline bool empty() const
{
bool ret = false;
if (start_key_.is_min() || end_key_.is_max()) {
ret = false;
} else {
const int32_t result = end_key_.compare(start_key_);
ret = result < 0
|| ((0 == result)
&& !((border_flag_.inclusive_end())
&& border_flag_.inclusive_start()));
}
return ret;
}
friend int deep_copy_range(ObIAllocator &allocator, const ObStoreRange &src, ObStoreRange *&dst);
};
int ObStoreRange::build_range(uint64_t table_id, ObStoreRowkey store_rowkey)
{
int ret = OB_SUCCESS;
if (OB_INVALID_ID == table_id || !store_rowkey.is_valid()) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid arguments.", K(table_id), K(store_rowkey), K(ret));
} else {
table_id_ = table_id;
start_key_ = store_rowkey;
end_key_ = store_rowkey;
border_flag_.set_inclusive_start();
border_flag_.set_inclusive_end();
}
return ret;
}
int ObStoreRange::compare_with_startkey(const ObStoreRange &r, int &cmp) const
{
int ret = OB_SUCCESS;
if (0 != (cmp = start_key_.compare(r.start_key_))) {
// do nothing
} else if (border_flag_.inclusive_start() && !r.border_flag_.inclusive_start()) {
cmp = -1;
} else if (!border_flag_.inclusive_start() && r.border_flag_.inclusive_start()) {
cmp = 1;
}
return ret;
}
void ObStoreRange::set_whole_range()
{
start_key_.set_min();
end_key_.set_max();
border_flag_.unset_inclusive_start();
border_flag_.unset_inclusive_end();
}
bool ObStoreRange::is_single_rowkey() const
{
int ret = true;
if (!start_key_.simple_equal(end_key_)) {
ret = false;
} else if (!border_flag_.inclusive_start() || !border_flag_.inclusive_end()) {
ret = false;
} else if (start_key_.contains_min_or_max_obj()) {
ret = false;
}
return ret;
}
int ObStoreRange::get_common_store_rowkey(ObStoreRowkey &store_rowkey) const
{
int ret = OB_SUCCESS;
int64_t prefix_len = 0;
if (OB_FAIL(ObStoreRowkey::get_common_prefix_length(start_key_, end_key_, prefix_len))) {
COMMON_LOG(WARN, "fail to get common prefix length", K(ret));
} else if (prefix_len > 0) {
ret = store_rowkey.assign(const_cast<ObObj *>(start_key_.get_obj_ptr()), prefix_len);
}
return ret;
}
//FIXME-yangsuli: remove this method later
inline int deep_copy_range(ObIAllocator &allocator, const ObStoreRange &src, ObStoreRange *&dst)
{
int ret = OB_SUCCESS;
void *ptr = NULL;
if (NULL == (ptr = allocator.alloc(sizeof(ObStoreRange)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
COMMON_LOG(ERROR, "allocate new range failed", K(ret));
} else {
dst = new(ptr) ObStoreRange();
if (OB_FAIL(src.start_key_.deep_copy(dst->start_key_, allocator))) {
COMMON_LOG(WARN, "deep copy start key failed.", K(src.start_key_), K(ret));
} else if (OB_FAIL(src.end_key_.deep_copy(dst->end_key_, allocator))) {
COMMON_LOG(WARN, "deep copy end key failed.", K(src.end_key_), K(ret));
} else {
dst->table_id_ = src.table_id_;
dst->border_flag_ = src.border_flag_;
}
if (OB_FAIL(ret) && NULL != ptr) {
allocator.free(ptr);
ptr = NULL;
}
}
return ret;
}
class ObVersionStoreRangeConversionHelper
{
public:
static int store_rowkey_to_multi_version_range(const ObStoreRowkey &src_rowkey,
const ObVersionRange &version_range,
ObIAllocator &allocator,
ObStoreRange &multi_version_range);
static int range_to_multi_version_range(const ObStoreRange &src_range,
const ObVersionRange &version_range,
ObIAllocator &allocator,
ObStoreRange &multi_version_range);
private:
static int build_multi_version_store_rowkey(const ObStoreRowkey &rowkey,
const bool min_value,
ObIAllocator &allocator,
ObStoreRowkey &multi_version_rowkey);
};
} //end namespace common
} //end namespace oceanbase
#endif //OCEANBASE_COMMON_OB_STORE_RANGE_H_