* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* 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 PSL v2 for more details.
* -------------------------------------------------------------------------
*
* knl_index.h
*
*
* IDENTIFICATION
* src/kernel/index/knl_index.h
*
* -------------------------------------------------------------------------
*/
#ifndef __KNL_INDEX_H__
#define __KNL_INDEX_H__
#include "cm_defs.h"
#include "knl_common.h"
#include "knl_interface.h"
#include "knl_session.h"
#include "knl_page.h"
#include "knl_lock.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OG_SHADOW_INDEX_ID (OG_MAX_TABLE_INDEXES + 1)
#define INDEX_DESC(index) (&((index_t *)(index))->desc)
#define OG_MAX_RECYCLE_INDEXES 1024
#define INDEX_RECY_CLOCK 2
#define INDEX_NEED_RECY_RATIO(se) ((se)->kernel->attr.idx_recycle_percent * 1.0 / OG_PERCENT)
#define INDEX_NEED_REBUILD_RATION 0.5
#define INDEX_NEED_REBUILD_SIZE SIZE_G(1)
#define MAX_DUPKEY_MSG_LEN 256
#define MAX_DUPKEY_MSG_KEY_LEN 64
#define MAX_SORT_THREADS 12
#define MIN_SORT_THREADS 2
#define INDEX_IS_UNSTABLE(index, is_splitting) (((index)->desc.primary || (index)->desc.unique) && !(is_splitting))
typedef enum en_dep_scan_mode {
DEP_SCAN_TABLE_FULL = 0,
DEP_SCAN_INDEX_ONLY = 1,
DEP_SCAN_MIX = 2,
} dep_scan_mode_t;
typedef struct st_cons_dep {
uint16 *cols;
uint8 *col_map;
struct st_cons_dep *next;
volatile bool32 loaded;
spinlock_t lock;
knl_refactor_t refactor;
knl_constraint_state_t cons_state;
uint16 uid;
uint32 oid;
uint8 col_count;
uint8 idx_slot;
uint8 ix_match_cols;
uint8 align;
dep_scan_mode_t scan_mode;
knl_scn_t chg_scn;
} cons_dep_t;
typedef struct st_dep_condition {
char *data[OG_MAX_INDEX_COLUMNS];
uint16 lens[OG_MAX_INDEX_COLUMNS];
knl_cursor_t *child_cursor;
cons_dep_t *dep;
} dep_condition_t;
typedef struct st_cons_dep_set {
cons_dep_t *first;
cons_dep_t *last;
uint32 count;
} cons_dep_set_t;
typedef struct st_index_accessor {
knl_cursor_operator_t do_fetch;
knl_cursor_operator_t do_insert;
knl_cursor_operator_t do_delete;
} idx_accessor_t;
typedef struct st_index {
knl_index_desc_t desc;
cons_dep_set_t dep_set;
struct st_dc_entity *entity;
union {
btree_t btree;
void *temp_btree;
};
struct st_part_index *part_index;
idx_accessor_t *acsor;
} index_t;
#define INDEX_PROFILE(index) (&(index)->desc.profile)
#define IS_UNIQUE_PRIMARY_INDEX(index) ((index)->desc.primary || (index)->desc.unique)
#define IS_PART_INDEX(index) (((index_t *)(index))->desc.parted)
#define INDEX_GET_PART(index, part_no) PART_GET_ENTITY(((index_t *)(index))->part_index, part_no)
#define OG_MAX_ROOT_LEVEL (OG_MAX_BTREE_LEVEL - 1)
#define BTREE_NEED_CMP_ROWID(cursor, index) (!IS_UNIQUE_PRIMARY_INDEX(index) || (cursor)->index_paral)
#define COLUMN_IS_REAL(c) ((c)->datatype == OG_TYPE_REAL)
#define BTREE_LOCATE_NEXT_KEY(search_info, cursor) ((search_info)->is_dsc_scan \
|| (cursor)->asc_relocate_next_key)
typedef struct st_index_set {
index_t *items[OG_MAX_TABLE_INDEXES];
uint32 count;
uint32 total_count;
} index_set_t;
typedef struct st_index_recycle_item {
xid_t xid;
knl_scn_t scn;
knl_scn_t part_org_scn;
uint32 table_id;
uint32 part_no;
uint32 uid;
uint32 index_id;
bool32 is_tx_active;
uint32 next;
} index_recycle_item_t;
typedef struct st_index_recycle_ctx {
spinlock_t lock;
bool32 is_working;
id_list_t idx_list;
id_list_t free_list;
thread_t thread;
index_recycle_item_t items[OG_MAX_RECYCLE_INDEXES];
} index_recycle_ctx_t;
typedef struct st_index_page_item {
uint32 next;
bool32 is_invalid;
knl_scn_t cache_scn;
char page[0];
} index_page_item_t;
typedef struct st_index_cache_ctx {
spinlock_t lock;
uint32 capacity;
uint32 hwm;
id_list_t free_items;
id_list_t expired_items;
index_page_item_t *items;
} index_cache_ctx_t;
typedef struct st_index_area {
index_recycle_ctx_t recycle_ctx;
index_cache_ctx_t cache_ctx;
} index_area_t;
typedef struct st_btree_mt_context {
mtrl_context_t mtrl_ctx;
mtrl_context_t mtrl_ctx_paral;
bool32 initialized;
uint32 seg_id;
bool32 is_parallel;
bool32 nologging;
uint64 rows;
char *page_buf;
} btree_mt_context_t;
typedef struct st_btree_path_t {
rowid_t path[OG_MAX_BTREE_LEVEL];
uint64 leaf_lsn;
knl_part_locate_t part_loc;
bool8 get_sibling;
char *sibling_key;
bool8 is_rebuild;
bool8 is_empty_newnode;
} btree_path_info_t;
typedef struct st_idx_range_info {
page_id_t l_page[OG_MAX_BTREE_LEVEL];
page_id_t r_page[OG_MAX_BTREE_LEVEL];
uint32 l_slot[OG_MAX_BTREE_LEVEL];
uint32 r_slot[OG_MAX_BTREE_LEVEL];
uint32 keys;
uint32 level;
}idx_range_info_t;
typedef enum en_index_build_mode {
REBUILD_INDEX_ONLINE = 0,
REBUILD_INDEX = 1,
CREATE_INDEX_ONLINE = 2,
REBUILD_INDEX_PARALLEL = 3,
}index_build_mode_t;
typedef struct st_auto_rebuild_item {
uint32 uid;
uint32 oid;
alter_index_type_t type;
arebuild_index_state_t state;
knl_scn_t scn;
char name[OG_NAME_BUFFER_SIZE];
char part_name[OG_NAME_BUFFER_SIZE];
knl_scn_t org_scn;
uint32 next;
} auto_rebuild_item_t;
typedef struct st_auto_rebuild_ctx {
spinlock_t lock;
bool32 working;
id_list_t idx_list;
id_list_t free_list;
thread_t thread;
auto_rebuild_item_t items[OG_MAX_RECYCLE_INDEXES];
} auto_rebuild_ctx_t;
extern idx_accessor_t g_btree_acsor;
extern idx_accessor_t g_pcr_btree_acsor;
extern idx_accessor_t g_temp_btree_acsor;
extern idx_accessor_t g_invalid_index_acsor;
typedef void (*idx_put_key_data_t)(char *key_buf, og_type_t type, const char *data, uint16 len, uint16 id);
typedef status_t (*idx_batch_insert)(knl_handle_t session, knl_cursor_t *cursor);
status_t knl_make_key(knl_handle_t session, knl_cursor_t *cursor, index_t *index, char *key_buf);
status_t knl_make_update_key(knl_handle_t session, knl_cursor_t *cursor, index_t *index, char *key_buf,
knl_update_info_t *ui, uint16 *map);
void idx_decode_row(knl_session_t *session, knl_cursor_t *cursor, uint16 *offsets, uint16 *lens, uint16 *size);
status_t idx_generate_dupkey_error(knl_session_t *session, index_t *index, const char *key);
status_t idx_construct(btree_mt_context_t *ogx);
void idx_recycle_proc(thread_t *thread);
void idx_recycle_close(knl_session_t *session);
void idx_binary_search(index_t *index, char *curr_page, knl_scan_key_t *scan_key, btree_path_info_t *path_info,
bool32 cmp_rowid, bool32 *is_same);
status_t idx_get_paral_schedule(knl_session_t *session, btree_t *btree, knl_scn_t org_scn,
knl_idx_paral_info_t paral_info, knl_index_paral_range_t *sub_ranges);
void idx_enter_next_range(knl_session_t *session, page_id_t page_id, uint32 slot, uint32 step, uint32 *border);
void idx_reverse_key_data(char *data, og_type_t type, uint16 len);
uint16 idx_get_col_size(og_type_t type, uint16 len, bool32 is_pcr);
void auto_rebuild_init(knl_session_t *session);
void auto_rebuild_add_index(knl_session_t *session, index_t *index, knl_part_locate_t part_loc);
void auto_rebuild_release_item(knl_session_t *session, uint32 id_input);
void auto_rebuild_close(knl_session_t *session);
void idx_auto_rebuild_proc(thread_t *thread);
void index_print_key(index_t *index, const char *key, char *buf, uint16 buf_len);
#ifdef __cplusplus
}
#endif
#endif