add tableapi to opensource release

This commit is contained in:
xj0
2021-08-11 19:24:11 +08:00
committed by wangzelin.wzl
parent 7c05e32506
commit 895f700d99
31 changed files with 10203 additions and 3 deletions

658
src/share/table/ob_table.h Normal file
View File

@ -0,0 +1,658 @@
/**
* 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 _OB_TABLE_TABLE_H
#define _OB_TABLE_TABLE_H 1
#include "lib/ob_define.h"
#include "lib/ob_errno.h"
#include "lib/string/ob_string.h"
#include "common/object/ob_object.h"
#include "common/rowkey/ob_rowkey.h"
#include "lib/container/ob_iarray.h"
#include "lib/container/ob_se_array.h"
#include "lib/hash/ob_hashmap.h"
#include "lib/list/ob_dlist.h"
#include "common/ob_common_types.h"
#include "common/ob_range.h"
namespace oceanbase
{
namespace common
{
class ObNewRow;
}
namespace table
{
using common::ObString;
using common::ObRowkey;
using common::ObObj;
using common::ObIArray;
using common::ObSEArray;
////////////////////////////////////////////////////////////////
// structs of a table storage interface
////////////////////////////////////////////////////////////////
/// A Table Entity
class ObITableEntity: public common::ObDLinkBase<ObITableEntity>
{
OB_UNIS_VERSION_V(1);
public:
ObITableEntity()
:alloc_(NULL)
{}
virtual ~ObITableEntity() = default;
virtual void reset() = 0;
virtual bool is_empty() const { return 0 == get_rowkey_size() && 0 == get_properties_count(); }
//@{ primary key contains partition key. Note that all values are shallow copy.
virtual int set_rowkey(const ObRowkey &rowkey) = 0;
virtual int set_rowkey(const ObITableEntity &other) = 0;
virtual int set_rowkey_value(int64_t idx, const ObObj &value) = 0;
virtual int add_rowkey_value(const ObObj &value) = 0;
virtual int64_t get_rowkey_size() const = 0;
virtual int get_rowkey_value(int64_t idx, ObObj &value) const = 0;
virtual ObRowkey get_rowkey() = 0;
virtual int64_t hash_rowkey() const = 0;
//@}
//@{ property is a key-value pair.
virtual int set_property(const ObString &prop_name, const ObObj &prop_value) = 0;
virtual int get_property(const ObString &prop_name, ObObj &prop_value) const = 0;
virtual int get_properties(ObIArray<std::pair<ObString, ObObj> > &properties) const = 0; // @todo property iterator
virtual int get_properties_names(ObIArray<ObString> &properties) const = 0;
virtual int get_properties_values(ObIArray<ObObj> &properties_values) const = 0;
virtual int64_t get_properties_count() const = 0;
//@}
virtual int deep_copy(common::ObIAllocator &allocator, const ObITableEntity &other);
int deep_copy_rowkey(common::ObIAllocator &allocator, const ObITableEntity &other);
int deep_copy_properties(common::ObIAllocator &allocator, const ObITableEntity &other);
virtual int add_retrieve_property(const ObString &prop_name);
void set_allocator(common::ObIAllocator *alloc) { alloc_ = alloc; }
common::ObIAllocator *get_allocator() { return alloc_; }
VIRTUAL_TO_STRING_KV("ITableEntity", "");
protected:
common::ObIAllocator *alloc_; // for deep copy in deserialize
};
class ObITableEntityFactory
{
public:
virtual ~ObITableEntityFactory() = default;
virtual ObITableEntity *alloc() = 0;
virtual void free(ObITableEntity *obj) = 0;
virtual void free_and_reuse() = 0;
virtual int64_t get_used_count() const = 0;
virtual int64_t get_free_count() const = 0;
virtual int64_t get_used_mem() const = 0;
virtual int64_t get_total_mem() const = 0;
};
/// An implementation for ObITableEntity
class ObTableEntity: public ObITableEntity
{
public:
ObTableEntity();
~ObTableEntity();
virtual int set_rowkey(const ObRowkey &rowkey) override;
virtual int set_rowkey(const ObITableEntity &other) override;
virtual int set_rowkey_value(int64_t idx, const ObObj &value) override;
virtual int add_rowkey_value(const ObObj &value) override;
virtual int64_t get_rowkey_size() const override { return rowkey_.count(); };
virtual int get_rowkey_value(int64_t idx, ObObj &value) const override;
virtual int64_t hash_rowkey() const override;
virtual int get_property(const ObString &prop_name, ObObj &prop_value) const override;
virtual int set_property(const ObString &prop_name, const ObObj &prop_value) override;
virtual int get_properties(ObIArray<std::pair<ObString, ObObj> > &properties) const override;
virtual int get_properties_names(ObIArray<ObString> &properties_names) const override;
virtual int get_properties_values(ObIArray<ObObj> &properties_values) const override;
virtual int64_t get_properties_count() const override;
virtual void reset() override { rowkey_.reset(); properties_.clear(); }
virtual ObRowkey get_rowkey() override;
DECLARE_TO_STRING;
private:
int try_init();
class GetPropertyFn;
class GetPropertyNameFn;
class GetPropertyValueFn;
typedef common::hash::ObHashMap<ObString, ObObj, common::hash::NoPthreadDefendMode> PropertiesMap;
private:
ObSEArray<ObObj, 8> rowkey_;
PropertiesMap properties_;
};
enum class ObTableEntityType
{
ET_DYNAMIC = 0,
ET_KV = 1
};
// @note not thread-safe
template <typename T>
class ObTableEntityFactory: public ObITableEntityFactory
{
public:
ObTableEntityFactory(const char *label = common::ObModIds::TABLE_PROC)
:alloc_(label)
{}
virtual ~ObTableEntityFactory();
virtual ObITableEntity *alloc() override;
virtual void free(ObITableEntity *obj) override;
virtual void free_and_reuse() override;
virtual int64_t get_free_count() const { return free_list_.get_size(); }
virtual int64_t get_used_count() const { return used_list_.get_size(); }
virtual int64_t get_used_mem() const { return alloc_.used(); }
virtual int64_t get_total_mem() const { return alloc_.total(); }
private:
void free_all();
private:
common::ObArenaAllocator alloc_;
common::ObDList<ObITableEntity> used_list_;
common::ObDList<ObITableEntity> free_list_;
};
template <typename T>
ObTableEntityFactory<T>::~ObTableEntityFactory()
{
free_all();
}
template <typename T>
ObITableEntity *ObTableEntityFactory<T>::alloc()
{
ObITableEntity *entity = free_list_.remove_first();
if (NULL == entity) {
void * ptr = alloc_.alloc(sizeof(T));
if (NULL == ptr) {
CLIENT_LOG(WARN, "no memory for table entity");
} else {
entity = new(ptr) T();
used_list_.add_last(entity);
}
} else {
used_list_.add_last(entity);
}
return entity;
}
template <typename T>
void ObTableEntityFactory<T>::free(ObITableEntity *entity)
{
if (NULL != entity) {
entity->reset();
entity->set_allocator(NULL);
used_list_.remove(entity);
free_list_.add_last(entity);
}
}
template <typename T>
void ObTableEntityFactory<T>::free_and_reuse()
{
while (!used_list_.is_empty()) {
this->free(used_list_.get_first());
}
}
template <typename T>
void ObTableEntityFactory<T>::free_all()
{
ObITableEntity *entity = NULL;
while (NULL != (entity = used_list_.remove_first())) {
entity->~ObITableEntity();
}
while (NULL != (entity = free_list_.remove_first())) {
entity->~ObITableEntity();
}
}
/// Table Operation Type
struct ObTableOperationType
{
enum Type
{
GET = 0,
INSERT = 1,
DEL = 2,
UPDATE = 3,
INSERT_OR_UPDATE = 4,
REPLACE = 5,
INCREMENT = 6,
APPEND = 7
};
};
/// A table operation
class ObTableOperation
{
OB_UNIS_VERSION(1);
public:
/**
* insert the entity.
* @return ObTableOperationResult
* In the case of insert success, the return errno is OB_SUCCESS, affected_rows is 1
* In the case of insert failed, the affected_rows is 0
* In the case of insert failed caused by primary key duplicated, the errno is OB_ERR_PRIMARY_KEY_DUPLICATE.
* If the option returning_affected_rows is false (default value), then the return value of affected_rows is undefined, but with better performance.
* Other common error code: OB_TIMEOUT indicates time out; OB_TRY_LOCK_ROW_CONFLICT indicate row lock conflict
*/
static ObTableOperation insert(const ObITableEntity &entity);
/**
* delete the entity.
* @return ObTableOperationResult
* In the case of delete success, the errno is OB_SUCCESS and the affeceted_row is 1.
* In the case of the row is NOT EXIST, the errno is OB_SUCCESS and the affected_row is 0.
* If the option returning_affected_rows is false (default value), then the return value of affected_rows is undefined, but with better performance.
* Other common error code: OB_TIMEOUT indicates time out; OB_TRY_LOCK_ROW_CONFLICT indicate row lock conflict
*/
static ObTableOperation del(const ObITableEntity &entity);
/**
* update the entity.
* @return ObTableOperationResult
* In the case of update success, the errno is OB_SUCCESS and the affeceted_row is 1.
* In the case of the row is NOT EXIST, the errno is OB_SUCCESS and the affected_row is 0.
* If the option returning_affected_rows is false (default value), then the return value of affected_rows is undefined, but with better performance.
* Other common error code: OB_TIMEOUT indicates time out; OB_TRY_LOCK_ROW_CONFLICT indicate row lock conflict
*/
static ObTableOperation update(const ObITableEntity &entity);
/**
* insert_or_update the entity.
* @return ObTableOperationResult
* If the row is NOT exist, then insert the row. In the case of success, the return errno is OB_SUCCESS and the affected_rows is 1.
* If the row is exist, then update the row. In the case of success, the return errno is OB_SUCCESS and the affected_rows i 1.
* If the option returning_affected_rows is false (default value), then the return value of affected_rows is undefined, but with better performance.
* Other common error code: OB_TIMEOUT; OB_TRY_LOCK_ROW_CONFLICT
*/
static ObTableOperation insert_or_update(const ObITableEntity &entity);
/**
* replace the entity.
* @return ObTableOperationResult
* If the row is NOT EXIST, then insert the row. In the case of success,
* the errno is OB_SUCCESS and the affected_row is 1.
* Otherwise the row is EXIST, then delete the old row and insert the new row. In the case of success,
* the errno is OB_SUCCESS and the affected_row is 1.
* Specially, if there is uniq index conflict, then delete all rows cause conflict and insert the new row.
* In the case of success, the errno is OB_SUCCESS and the affected_row >= 1.
* If the option returning_affected_rows is false (default value), then the return value of affected_rows is undefined, but with better performance.
* Other common error code: OB_TIMEOUT; OB_TRY_LOCK_ROW_CONFLICT
*/
static ObTableOperation replace(const ObITableEntity &entity);
/**
* retrieve the entity.
* @param entity Only return the given property
* @return ObTableOperationResult
* affected_rows is always 0
* If the row is exist, then return the ObTableOperationResult.entity
* Otherwise, entity is empty.
* Other common error code: OB_TIMEOUT
*/
static ObTableOperation retrieve(const ObITableEntity &entity);
/**
* Increase the value of given column.
* The type of the column MUST be integer.
* If the original value of given column is NULL, use the new value to replace it.
*/
static ObTableOperation increment(const ObITableEntity &entity);
/**
* Append the given string to original string.
* The type of the column MUST be string type, such as char, varchar, binary, varbinary or lob.
* If the original value of given column is NULL, use the new value to replace it.
*/
static ObTableOperation append(const ObITableEntity &entity);
public:
const ObITableEntity &entity() const { return *entity_; }
ObTableOperationType::Type type() const { return operation_type_; }
void set_entity(const ObITableEntity &entity) { entity_ = &entity; }
void set_type(ObTableOperationType::Type op_type) { operation_type_ = op_type; }
int get_entity(ObITableEntity *&entity);
uint64_t get_checksum();
TO_STRING_KV(K_(operation_type), "entity", to_cstring(entity_));
private:
const ObITableEntity *entity_;
ObTableOperationType::Type operation_type_;
};
/// common result for ObTable
class ObTableResult
{
OB_UNIS_VERSION(1);
public:
ObTableResult()
:errno_(common::OB_ERR_UNEXPECTED)
{
sqlstate_[0] = '\0';
msg_[0] = '\0';
}
~ObTableResult() = default;
void set_errno(int err) { errno_ = err; }
int get_errno() const { return errno_; }
int assign(const ObTableResult &other);
TO_STRING_KV(K_(errno));
private:
static const int64_t MAX_MSG_SIZE = common::OB_MAX_ERROR_MSG_LEN;
protected:
int32_t errno_;
char sqlstate_[6]; // terminate with '\0'
char msg_[MAX_MSG_SIZE]; // terminate with '\0'
};
/// result for ObTableOperation
class ObTableOperationResult final: public ObTableResult
{
OB_UNIS_VERSION(1);
public:
ObTableOperationResult();
~ObTableOperationResult() = default;
ObTableOperationType::Type type() const { return operation_type_; }
int get_entity(const ObITableEntity *&entity) const;
int get_entity(ObITableEntity *&entity);
int64_t get_affected_rows() const { return affected_rows_; }
void set_entity(ObITableEntity &entity) { entity_ = &entity; }
void set_type(ObTableOperationType::Type op_type) { operation_type_ = op_type; }
void set_affected_rows(int64_t affected_rows) { affected_rows_ = affected_rows; }
int deep_copy(common::ObIAllocator &allocator, ObITableEntityFactory &entity_factory, const ObTableOperationResult &other);
DECLARE_TO_STRING;
private:
ObTableOperationType::Type operation_type_;
ObITableEntity *entity_;
int64_t affected_rows_;
};
class ObIRetryPolicy
{
public:
virtual bool need_retry(int32_t curr_retry_count, int last_errno, int64_t &retry_interval)
{
UNUSEDx(curr_retry_count, last_errno, retry_interval);
return false;
}
};
class ObLinearRetry : public ObIRetryPolicy
{};
class ObExponentialRetry : public ObIRetryPolicy
{};
class ObNoRetry : public ObIRetryPolicy
{};
/// consistency levels
/// @see https://www.atatech.org/articles/102030
enum class ObTableConsistencyLevel
{
STRONG = 0,
EVENTUAL = 1,
};
/// clog row image type
/// @see share::ObBinlogRowImage
enum class ObBinlogRowImageType
{
MINIMAL = 0,
NOBLOB = 1,
FULL = 2,
};
/// request options for all the table operations
class ObTableRequestOptions final
{
public:
ObTableRequestOptions();
~ObTableRequestOptions() = default;
void set_consistency_level(ObTableConsistencyLevel consistency_level) { consistency_level_ = consistency_level; }
ObTableConsistencyLevel consistency_level() const { return consistency_level_; }
void set_server_timeout(int64_t server_timeout_us) { server_timeout_us_ = server_timeout_us; }
int64_t server_timeout() const { return server_timeout_us_; }
void set_execution_time(int64_t max_execution_time_us) { max_execution_time_us_ = max_execution_time_us; }
int64_t max_execution_time() const { return max_execution_time_us_; }
void set_retry_policy(ObIRetryPolicy *retry_policy) { retry_policy_ = retry_policy; }
ObIRetryPolicy* retry_policy() { return retry_policy_; }
void set_returning_affected_rows(bool returning) { returning_affected_rows_ = returning; }
bool returning_affected_rows() const { return returning_affected_rows_; }
void set_returning_rowkey(bool returning) { returning_rowkey_ = returning; }
bool returning_rowkey() const { return returning_rowkey_; }
void set_returning_affected_entity(bool returning) { returning_affected_entity_ = returning; }
bool returning_affected_entity() const { return returning_affected_entity_; }
void set_binlog_row_image_type(ObBinlogRowImageType type) { binlog_row_image_type_ = type; }
ObBinlogRowImageType binlog_row_image_type() const { return binlog_row_image_type_; }
private:
ObTableConsistencyLevel consistency_level_;
int64_t server_timeout_us_;
int64_t max_execution_time_us_;
ObIRetryPolicy *retry_policy_;
bool returning_affected_rows_; // default: false
bool returning_rowkey_; // default: false
bool returning_affected_entity_; // default: false
// bool batch_operation_as_atomic_; // default: false
// int route_policy
ObBinlogRowImageType binlog_row_image_type_; // default: FULL
};
/// A batch operation
class ObTableBatchOperation
{
OB_UNIS_VERSION(1);
public:
static const int64_t MAX_BATCH_SIZE = 1000;
static const int64_t COMMON_BATCH_SIZE = 8;
public:
ObTableBatchOperation()
:table_operations_(common::ObModIds::TABLE_BATCH_OPERATION, common::OB_MALLOC_NORMAL_BLOCK_SIZE),
is_readonly_(true),
is_same_type_(true),
is_same_properties_names_(true),
entity_factory_(NULL)
{}
~ObTableBatchOperation() = default;
void reset();
void set_entity_factory(ObITableEntityFactory *entity_factory) { entity_factory_ = entity_factory; }
/// insert the entity if not exists
int insert(const ObITableEntity &entity);
/// delete the entity if exists
int del(const ObITableEntity &entity);
/// update the entity if exists
int update(const ObITableEntity &entity);
/// insert the entity if not exists, otherwise update it
int insert_or_update(const ObITableEntity &entity);
/// insert the entity if not exists, otherwise replace it
int replace(const ObITableEntity &entity);
/// get the entity if exists
int retrieve(const ObITableEntity &entity);
/// add one table operation
int add(const ObTableOperation &table_operation);
/// increment the value
int increment(const ObITableEntity &entity);
/// append to the value
int append(const ObITableEntity &entity);
int64_t count() const { return table_operations_.count(); }
const ObTableOperation &at(int64_t idx) const { return table_operations_.at(idx); }
bool is_readonly() const { return is_readonly_; }
bool is_same_type() const { return is_same_type_; }
bool is_same_properties_names() const { return is_same_properties_names_; }
uint64_t get_checksum();
TO_STRING_KV(K_(is_readonly),
K_(is_same_type),
K_(is_same_properties_names),
"operatiton_count", table_operations_.count(),
K_(table_operations));
private:
ObSEArray<ObTableOperation, COMMON_BATCH_SIZE> table_operations_;
bool is_readonly_;
bool is_same_type_;
bool is_same_properties_names_;
// do not serialize
ObITableEntityFactory *entity_factory_;
};
/// result for ObTableBatchOperation
typedef ObIArray<ObTableOperationResult> ObITableBatchOperationResult;
class ObTableBatchOperationResult: public common::ObSEArrayImpl<ObTableOperationResult, ObTableBatchOperation::COMMON_BATCH_SIZE>
{
OB_UNIS_VERSION(1);
public:
ObTableBatchOperationResult()
:BaseType(common::ObModIds::TABLE_BATCH_OPERATION_RESULT, common::OB_MALLOC_NORMAL_BLOCK_SIZE),
entity_factory_(NULL),
alloc_(NULL)
{}
virtual ~ObTableBatchOperationResult() = default;
void set_entity_factory(ObITableEntityFactory *entity_factory) { entity_factory_ = entity_factory; }
ObITableEntityFactory *get_entity_factory() { return entity_factory_; }
void set_allocator(common::ObIAllocator *alloc) { alloc_ = alloc; }
common::ObIAllocator *get_allocator() { return alloc_; }
private:
typedef common::ObSEArrayImpl<ObTableOperationResult, ObTableBatchOperation::COMMON_BATCH_SIZE> BaseType;
ObITableEntityFactory *entity_factory_;
common::ObIAllocator *alloc_;
};
/// A table query
/// 1. support multi range scan
/// 2. support reverse scan
/// 3. support secondary index scan
class ObTableQuery final
{
OB_UNIS_VERSION(1);
public:
ObTableQuery()
:deserialize_allocator_(NULL),
key_ranges_(),
select_columns_(),
filter_string_(),
limit_(-1),
offset_(0),
scan_order_(common::ObQueryFlag::Forward),
index_name_(),
batch_size_(-1),
max_result_size_(-1)
{}
~ObTableQuery() = default;
void reset();
bool is_valid() const;
/// add a scan range, the number of scan ranges should be >=1.
int add_scan_range(common::ObNewRange &scan_range);
/// Scan order: Forward (By default) and Reverse.
int set_scan_order(common::ObQueryFlag::ScanOrder scan_order);
/// Set the index to scan, could be 'PRIMARY' (by default) or any other secondary index.
int set_scan_index(const ObString &index_name);
/// Add select columns.
int add_select_column(const ObString &columns);
/// Set the max rows to return. The value of -1 represents there is NO limit. The default value is -1.
/// For htable, set the limit of htable rows for this scan.
int set_limit(int32_t limit);
/// Set the offset to return. The default value is 0.
int set_offset(int32_t offset);
/// Add filter, currently NOT supported.
int set_filter(const ObString &filter);
/// Set max row count of each batch.
/// For htable, set the maximum number of cells to return for each call to next().
int set_batch(int32_t batch_size);
/// Set the maximum result size.
/// The default is -1; this means that no specific maximum result size will be set for this query.
/// @param max_result_size - The maximum result size in bytes.
int set_max_result_size(int64_t max_result_size);
const ObIArray<ObString> &get_select_columns() const { return select_columns_; }
const ObIArray<common::ObNewRange> &get_scan_ranges() const { return key_ranges_; }
int32_t get_limit() const { return limit_; }
int32_t get_offset() const { return offset_; }
common::ObQueryFlag::ScanOrder get_scan_order() const { return scan_order_; }
const ObString &get_index_name() const { return index_name_; }
int32_t get_batch() const { return batch_size_; }
int64_t get_max_result_size() const { return max_result_size_; }
int64_t get_range_count() const { return key_ranges_.count(); }
uint64_t get_checksum() const;
void clear_scan_range() { key_ranges_.reset(); }
void set_deserialize_allocator(common::ObIAllocator *allocator) { deserialize_allocator_ = allocator; }
TO_STRING_KV(K_(key_ranges),
K_(select_columns),
K_(filter_string),
K_(limit),
K_(offset),
K_(scan_order),
K_(index_name),
K_(batch_size),
K_(max_result_size));
public:
static ObString generate_filter_condition(const ObString &column, const ObString &op, const ObObj &value);
static ObString combile_filters(const ObString &filter1, const ObString &op, const ObString &filter2);
static common::ObNewRange generate_prefix_scan_range(const ObRowkey &rowkey_prefix);
private:
common::ObIAllocator *deserialize_allocator_;
ObSEArray<common::ObNewRange, 16> key_ranges_;
ObSEArray<ObString, 16> select_columns_;
ObString filter_string_;
int32_t limit_; // default -1 means unlimited
int32_t offset_;
common::ObQueryFlag::ScanOrder scan_order_;
ObString index_name_;
int32_t batch_size_;
int64_t max_result_size_;
};
/// result for ObTableQuery
class ObTableEntityIterator
{
public:
ObTableEntityIterator() = default;
virtual ~ObTableEntityIterator();
/**
* fetch the next entity
* @return OB_ITER_END when finished
*/
virtual int get_next_entity(const ObITableEntity *&entity) = 0;
};
class ObTableQueryResult: public ObTableEntityIterator
{
OB_UNIS_VERSION(1);
public:
ObTableQueryResult();
virtual ~ObTableQueryResult() {}
void reset();
void reset_except_property();
void rewind();
virtual int get_next_entity(const ObITableEntity *&entity) override;
int add_property_name(const ObString &name);
int add_row(const common::ObNewRow &row);
int add_all_property(const ObTableQueryResult &other);
int add_all_row(const ObTableQueryResult &other);
int64_t get_row_count() const { return row_count_; }
int64_t get_property_count() const { return properties_names_.count(); }
int64_t get_result_size();
int get_first_row(common::ObNewRow &row) const;
bool reach_batch_size_or_result_size(const int32_t batch_count,
const int64_t max_result_size);
private:
static const int64_t MAX_BUF_BLOCK_SIZE = common::OB_MAX_PACKET_BUFFER_LENGTH - (1024*1024LL);
static const int64_t DEFAULT_BUF_BLOCK_SIZE = common::OB_MALLOC_BIG_BLOCK_SIZE - (1024*1024LL);
int alloc_buf_if_need(const int64_t size);
private:
common::ObSEArray<ObString, 16> properties_names_; // serialize
int64_t row_count_; // serialize
common::ObDataBuffer buf_; // serialize
common::ObArenaAllocator allocator_;
int64_t fixed_result_size_;
// for deserialize and read
int64_t curr_idx_;
ObTableEntity curr_entity_;
};
} // end namespace table
} // end namespace oceanbase
#endif /* _OB_TABLE_TABLE_H */