diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-07 17:59:04 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-07 17:59:04 +0300 |
commit | a1dc1a7f2192176d73289076386a3008505690b3 (patch) | |
tree | 2a1a5e80c7bdf32a02368112a65d9e17450059d0 | |
parent | 4a5be2e94e749c26121395d2a4509dc60a856c44 (diff) | |
download | mariadb-git-bb-10.5-marko2.tar.gz |
WIP MDEV-19344 fixbb-10.5-marko2
This will be pushed to 10.1 with proper commit message.
-rw-r--r-- | storage/innobase/ibuf/ibuf0ibuf.cc | 62 |
1 files changed, 22 insertions, 40 deletions
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 790305c86d2..a9474295af8 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -2607,42 +2607,28 @@ ibuf_contract_after_insert( } while (size > 0 && sum_sizes < entry_size); } -/*********************************************************************//** -Determine if an insert buffer record has been encountered already. -@return TRUE if a new record, FALSE if possible duplicate */ -static -ibool -ibuf_get_volume_buffered_hash( -/*==========================*/ - const rec_t* rec, /*!< in: ibuf record in post-4.1 format */ - const byte* types, /*!< in: fields */ - const byte* data, /*!< in: start of user record data */ - ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT, - nonzero=ROW_FORMAT=COMPACT */ - ulint* hash, /*!< in/out: hash array */ - ulint size) /*!< in: number of elements in hash array */ +/** Determine if a change buffer record has been encountered already. +@param rec change buffer record in the MySQL 5.5 format +@param hash hash table of encountered records +@param size number of elements in hash +@retval true if a distinct record +@retval false if this may be duplicating an earlier record */ +static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash, + ulint size) { - ulint len; - ulint fold; - ulint bitmask; - - len = ibuf_rec_get_size( - rec, types, - rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp); - fold = ut_fold_binary(data, len); - - hash += (fold / (CHAR_BIT * sizeof *hash)) % size; - bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash))); - - if (*hash & bitmask) { - - return(FALSE); - } - - /* We have not seen this record yet. Insert it. */ - *hash |= bitmask; - - return(TRUE); + ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER); + const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER); + const ulint len= rec_get_data_size_old(rec) - start; + const uint32_t fold= ut_crc32(rec + start, len); + hash+= (fold / (CHAR_BIT * sizeof *hash)) % size; + ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash))); + + if (*hash & bitmask) + return false; + + /* We have not seen this record yet. Remember it. */ + *hash|= bitmask; + return true; } #ifdef UNIV_DEBUG @@ -2735,11 +2721,7 @@ ibuf_get_volume_buffered_count_func( case IBUF_OP_DELETE_MARK: /* There must be a record to delete-mark. See if this record has been already buffered. */ - if (n_recs && ibuf_get_volume_buffered_hash( - rec, types + IBUF_REC_INFO_SIZE, - types + len, - types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT, - hash, size)) { + if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) { (*n_recs)++; } |