mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 23:25:34 +02:00
remove fishy reinterpret_cast from buf_page_is_zeroes()
In my micro-benchmarks memcmp(4196) 3 times faster than old implementation. Also, it's generally better to use as less reinterpret_casts<> as possible. buf_is_zeroes(): renamed from buf_page_is_zeroes() and argument changed to span<> for convenience. st_::span<T>::const_iterator: fixed page_zip-verify_checksum(): make argument byte* instead of void*
This commit is contained in:
parent
2bde065525
commit
884d22f288
7 changed files with 43 additions and 39 deletions
|
|
@ -83,6 +83,8 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "lzo/lzo1x.h"
|
||||
#endif
|
||||
|
||||
using st_::span;
|
||||
|
||||
#ifdef HAVE_LIBNUMA
|
||||
#include <numa.h>
|
||||
#include <numaif.h>
|
||||
|
|
@ -461,7 +463,7 @@ buf_pool_register_chunk(
|
|||
@return true if temporary tablespace decrypted, false if not */
|
||||
static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
|
||||
{
|
||||
if (buf_page_is_zeroes(src_frame, srv_page_size)) {
|
||||
if (buf_is_zeroes(span<const byte>(src_frame, srv_page_size))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -950,20 +952,18 @@ static uint32_t buf_page_check_crc32(const byte* page, uint32_t checksum)
|
|||
# define buf_page_check_crc32(page, checksum) buf_calc_page_crc32(page)
|
||||
#endif /* INNODB_BUG_ENDIAN_CRC32 */
|
||||
|
||||
/** Check if a page is all zeroes.
|
||||
@param[in] read_buf database page
|
||||
@param[in] page_size page frame size
|
||||
@return whether the page is all zeroes */
|
||||
bool buf_page_is_zeroes(const void* read_buf, size_t page_size)
|
||||
|
||||
/** Check if a buffer is all zeroes.
|
||||
@param[in] buf data to check
|
||||
@return whether the buffer is all zeroes */
|
||||
bool buf_is_zeroes(span<const byte> buf)
|
||||
{
|
||||
const ulint* b = reinterpret_cast<const ulint*>(read_buf);
|
||||
const ulint* const e = b + page_size / sizeof *b;
|
||||
do {
|
||||
if (*b++) {
|
||||
return false;
|
||||
}
|
||||
} while (b != e);
|
||||
return true;
|
||||
static const byte zeroes[4 * 1024] = {0};
|
||||
for (size_t i = 0; i < buf.size(); i += sizeof(zeroes)) {
|
||||
if (memcmp(zeroes, buf.data() + i, sizeof(zeroes)) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check if a page is corrupt.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ Created 2011/12/19
|
|||
#include "fil0crypt.h"
|
||||
#include "fil0pagecompress.h"
|
||||
|
||||
using st_::span;
|
||||
|
||||
/** The doublewrite buffer */
|
||||
buf_dblwr_t* buf_dblwr = NULL;
|
||||
|
||||
|
|
@ -581,7 +583,8 @@ buf_dblwr_process()
|
|||
}
|
||||
|
||||
const page_size_t page_size(space->flags);
|
||||
ut_ad(!buf_page_is_zeroes(page, page_size.physical()));
|
||||
ut_ad(!buf_is_zeroes(span<const byte>(page,
|
||||
page_size.physical())));
|
||||
|
||||
/* We want to ensure that for partial reads the
|
||||
unread portion of the page is NUL. */
|
||||
|
|
@ -604,8 +607,8 @@ buf_dblwr_process()
|
|||
<< "error: " << ut_strerr(err);
|
||||
}
|
||||
|
||||
const bool is_all_zero = buf_page_is_zeroes(
|
||||
read_buf, page_size.physical());
|
||||
const bool is_all_zero = buf_is_zeroes(
|
||||
span<const byte>(read_buf, page_size.physical()));
|
||||
const bool expect_encrypted = space->crypt_data
|
||||
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2016, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2016, 2020 MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -28,6 +28,8 @@ Created 7/19/1997 Heikki Tuuri
|
|||
#include "sync0sync.h"
|
||||
#include "btr0sea.h"
|
||||
|
||||
using st_::span;
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
my_bool srv_ibuf_disable_background_merge;
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
|
@ -4970,7 +4972,8 @@ ibuf_check_bitmap_on_import(
|
|||
bitmap_page = ibuf_bitmap_get_map_page(
|
||||
page_id_t(space_id, page_no), page_size, &mtr);
|
||||
|
||||
if (buf_page_is_zeroes(bitmap_page, page_size.physical())) {
|
||||
if (buf_is_zeroes(span<const byte>(bitmap_page,
|
||||
page_size.physical()))) {
|
||||
/* This means we got all-zero page instead of
|
||||
ibuf bitmap page. The subsequent page should be
|
||||
all-zero pages. */
|
||||
|
|
@ -4983,8 +4986,8 @@ ibuf_check_bitmap_on_import(
|
|||
page_size,
|
||||
RW_S_LATCH, &mtr);
|
||||
page_t* page = buf_block_get_frame(block);
|
||||
ut_ad(buf_page_is_zeroes(
|
||||
page, page_size.physical()));
|
||||
ut_ad(buf_is_zeroes(span<const byte>(
|
||||
page, page_size.physical())));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
ibuf_exit(&mtr);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020 MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "fil0fil.h"
|
||||
#include "mtr0types.h"
|
||||
#include "buf0types.h"
|
||||
#include "span.h"
|
||||
#ifndef UNIV_INNOCHECKSUM
|
||||
#include "hash0hash.h"
|
||||
#include "ut0byte.h"
|
||||
|
|
@ -646,11 +647,10 @@ buf_block_unfix(buf_block_t* block);
|
|||
# endif /* UNIV_DEBUG */
|
||||
#endif /* !UNIV_INNOCHECKSUM */
|
||||
|
||||
/** Check if a page is all zeroes.
|
||||
@param[in] read_buf database page
|
||||
@param[in] page_size page frame size
|
||||
@return whether the page is all zeroes */
|
||||
bool buf_page_is_zeroes(const void* read_buf, size_t page_size);
|
||||
/** Check if a buffer is all zeroes.
|
||||
@param[in] buf data to check
|
||||
@return whether the buffer is all zeroes */
|
||||
bool buf_is_zeroes(st_::span<const byte> buf);
|
||||
|
||||
/** Checks if the page is in crc32 checksum format.
|
||||
@param[in] read_buf database page
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ page_zip_calc_checksum(
|
|||
@param data ROW_FORMAT=COMPRESSED page
|
||||
@param size size of the page, in bytes
|
||||
@return whether the stored checksum matches innodb_checksum_algorithm */
|
||||
bool page_zip_verify_checksum(const void *data, size_t size);
|
||||
bool page_zip_verify_checksum(const byte *data, size_t size);
|
||||
|
||||
#ifndef UNIV_INNOCHECKSUM
|
||||
/**********************************************************************//**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2019, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2020 MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -34,7 +34,7 @@ public:
|
|||
typedef element_type& reference;
|
||||
typedef const element_type& const_reference;
|
||||
typedef pointer iterator;
|
||||
typedef const pointer const_iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ Created June 2005 by Marko Makela
|
|||
|
||||
#include "page0size.h"
|
||||
#include "page0zip.h"
|
||||
#include "span.h"
|
||||
|
||||
using st_::span;
|
||||
|
||||
/** A BLOB field reference full of zero, for use in assertions and tests.
|
||||
Initially, BLOB field references are set to zero, in
|
||||
|
|
@ -4990,7 +4993,7 @@ page_zip_calc_checksum(
|
|||
@param data ROW_FORMAT=COMPRESSED page
|
||||
@param size size of the page, in bytes
|
||||
@return whether the stored checksum matches innodb_checksum_algorithm */
|
||||
bool page_zip_verify_checksum(const void *data, size_t size)
|
||||
bool page_zip_verify_checksum(const byte *data, size_t size)
|
||||
{
|
||||
const srv_checksum_algorithm_t curr_algo =
|
||||
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
|
||||
|
|
@ -4999,17 +5002,12 @@ bool page_zip_verify_checksum(const void *data, size_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (static_cast<const byte*>(data)[i] != 0) {
|
||||
goto not_all_zeroes;
|
||||
}
|
||||
if (buf_is_zeroes(span<const byte>(data, size))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
not_all_zeroes:
|
||||
const uint32_t stored = mach_read_from_4(
|
||||
static_cast<const byte*>(data) + FIL_PAGE_SPACE_OR_CHKSUM);
|
||||
data + FIL_PAGE_SPACE_OR_CHKSUM);
|
||||
|
||||
uint32_t calc = page_zip_calc_checksum(data, size, curr_algo);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue