MurmurHash - как он проходит через ключ? - PullRequest
1 голос
/ 20 октября 2010

Я смотрю на MurmurHash (sites.google.com/site/murmurhash/) Я использую его в чёрном ящике и не пытаюсь понять математику на данном этапе.

Однако я немного посмотрел на код и забеспокоился о том, как он работает ... Вот код:

uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed )
{
    const uint64_t m = 0xc6a4a7935bd1e995;
    const int r = 47;

    uint64_t h = seed ^ (len * m);

    const uint64_t * data = (const uint64_t *)key;
    const uint64_t * end = data + (len/8);

    while(data != end)
    {
        uint64_t k = *data++;

        k *= m; 
        k ^= k >> r; 
        k *= m; 

        h ^= k;
        h *= m; 
    }

    const unsigned char * data2 = (const unsigned char*)data;

    switch(len & 7)
    {
    case 7: h ^= uint64_t(data2[6]) << 48;
    case 6: h ^= uint64_t(data2[5]) << 40;
    case 5: h ^= uint64_t(data2[4]) << 32;
    case 4: h ^= uint64_t(data2[3]) << 24;
    case 3: h ^= uint64_t(data2[2]) << 16;
    case 2: h ^= uint64_t(data2[1]) << 8;
    case 1: h ^= uint64_t(data2[0]);
            h *= m;
    };

    h ^= h >> r;
    h *= m;
    h ^= h >> r;

    return h;
} 

Обратите внимание, что это 64-битная версия для 64-битных машин. Моя проблема в том, что я не понимаю, как он проходит через ключ, который вы отправляете. Если я например отправлю ему указатель на строку символов "ABC". Я вижу, что отправил бы указатель на первый символ «A» и длиной 3 *.

Мои ограниченные знания C ++ говорят мне, что он создает указатель «данные», который указывает на то же местоположение, что и входящий указатель. Но затем в нем вычисляется конец ключа, беря «данные» и добавляя к нему длину строки, деленную на 8. Поэтому, если бы ключ был меньше 8, цикл while не сработал бы, и ни один из первых математических элементов не был бы выполнен. Кто-нибудь знает, почему он делится на 8?

Это потому, что первый математический бит предназначен только для клавиш длиной 8 и более (если так, почему)?

Спасибо заранее. C

1 Ответ

3 голосов
/ 20 октября 2010

Алгоритм обрабатывает данные, передаваемые по 8 байт за раз (uint64_t равен 8 байтам). Первый цикл объединит весь набор из 8 байтов, чтобы создать один ключ из 8 байтов. Затем коммутатор будет использовать оставшиеся байты (все 3 байта в вашем примере, передающие «ABC») и обрабатывать их, чтобы учесть их в конечном результате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...