mariadb/strings/hasher-mysql5x.c
Yuchen Pei bd1e74aa0b
MDEV-9826 More hash algorithms for PARTITION BY [LINEAR] KEY
PARTITION BY [LINEAR] KEY ALGORITHM={MYSQL51|MYSQL55|BASE31|CRC32C|XXH32|XXH3}

- The MYSQL5X algorithms are the existing algorithms, with MYSQL55
  being the default
- The BASE31 algorithm uses a base-31 representation of the bytes, see
  Modular hashing in https://algs4.cs.princeton.edu/34hash/. It serves
  as a simple baseline that distributes better than the old mysql5x
  algorithms
- CRC32C uses my_crc32c.
- XXH32 and XXH3 are xxhash algorithms - xxhash.h copied from latest
  release (0.8.3) of https://github.com/Cyan4973/xxHash

For performance (esp. xxh) we use one-shot hash functions in binary
hash_sort, and streaming hash function otherwise for byte-by-byte
hashing. XXH is the only stateful hash function. The other hash
algorithms are stateless and homomorphic, so streaming and one-shot
functions are identical.

Also updated the columnstore hash due to the change of MY_HASH_ADD
signature.

The following testing commands were run at an earlier version of the
patch with the following patch that changes the default algorithm from
MYSQL55 to CRC32C, and XXH32 (changing the patch accordingly)

mtr --suite main --do-test=.*partition
mtr --suite parts

modified   sql/ha_partition.cc
@@ -10336,6 +10336,8 @@ uint32 ha_partition::calculate_key_hash_value(Field **field_array)
   switch ((*field_array)->table->part_info->key_algorithm)
   {
   case partition_info::KEY_ALGORITHM_NONE:
+    hasher.set_algorithm(HASH_ALGORITHM_CRC32C);
+    break;
   case partition_info::KEY_ALGORITHM_55:
     /* Hasher default to mysql55 */
     break;
modified   sql/partition_info.cc
@@ -2328,7 +2328,7 @@ bool partition_info::fix_parser_data(THD *thd)
       if ((thd_sql_command(thd) == SQLCOM_CREATE_TABLE ||
            thd_sql_command(thd) == SQLCOM_ALTER_TABLE) &&
           key_algorithm == KEY_ALGORITHM_NONE)
-        key_algorithm= KEY_ALGORITHM_55;
+        key_algorithm= PARTITION_INFO_DEFAULT_ALGORITHM;
     }
     DBUG_RETURN(FALSE);
   }
@@ -2344,7 +2344,7 @@ bool partition_info::fix_parser_data(THD *thd)
     if ((thd_sql_command(thd) == SQLCOM_CREATE_TABLE ||
          thd_sql_command(thd) == SQLCOM_ALTER_TABLE) &&
         key_algorithm == KEY_ALGORITHM_NONE)
-      key_algorithm= KEY_ALGORITHM_55;
+      key_algorithm= PARTITION_INFO_DEFAULT_ALGORITHM;
   }
   defined_max_value= FALSE; // in case it already set (CREATE TABLE LIKE)
   do
modified   sql/partition_info.h
@@ -446,6 +446,8 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc
   int gen_part_type(THD *thd, String *str) const;
 };

+#define PARTITION_INFO_DEFAULT_ALGORITHM partition_info::KEY_ALGORITHM_CRC32C
+
 void part_type_error(THD *thd, partition_info *work_part_info,
                      const char *part_type, partition_info *tab_part_info);

modified   sql/sql_partition.cc
@@ -2471,7 +2471,7 @@ static int add_key_with_algorithm(String *str, const partition_info *part_info)
   err+= str->append(STRING_WITH_LEN("KEY "));

   if (part_info->key_algorithm != partition_info::KEY_ALGORITHM_NONE &&
-      part_info->key_algorithm != partition_info::KEY_ALGORITHM_55)
+      part_info->key_algorithm != PARTITION_INFO_DEFAULT_ALGORITHM)
   {
     err+= str->append(STRING_WITH_LEN("ALGORITHM = "));
     switch (part_info->key_algorithm)
@@ -2479,6 +2479,9 @@ static int add_key_with_algorithm(String *str, const partition_info *part_info)
       case partition_info::KEY_ALGORITHM_51:
         err+= str->append(STRING_WITH_LEN("MYSQL51"));
         break;
+      case partition_info::KEY_ALGORITHM_55:
+        err+= str->append(STRING_WITH_LEN("MYSQL55"));
+        break;
       case partition_info::KEY_ALGORITHM_BASE31:
         err+= str->append(STRING_WITH_LEN("BASE31"));
         break;
2026-02-05 11:55:12 +11:00

36 lines
1 KiB
C

#include "strings_def.h"
#include <m_ctype.h>
static uint64_t my_hasher_mysql5x_finalize(my_hasher_st *hasher)
{
/* Cast to uint32 for backward compatibility */
return (uint32) hasher->m_nr1;
}
static void my_hasher_mysql5x_hash_num(struct my_hasher_st *hasher,
const uchar* num,
size_t binary_size)
{
my_hash_sort_simple(hasher, &my_charset_latin1, num, binary_size);
}
/* The default MYSQL51/MYSQL55 hash algorithms. */
my_hasher_st my_hasher_mysql5x(void)
{
my_hasher_st tmp=
{ {{.m_nr1 = 1, .m_nr2 = 4}}, FALSE, NULL, NULL,
my_hasher_mysql5x_hash_num, my_hasher_mysql5x_finalize, NULL };
return tmp;
}
/*
Used in myisam/aria hash of row with unique constraints. Likely
introduced by mistake - don't use in new code
*/
my_hasher_st my_hasher_mysql5x_for_unique(void)
{
my_hasher_st tmp=
{ {{.m_nr1 = 0, .m_nr2 = 4}}, FALSE, NULL, NULL,
my_hasher_mysql5x_hash_num, my_hasher_mysql5x_finalize, NULL };
return tmp;
}