145 lines
4.9 KiB
C++
145 lines
4.9 KiB
C++
/* Copyright (c) 2018, 2021, Alibaba and/or its affiliates. All rights reserved.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL/PolarDB-X Engine hereby grant you an
|
|
additional permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with
|
|
MySQL/PolarDB-X Engine.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
|
|
/** @file include/lizard0page.cc
|
|
lizard page operation.
|
|
|
|
Created 2020-04-08 by Jianwei.zhao
|
|
*******************************************************/
|
|
|
|
#include "lizard0page.h"
|
|
#include "dict0mem.h"
|
|
#include "mem0mem.h"
|
|
#include "page0page.h"
|
|
#include "page0zip.h"
|
|
|
|
#include "lizard0row.h"
|
|
|
|
extern ibool page_zip_header_cmp(const page_zip_des_t *, const byte *);
|
|
|
|
namespace lizard {
|
|
|
|
/**
|
|
Write the scn and uba of a record on a B-tree leaf node page.
|
|
@param[in/out] page_zip compressed page
|
|
@param[in/out] rec record
|
|
@param[in] offsets rec_get_offsets(rec, index)
|
|
@param[in] scn_col column number of SCN_ID in rec
|
|
@param[in] scn transaction scn
|
|
@param[in] undo_ptr undo_ptr
|
|
*/
|
|
void page_zip_write_scn_and_undo_ptr(page_zip_des_t *page_zip, byte *rec,
|
|
const ulint *offsets, ulint scn_col,
|
|
const scn_t scn, const undo_ptr_t undo_ptr,
|
|
const gcn_t gcn) {
|
|
byte *field;
|
|
byte *storage;
|
|
#ifdef UNIV_DEBUG
|
|
page_t *page = page_align(rec);
|
|
#endif /* UNIV_DEBUG */
|
|
ulint len;
|
|
|
|
ut_ad(page_simple_validate_new(page));
|
|
ut_ad(page_zip_simple_validate(page_zip));
|
|
ut_ad(page_zip_get_size(page_zip) >
|
|
PAGE_DATA + page_zip_dir_size(page_zip));
|
|
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
|
ut_ad(rec_offs_comp(offsets));
|
|
|
|
ut_ad(page_zip->m_start >= PAGE_DATA);
|
|
ut_ad(page_zip_header_cmp(page_zip, page));
|
|
|
|
ut_ad(page_is_leaf(page));
|
|
|
|
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
|
|
|
/** Get location of scn_id slot */
|
|
storage = page_zip_dir_start(page_zip) -
|
|
(rec_get_heap_no_new(rec) - 1) * PAGE_ZIP_TRX_FIELDS_SIZE +
|
|
DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
|
|
|
|
/** Get pointer of scn_id in record */
|
|
field = const_cast<byte *>(rec_get_nth_field(rec, offsets, scn_col, &len));
|
|
ut_ad(len == DATA_SCN_ID_LEN);
|
|
ut_ad(field + DATA_SCN_ID_LEN ==
|
|
rec_get_nth_field(rec, offsets, scn_col + 1, &len));
|
|
ut_ad(len == DATA_UNDO_PTR_LEN);
|
|
|
|
ut_ad(field + DATA_SCN_ID_LEN + DATA_UNDO_PTR_LEN ==
|
|
rec_get_nth_field(rec, offsets, scn_col + 2, &len));
|
|
ut_ad(len == DATA_GCN_ID_LEN);
|
|
|
|
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
|
ut_a(!memcmp(storage, field, DATA_LIZARD_TOTAL_LEN));
|
|
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
|
|
|
row_upd_rec_write_scn_and_undo_ptr(field, scn, undo_ptr, gcn);
|
|
|
|
/** Copy to compressed page */
|
|
memcpy(storage, field, DATA_LIZARD_TOTAL_LEN);
|
|
|
|
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
|
|
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
|
|
rec_offs_extra_size(offsets));
|
|
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
|
}
|
|
|
|
#if defined UNIV_DEBUG || defined LIZARD_DEBUG
|
|
/**
|
|
Check the lizard fields in every user records of the page
|
|
@param[in] page cluster index page
|
|
@param[in] index cluster index
|
|
|
|
@retval true Success
|
|
*/
|
|
bool lizard_page_attributes(page_t *page, const dict_index_t *index) {
|
|
rec_t *rec;
|
|
mem_heap_t *heap;
|
|
ulint *offsets = NULL;
|
|
|
|
ut_ad(page);
|
|
|
|
if (!index->is_clustered() || index->table->is_intrinsic()) return true;
|
|
|
|
/** Didn't check other type except of compact and branch */
|
|
if (!page_is_comp(page) || !page_is_leaf(page)) return true;
|
|
|
|
heap = mem_heap_create(UNIV_PAGE_SIZE + 200);
|
|
|
|
rec = page_rec_get_next(page_get_infimum_rec(page));
|
|
|
|
while (page_rec_is_user_rec(rec)) {
|
|
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
|
|
|
|
/* Assert the validation */
|
|
ut_ad(page_rec_is_comp(rec));
|
|
assert_row_lizard_valid(rec, index, offsets);
|
|
|
|
rec = page_rec_get_next(rec);
|
|
}
|
|
|
|
mem_heap_free(heap);
|
|
|
|
return true;
|
|
}
|
|
#endif /* UNIV_DEBUG || LIZARD_DEBUG define */
|
|
|
|
} // namespace lizard
|