hash

mysqlのハッシュテーブルは、PostgreSQLと同じリニアハッシュ・アルゴリズムを使用している。
(PostgreSQLのハッシュテーブル:http://www.hi-ho.ne.jp/a_ogawa/document/pg_dynahash.pdf)
PostgreSQLと違う点。
- ハッシュテーブルにデータを登録するたびに、テーブルを拡張する。 (データ数 = Bucket数になる)
- ハッシュ番地が衝突したときは、データを空いているBucketに登録して、 線形リストでリンクする。

typedef struct st_hash {
  uint key_offset,key_length;       /* Length of key if const length */
  uint records,blength,current_record;
  uint flags;
  DYNAMIC_ARRAY array;              /* Place for hash_keys */
  hash_get_key get_key;
  void (*free)(void *);
  CHARSET_INFO *charset;
} HASH;

_hash_init

HASHを初期化する。
CALLER_INFOを受け取るために、hash_initマクロ経由で実行される。

CHARSET_INFO

include/m_ctype.hで定義されている。

my_hash_insert

ハッシュテーブルにデータを登録する。
関数の前半部分は、リニアハッシュのBucketを拡張する処理。
後半部分(/* Check if we are at the empty position */以降)がデータ登録処理。

rec_hashnr

unsigned int rec_hashnr(HASH *hash,const byte *record)
{
  uint length;
  byte *key= (byte*) hash_key(hash,record,&length,0);
  return calc_hash(hash,key,length);
}

hash_keyでキーを取り出した後、calc_hashでハッシュ値を計算する

hash_key

static inline char*
hash_key(HASH *hash,const byte *record,uint *length,my_bool first)
{
  if (hash->get_key)
    return (*hash->get_key)(record,length,first);
  *length=hash->key_length;
  return (byte*) record+hash->key_offset;
}

ハッシュのキーとキーの長さを取り出す。
HASH->get_keyに関数ポインタが設定されているときは、その関数を使う。
たとえばtable_def_cacheでは、get_keyにtable_def_key関数が使われる。
get_keyが指定されていないときは、長さ(length)にHASH->key_lengthが設定され、キーにrecord + hash->key_offsetを返す。

calc_hash

static uint calc_hash(HASH *hash,const byte *key,uint length)
{
  ulong nr1=1, nr2=4;
  hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
  return nr1;
}

HASH->charset->coll->hash_sortの関数を使って、ハッシュ値を計算する。
たとえばtable_def_cacheでは、hash_sortにmy_hash_sort_binが使用される。