Commit 884d22f2 authored by Eugene Kosov's avatar Eugene Kosov

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*
parent 2bde0655
......@@ -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;
......
/*****************************************************************************
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);
......
/*****************************************************************************
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
/**********************************************************************//**
......
/*****************************************************************************
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 @@ template <class ElementType> class span {
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment