321 lines
13 KiB
C++
321 lines
13 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_SRC_SHARE_SCHEMA_OB_ROUTINE_MGR_H_
|
|
#define OCEANBASE_SRC_SHARE_SCHEMA_OB_ROUTINE_MGR_H_
|
|
|
|
#include "share/ob_define.h"
|
|
#include "lib/hash/ob_pointer_hashmap.h"
|
|
#include "lib/container/ob_vector.h"
|
|
#include "lib/allocator/page_arena.h"
|
|
#include "ob_routine_info.h"
|
|
namespace oceanbase
|
|
{
|
|
namespace share
|
|
{
|
|
namespace schema
|
|
{
|
|
struct ObTenantRoutineId
|
|
{
|
|
public:
|
|
ObTenantRoutineId()
|
|
: tenant_id_(common::OB_INVALID_ID),
|
|
routine_id_(common::OB_INVALID_ID) {}
|
|
ObTenantRoutineId(uint64_t tenant_id, uint64_t routine_id)
|
|
: tenant_id_(tenant_id),
|
|
routine_id_(routine_id) {}
|
|
ObTenantRoutineId(const ObTenantRoutineId &other)
|
|
: tenant_id_(other.tenant_id_),
|
|
routine_id_(other.routine_id_) {}
|
|
ObTenantRoutineId &operator =(const ObTenantRoutineId &other)
|
|
{
|
|
tenant_id_ = other.tenant_id_;
|
|
routine_id_ = other.routine_id_;
|
|
return *this;
|
|
}
|
|
bool operator ==(const ObTenantRoutineId &rhs) const
|
|
{
|
|
return (tenant_id_ == rhs.tenant_id_)
|
|
&& (routine_id_ == rhs.routine_id_);
|
|
}
|
|
bool operator !=(const ObTenantRoutineId &rhs) const
|
|
{
|
|
return !(*this == rhs);
|
|
}
|
|
bool operator <(const ObTenantRoutineId &rhs) const
|
|
{
|
|
bool bret = tenant_id_ < rhs.tenant_id_;
|
|
if (tenant_id_ == rhs.tenant_id_) {
|
|
bret = routine_id_ < rhs.routine_id_;
|
|
}
|
|
return bret;
|
|
}
|
|
inline uint64_t hash() const
|
|
{
|
|
uint64_t hash_ret = 0;
|
|
hash_ret = common::murmurhash(&tenant_id_, sizeof(tenant_id_), 0);
|
|
hash_ret = common::murmurhash(&routine_id_, sizeof(routine_id_), hash_ret);
|
|
return hash_ret;
|
|
}
|
|
bool is_valid() const
|
|
{
|
|
return (tenant_id_ != common::OB_INVALID_ID)
|
|
&& (routine_id_ != common::OB_INVALID_ID);
|
|
}
|
|
inline uint64_t get_tenant_id() const { return tenant_id_; }
|
|
inline uint64_t get_routine_id() const { return routine_id_; }
|
|
TO_STRING_KV(K_(tenant_id), K_(routine_id));
|
|
private:
|
|
uint64_t tenant_id_;
|
|
uint64_t routine_id_;
|
|
};
|
|
|
|
class ObSimpleRoutineSchema : public ObSchema
|
|
{
|
|
public:
|
|
ObSimpleRoutineSchema();
|
|
explicit ObSimpleRoutineSchema(common::ObIAllocator *allocator);
|
|
ObSimpleRoutineSchema(const ObSimpleRoutineSchema &src_schema);
|
|
virtual ~ObSimpleRoutineSchema();
|
|
ObSimpleRoutineSchema &operator =(const ObSimpleRoutineSchema &other);
|
|
bool operator ==(const ObSimpleRoutineSchema &other) const;
|
|
void reset()
|
|
{
|
|
tenant_id_ = common::OB_INVALID_ID;
|
|
database_id_ = common::OB_INVALID_ID;
|
|
package_id_ = common::OB_INVALID_ID;
|
|
routine_id_ = common::OB_INVALID_ID;
|
|
reset_string(routine_name_);
|
|
schema_version_ = common::OB_INVALID_VERSION;
|
|
routine_type_ = INVALID_ROUTINE_TYPE;
|
|
overload_ = common::OB_INVALID_INDEX;
|
|
ObSchema::reset();
|
|
}
|
|
int64_t get_convert_size() const;
|
|
bool is_valid() const
|
|
{
|
|
return (common::OB_INVALID_ID != tenant_id_
|
|
&& common::OB_INVALID_ID != database_id_
|
|
&& common::OB_INVALID_ID != routine_id_
|
|
&& !routine_name_.empty()
|
|
&& common::OB_INVALID_INDEX != overload_
|
|
&& INVALID_ROUTINE_TYPE != routine_type_
|
|
&& schema_version_ >= 0);
|
|
}
|
|
inline void set_tenant_id(uint64_t tenant_id) { tenant_id_ = tenant_id; }
|
|
inline uint64_t get_tenant_id() const { return tenant_id_; }
|
|
inline void set_routine_id(uint64_t routine_id) { routine_id_ = routine_id; }
|
|
inline uint64_t get_routine_id() const { return routine_id_; }
|
|
inline void set_package_id(uint64_t package_id) { package_id_ = package_id; }
|
|
inline uint64_t get_package_id() const { return package_id_; }
|
|
inline void set_schema_version(const int64_t schema_version) { schema_version_ = schema_version; }
|
|
inline int64_t get_schema_version() const { return schema_version_; }
|
|
inline void set_database_id(const uint64_t database_id) { database_id_ = database_id; }
|
|
inline uint64_t get_database_id() const { return database_id_; }
|
|
inline void set_overload(const uint64_t overload) { overload_ = overload; }
|
|
inline uint64_t get_overload() const { return overload_; }
|
|
inline int set_routine_name(const common::ObString &routine_name)
|
|
{ return deep_copy_str(routine_name, routine_name_); }
|
|
inline const common::ObString &get_routine_name() const { return routine_name_; }
|
|
inline ObTenantRoutineId get_routine_key() const
|
|
{ return ObTenantRoutineId(tenant_id_, routine_id_); }
|
|
ObRoutineType get_routine_type() const { return routine_type_; }
|
|
void set_routine_type(ObRoutineType routine_type) { routine_type_ = routine_type; }
|
|
TO_STRING_KV(K_(tenant_id),
|
|
K_(database_id),
|
|
K_(package_id),
|
|
K_(routine_id),
|
|
K_(routine_name),
|
|
K_(routine_type),
|
|
K_(overload),
|
|
K_(schema_version));
|
|
private:
|
|
uint64_t tenant_id_;
|
|
uint64_t database_id_;
|
|
uint64_t package_id_;
|
|
uint64_t routine_id_;
|
|
common::ObString routine_name_;
|
|
ObRoutineType routine_type_;
|
|
uint64_t overload_;
|
|
int64_t schema_version_;
|
|
};
|
|
|
|
class ObRoutineNameHashWrapper
|
|
{
|
|
public:
|
|
ObRoutineNameHashWrapper()
|
|
: tenant_id_(common::OB_INVALID_ID),
|
|
database_id_(common::OB_INVALID_ID),
|
|
package_id_(common::OB_INVALID_ID),
|
|
overload_(common::OB_INVALID_INDEX),
|
|
routine_type_(INVALID_ROUTINE_TYPE) {}
|
|
ObRoutineNameHashWrapper(uint64_t tenant_id, uint64_t database_id, uint64_t package_id,
|
|
const common::ObString &routine_name, uint64_t overload, ObRoutineType routine_type)
|
|
: tenant_id_(tenant_id),
|
|
database_id_(database_id),
|
|
package_id_(package_id),
|
|
routine_name_(routine_name),
|
|
overload_(overload),
|
|
routine_type_(routine_type) {}
|
|
~ObRoutineNameHashWrapper() {}
|
|
inline uint64_t hash() const;
|
|
inline bool operator ==(const ObRoutineNameHashWrapper &rv) const;
|
|
inline void set_tenant_id(uint64_t tenant_id) { tenant_id_ = tenant_id; }
|
|
inline void set_database_id(uint64_t database_id) { database_id_ = database_id; }
|
|
inline void set_package_id(uint64_t package_id) { package_id_ = package_id; }
|
|
inline void set_routine_name(const common::ObString &routine_name) { routine_name_ = routine_name; }
|
|
inline void set_overload(uint64_t overload) { overload_ = overload; }
|
|
inline void set_routine_type(ObRoutineType routine_type) { routine_type_ = routine_type; }
|
|
inline uint64_t get_tenant_id() const { return tenant_id_; }
|
|
inline uint64_t get_database_id() const { return database_id_; }
|
|
inline uint64_t get_package_id() const { return package_id_; }
|
|
inline const common::ObString &get_routine_name() const { return routine_name_; }
|
|
inline uint64_t get_overload() const { return overload_; }
|
|
inline ObRoutineType get_routine_type() { return routine_type_; }
|
|
TO_STRING_KV(K_(tenant_id), K_(database_id), K_(package_id), K_(routine_name), K_(overload), K_(routine_type));
|
|
private:
|
|
uint64_t tenant_id_;
|
|
uint64_t database_id_;
|
|
uint64_t package_id_;
|
|
common::ObString routine_name_;
|
|
uint64_t overload_;
|
|
ObRoutineType routine_type_;
|
|
};
|
|
|
|
inline bool ObRoutineNameHashWrapper::operator ==(const ObRoutineNameHashWrapper &rv) const
|
|
{
|
|
ObCompareNameWithTenantID name_cmp(tenant_id_);
|
|
return (tenant_id_ == rv.tenant_id_)
|
|
&& (database_id_ == rv.database_id_)
|
|
&& (package_id_ == rv.package_id_)
|
|
&& (0 == name_cmp.compare(routine_name_, rv.routine_name_))
|
|
&& (overload_ == rv.overload_)
|
|
&& (routine_type_ == rv.routine_type_);
|
|
}
|
|
|
|
inline uint64_t ObRoutineNameHashWrapper::hash() const
|
|
{
|
|
uint64_t hash_ret = 0;
|
|
common::ObCollationType cs_type = common::CS_TYPE_UTF8MB4_GENERAL_CI;
|
|
hash_ret = common::murmurhash(&tenant_id_, sizeof(uint64_t), 0);
|
|
hash_ret = common::murmurhash(&database_id_, sizeof(uint64_t), hash_ret);
|
|
hash_ret = common::murmurhash(&package_id_, sizeof(uint64_t), hash_ret);
|
|
hash_ret = common::ObCharset::hash(cs_type, routine_name_, hash_ret);
|
|
hash_ret = common::murmurhash(&overload_, sizeof(uint64_t), hash_ret);
|
|
hash_ret = common::murmurhash(&routine_type_, sizeof(ObRoutineType), hash_ret);
|
|
return hash_ret;
|
|
}
|
|
|
|
template<class T, class V>
|
|
struct ObGetRoutineKey
|
|
{
|
|
void operator()(const T & t, const V &v) const
|
|
{
|
|
UNUSED(t);
|
|
UNUSED(v);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct ObGetRoutineKey<uint64_t, ObSimpleRoutineSchema *>
|
|
{
|
|
uint64_t operator()(const ObSimpleRoutineSchema *routine_schema) const
|
|
{
|
|
return NULL != routine_schema ? routine_schema->get_routine_id() : common::OB_INVALID_ID;
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct ObGetRoutineKey<ObRoutineNameHashWrapper, ObSimpleRoutineSchema *>
|
|
{
|
|
ObRoutineNameHashWrapper operator ()(const ObSimpleRoutineSchema *routine_schema) const
|
|
{
|
|
ObRoutineNameHashWrapper name_wrap;
|
|
if (routine_schema != NULL) {
|
|
name_wrap.set_tenant_id(routine_schema->get_tenant_id());
|
|
name_wrap.set_database_id(routine_schema->get_database_id());
|
|
name_wrap.set_package_id(routine_schema->get_package_id());
|
|
name_wrap.set_routine_name(routine_schema->get_routine_name());
|
|
name_wrap.set_overload(routine_schema->get_overload());
|
|
name_wrap.set_routine_type(routine_schema->get_routine_type());
|
|
}
|
|
return name_wrap;
|
|
}
|
|
};
|
|
|
|
class ObRoutineMgr
|
|
{
|
|
typedef common::ObSortedVector<ObSimpleRoutineSchema *> RoutineInfos;
|
|
typedef common::hash::ObPointerHashMap<uint64_t, ObSimpleRoutineSchema *,
|
|
ObGetRoutineKey, 1024> RoutineIdMap;
|
|
typedef common::hash::ObPointerHashMap<ObRoutineNameHashWrapper, ObSimpleRoutineSchema *,
|
|
ObGetRoutineKey, 1024> RoutineNameMap;
|
|
typedef RoutineInfos::iterator RoutineIter;
|
|
typedef RoutineInfos::const_iterator ConstRoutineIter;
|
|
public:
|
|
ObRoutineMgr();
|
|
explicit ObRoutineMgr(common::ObIAllocator &allocator);
|
|
virtual ~ObRoutineMgr();
|
|
int init();
|
|
void reset();
|
|
ObRoutineMgr &operator =(const ObRoutineMgr &other);
|
|
int assign(const ObRoutineMgr &other);
|
|
int deep_copy(const ObRoutineMgr &other);
|
|
void dump() const;
|
|
|
|
int add_routines(const common::ObIArray<ObSimpleRoutineSchema> &routine_schemas);
|
|
int del_routines(const common::ObIArray<ObTenantRoutineId> &routines);
|
|
int add_routine(const ObSimpleRoutineSchema &routine_schema);
|
|
int del_routine(const ObTenantRoutineId &routine_id);
|
|
int get_routine_schema(uint64_t tenant_id, uint64_t database_id,
|
|
uint64_t package_id, const common::ObString &routine_name,
|
|
uint64_t overload, ObRoutineType routine_type,
|
|
const ObSimpleRoutineSchema *&routine_schema) const;
|
|
int get_routine_schema(uint64_t routine_id, const ObSimpleRoutineSchema *&routine_schema) const;
|
|
int get_routine_schemas_in_tenant(uint64_t tenant_id,
|
|
common::ObIArray<const ObSimpleRoutineSchema *> &routine_schemas) const;
|
|
int get_routine_schemas_in_database(
|
|
uint64_t tenant_id, uint64_t database_id,
|
|
common::ObIArray<const ObSimpleRoutineSchema *> &routine_schemas) const;
|
|
int get_routine_schemas_in_udt(uint64_t tenant_id, uint64_t udt_id,
|
|
common::ObIArray<const ObSimpleRoutineSchema *> &routine_schemas) const;
|
|
int get_routine_schemas_in_package(uint64_t tenant_id, uint64_t package_id,
|
|
common::ObIArray<const ObSimpleRoutineSchema *> &routine_schemas) const;
|
|
int del_routine_schemas_in_tenant(uint64_t tenant_id);
|
|
int del_routine_schemas_in_database(uint64_t tenant_id, uint64_t database_id);
|
|
int del_routine_schemas_in_package(uint64_t tenant_id, uint64_t package_id);
|
|
int get_routine_schema_count(int64_t &routine_schema_count) const;
|
|
int get_schema_statistics(ObSchemaStatisticsInfo &schema_info) const;
|
|
private:
|
|
inline bool check_inner_stat() const;
|
|
inline static bool compare_routine(const ObSimpleRoutineSchema *lhs,
|
|
const ObSimpleRoutineSchema *rhs);
|
|
inline static bool equal_routine(const ObSimpleRoutineSchema *lhs,
|
|
const ObSimpleRoutineSchema *rhs);
|
|
inline static bool compare_with_tenant_routine_id(const ObSimpleRoutineSchema *lhs,
|
|
const ObTenantRoutineId &tenant_routine_id);
|
|
inline static bool equal_with_tenant_routine_id(const ObSimpleRoutineSchema *lhs,
|
|
const ObTenantRoutineId &tenant_routine_id);
|
|
int rebuild_routine_hashmap();
|
|
private:
|
|
common::ObArenaAllocator local_allocator_;
|
|
common::ObIAllocator &allocator_;
|
|
RoutineInfos routine_infos_;
|
|
RoutineIdMap routine_id_map_;
|
|
RoutineNameMap routine_name_map_;
|
|
bool is_inited_;
|
|
};
|
|
} // namespace schema
|
|
} // namespace share
|
|
} // namespace oceanbase
|
|
#endif /* OCEANBASE_SRC_SHARE_SCHEMA_OB_ROUTINE_MGR_H_ */
|