* 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_map.h
*
*
* IDENTIFICATION
* src/kernel/table/knl_map.h
*
* -------------------------------------------------------------------------
*/
#ifndef __KNL_MAP_H__
#define __KNL_MAP_H__
#include "knl_table_module.h"
#include "cm_defs.h"
#include "knl_common.h"
#include "knl_page.h"
#include "knl_interface.h"
#include "knl_log.h"
#include "knl_space_manage.h"
#include "knl_undo.h"
#include "knl_map_persistent.h"
#ifdef __cplusplus
extern "C" {
#endif
status_t heap_find_free_page(knl_session_t *session, knl_handle_t heap_handle, knl_part_locate_t part_loc, uint8 mid,
bool32 use_cached, page_id_t *page_id, bool32 *degrade_mid);
status_t heap_find_appendonly_page(knl_session_t *session, knl_handle_t heap_handle, knl_part_locate_t part_loc,
uint32 data_size, page_id_t *page_id);
void heap_remove_cached_page(knl_session_t *session, bool32 appendonly);
void heap_add_tx_free_page(knl_session_t *session, knl_handle_t heap_handle, page_id_t page_id, uint8 itl_id,
xid_t xid, knl_scn_t seg_scn);
int32 heap_find_tx_free_page_index(knl_session_t *session, knl_handle_t heap_handle, uint8 *next, uint8 *count);
void heap_get_paral_schedule(knl_session_t *session, knl_handle_t heap_handle, knl_scn_t org_scn, uint32 workers,
knl_paral_range_t *range);
uint8 heap_get_owner_list(knl_session_t *session, heap_segment_t *segment, uint32 free_size);
uint32 heap_get_target_list(knl_session_t *session, heap_segment_t *segment, uint32 size);
void heap_try_change_map(knl_session_t *session, knl_handle_t heap_handle, page_id_t page_id);
void heap_degrade_change_map(knl_session_t *session, knl_handle_t heap_handle, page_id_t page_id, uint8 new_id);
void heap_set_pctfree(knl_session_t *session, heap_segment_t *segment, uint32 pctfree);
void heap_get_map_path(knl_session_t *session, knl_handle_t heap_handle, page_id_t page_id, map_path_t *path);
int32 heap_compare_map_path(map_path_t *left, map_path_t *right);
status_t heap_seq_find_map(knl_session_t *session, knl_handle_t heap_handle, map_path_t *path,
uint32 mid_input, page_id_t *page_id, bool32 *degrade_mid);
void heap_drop_garbage_segment(knl_session_t *session, knl_seg_desc_t *seg);
void heap_drop_part_garbage_segment(knl_session_t *session, knl_seg_desc_t *seg);
void heap_truncate_garbage_segment(knl_session_t *session, knl_seg_desc_t *seg);
void heap_truncate_part_garbage_segment(knl_session_t *session, knl_seg_desc_t *seg);
void heap_format_free_ufp(knl_session_t *session, heap_segment_t *segment);
void heap_change_map(knl_session_t *session, heap_segment_t *segment, map_index_t *map, uint8 new_id, uint32 level);
void heap_add_ufp(knl_session_t *session, heap_segment_t *segment,
page_id_t page_id, uint32 count, bool32 need_noread);
void heap_paral_init_map_path(map_path_t *path, page_id_t map_id, uint32 map_level);
static inline void heap_format_map(knl_session_t *session, map_page_t *page, page_id_t page_id, uint32 extent_size)
{
page_init(session, (page_head_t *)page, page_id, PAGE_TYPE_HEAP_MAP);
page->head.type = PAGE_TYPE_HEAP_MAP;
TO_PAGID_DATA(INVALID_PAGID, page->head.next_ext);
page->head.ext_size = spc_ext_id_by_size(extent_size);
page->map.file = INVALID_FILE_ID;
page->map.page = 0;
page->map.slot = INVALID_SLOT;
page->map.list_id = 0;
page->hwm = 0;
for (uint32 i = 0; i < HEAP_FREE_LIST_COUNT; i++) {
page->lists[i].count = 0;
page->lists[i].first = INVALID_SLOT;
}
}
static inline void heap_reset_page_count(heap_segment_t *segment)
{
segment->page_count = 0;
segment->free_page_count = 0;
segment->last_ext_size = 0;
}
static inline uint8 heap_find_last_list(map_page_t *page)
{
uint8 i;
for (i = HEAP_FREE_LIST_COUNT - 1; i > 0; i--) {
if (page->lists[i].count > 0) {
return i;
}
}
return 0;
}
static inline map_node_t *heap_get_map_node(char *page, uint16 slot)
{
char *base_ptr = ((char *)page) + sizeof(map_page_t);
return (map_node_t *)(base_ptr + (uint32)slot * sizeof(map_node_t));
}
static inline void heap_insert_into_list(map_page_t *page, map_list_t *list, uint16 slot)
{
map_node_t *node;
map_node_t *first_node = NULL;
node = heap_get_map_node((char *)page, slot);
node->next = list->first;
node->prev = INVALID_SLOT;
if (list->count > 0) {
first_node = heap_get_map_node((char *)page, list->first);
first_node->prev = slot;
}
list->first = slot;
list->count++;
}
static inline void heap_remove_from_list(map_page_t *page, map_list_t *list, uint16 slot)
{
knl_panic(list->count > 0);
map_node_t *node = heap_get_map_node((char *)page, slot);
if (list->first == slot) {
list->first = (uint16)node->next;
}
if (node->prev != INVALID_SLOT) {
map_node_t *prev_node = heap_get_map_node((char *)page, (uint16)node->prev);
prev_node->next = node->next;
}
if (node->next != INVALID_SLOT) {
map_node_t *next_node = heap_get_map_node((char *)page, (uint16)node->next);
next_node->prev = node->prev;
}
list->count--;
}
status_t map_dump_page(knl_session_t *session, page_head_t *page_head, cm_dump_t *dump);
status_t map_segment_dump(knl_session_t *session, page_head_t *page_head, cm_dump_t *dump);
static inline uint32 heap_get_segment_page_count(space_t *space, heap_segment_t *segment)
{
if (segment->page_count == 0) {
return spc_pages_by_ext_cnt(space, segment->extents.count, PAGE_TYPE_HEAP_HEAD);
}
return segment->page_count;
}
static inline uint32 heap_get_all_page_count(space_t *space, heap_segment_t *segment)
{
uint32 total_count = segment->page_count + segment->free_page_count;
if (total_count == 0) {
return spc_pages_by_ext_cnt(space, segment->extents.count + segment->free_extents.count, PAGE_TYPE_HEAP_HEAD);
}
knl_panic(segment->page_count != 0);
return total_count;
}
status_t heap_generate_create_undo(knl_session_t *session, page_id_t entry, uint32 space_id, bool32 need_redo);
void heap_undo_create_part(knl_session_t *session, undo_row_t *ud_row, undo_page_t *ud_page, int32 ud_slot);
#ifdef __cplusplus
}
#endif
#endif