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 ...@@ -83,6 +83,8 @@ Created 11/5/1995 Heikki Tuuri
#include "lzo/lzo1x.h" #include "lzo/lzo1x.h"
#endif #endif
using st_::span;
#ifdef HAVE_LIBNUMA #ifdef HAVE_LIBNUMA
#include <numa.h> #include <numa.h>
#include <numaif.h> #include <numaif.h>
...@@ -461,7 +463,7 @@ buf_pool_register_chunk( ...@@ -461,7 +463,7 @@ buf_pool_register_chunk(
@return true if temporary tablespace decrypted, false if not */ @return true if temporary tablespace decrypted, false if not */
static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) 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; return true;
} }
...@@ -950,20 +952,18 @@ static uint32_t buf_page_check_crc32(const byte* page, uint32_t checksum) ...@@ -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) # define buf_page_check_crc32(page, checksum) buf_calc_page_crc32(page)
#endif /* INNODB_BUG_ENDIAN_CRC32 */ #endif /* INNODB_BUG_ENDIAN_CRC32 */
/** Check if a page is all zeroes.
@param[in] read_buf database page /** Check if a buffer is all zeroes.
@param[in] page_size page frame size @param[in] buf data to check
@return whether the page is all zeroes */ @return whether the buffer is all zeroes */
bool buf_page_is_zeroes(const void* read_buf, size_t page_size) bool buf_is_zeroes(span<const byte> buf)
{ {
const ulint* b = reinterpret_cast<const ulint*>(read_buf); static const byte zeroes[4 * 1024] = {0};
const ulint* const e = b + page_size / sizeof *b; for (size_t i = 0; i < buf.size(); i += sizeof(zeroes)) {
do { if (memcmp(zeroes, buf.data() + i, sizeof(zeroes)) != 0)
if (*b++) { return false;
return false; }
} return true;
} while (b != e);
return true;
} }
/** Check if a page is corrupt. /** Check if a page is corrupt.
......
...@@ -34,6 +34,8 @@ Created 2011/12/19 ...@@ -34,6 +34,8 @@ Created 2011/12/19
#include "fil0crypt.h" #include "fil0crypt.h"
#include "fil0pagecompress.h" #include "fil0pagecompress.h"
using st_::span;
/** The doublewrite buffer */ /** The doublewrite buffer */
buf_dblwr_t* buf_dblwr = NULL; buf_dblwr_t* buf_dblwr = NULL;
...@@ -581,7 +583,8 @@ buf_dblwr_process() ...@@ -581,7 +583,8 @@ buf_dblwr_process()
} }
const page_size_t page_size(space->flags); 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 /* We want to ensure that for partial reads the
unread portion of the page is NUL. */ unread portion of the page is NUL. */
...@@ -604,8 +607,8 @@ buf_dblwr_process() ...@@ -604,8 +607,8 @@ buf_dblwr_process()
<< "error: " << ut_strerr(err); << "error: " << ut_strerr(err);
} }
const bool is_all_zero = buf_page_is_zeroes( const bool is_all_zero = buf_is_zeroes(
read_buf, page_size.physical()); span<const byte>(read_buf, page_size.physical()));
const bool expect_encrypted = space->crypt_data const bool expect_encrypted = space->crypt_data
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -28,6 +28,8 @@ Created 7/19/1997 Heikki Tuuri ...@@ -28,6 +28,8 @@ Created 7/19/1997 Heikki Tuuri
#include "sync0sync.h" #include "sync0sync.h"
#include "btr0sea.h" #include "btr0sea.h"
using st_::span;
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
my_bool srv_ibuf_disable_background_merge; my_bool srv_ibuf_disable_background_merge;
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
...@@ -4970,7 +4972,8 @@ ibuf_check_bitmap_on_import( ...@@ -4970,7 +4972,8 @@ ibuf_check_bitmap_on_import(
bitmap_page = ibuf_bitmap_get_map_page( bitmap_page = ibuf_bitmap_get_map_page(
page_id_t(space_id, page_no), page_size, &mtr); 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 /* This means we got all-zero page instead of
ibuf bitmap page. The subsequent page should be ibuf bitmap page. The subsequent page should be
all-zero pages. */ all-zero pages. */
...@@ -4983,8 +4986,8 @@ ibuf_check_bitmap_on_import( ...@@ -4983,8 +4986,8 @@ ibuf_check_bitmap_on_import(
page_size, page_size,
RW_S_LATCH, &mtr); RW_S_LATCH, &mtr);
page_t* page = buf_block_get_frame(block); page_t* page = buf_block_get_frame(block);
ut_ad(buf_page_is_zeroes( ut_ad(buf_is_zeroes(span<const byte>(
page, page_size.physical())); page, page_size.physical())));
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
ibuf_exit(&mtr); ibuf_exit(&mtr);
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri ...@@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0fil.h" #include "fil0fil.h"
#include "mtr0types.h" #include "mtr0types.h"
#include "buf0types.h" #include "buf0types.h"
#include "span.h"
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
#include "hash0hash.h" #include "hash0hash.h"
#include "ut0byte.h" #include "ut0byte.h"
...@@ -646,11 +647,10 @@ buf_block_unfix(buf_block_t* block); ...@@ -646,11 +647,10 @@ buf_block_unfix(buf_block_t* block);
# endif /* UNIV_DEBUG */ # endif /* UNIV_DEBUG */
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */
/** Check if a page is all zeroes. /** Check if a buffer is all zeroes.
@param[in] read_buf database page @param[in] buf data to check
@param[in] page_size page frame size @return whether the buffer is all zeroes */
@return whether the page is all zeroes */ bool buf_is_zeroes(st_::span<const byte> buf);
bool buf_page_is_zeroes(const void* read_buf, size_t page_size);
/** Checks if the page is in crc32 checksum format. /** Checks if the page is in crc32 checksum format.
@param[in] read_buf database page @param[in] read_buf database page
......
...@@ -507,7 +507,7 @@ page_zip_calc_checksum( ...@@ -507,7 +507,7 @@ page_zip_calc_checksum(
@param data ROW_FORMAT=COMPRESSED page @param data ROW_FORMAT=COMPRESSED page
@param size size of the page, in bytes @param size size of the page, in bytes
@return whether the stored checksum matches innodb_checksum_algorithm */ @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 #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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -34,7 +34,7 @@ template <class ElementType> class span { ...@@ -34,7 +34,7 @@ template <class ElementType> class span {
typedef element_type& reference; typedef element_type& reference;
typedef const element_type& const_reference; typedef const element_type& const_reference;
typedef pointer iterator; typedef pointer iterator;
typedef const pointer const_iterator; typedef const_pointer const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
......
...@@ -27,6 +27,9 @@ Created June 2005 by Marko Makela ...@@ -27,6 +27,9 @@ Created June 2005 by Marko Makela
#include "page0size.h" #include "page0size.h"
#include "page0zip.h" #include "page0zip.h"
#include "span.h"
using st_::span;
/** A BLOB field reference full of zero, for use in assertions and tests. /** A BLOB field reference full of zero, for use in assertions and tests.
Initially, BLOB field references are set to zero, in Initially, BLOB field references are set to zero, in
...@@ -4990,7 +4993,7 @@ page_zip_calc_checksum( ...@@ -4990,7 +4993,7 @@ page_zip_calc_checksum(
@param data ROW_FORMAT=COMPRESSED page @param data ROW_FORMAT=COMPRESSED page
@param size size of the page, in bytes @param size size of the page, in bytes
@return whether the stored checksum matches innodb_checksum_algorithm */ @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 = const srv_checksum_algorithm_t curr_algo =
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm); static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
...@@ -4999,17 +5002,12 @@ bool page_zip_verify_checksum(const void *data, size_t size) ...@@ -4999,17 +5002,12 @@ bool page_zip_verify_checksum(const void *data, size_t size)
return true; return true;
} }
for (size_t i = 0; i < size; i++) { if (buf_is_zeroes(span<const byte>(data, size))) {
if (static_cast<const byte*>(data)[i] != 0) { return true;
goto not_all_zeroes;
}
} }
return true;
not_all_zeroes:
const uint32_t stored = mach_read_from_4( 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); 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