blob: b45bd6d492269b45dc21243b795e8bc90d048758 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Adaptor.hh"
#include "Murmur3.hh"
#define ROTL64(x, r) ((x << r) | (x >> (64 - r)))
namespace orc {
inline uint64_t rotl64 ( uint64_t x, int8_t r ) {
return (x << r) | (x >> (64 - r));
}
inline uint64_t Murmur3::fmix64(uint64_t value) {
value ^= (value >> 33);
value *= 0xff51afd7ed558ccdL;
value ^= (value >> 33);
value *= 0xc4ceb9fe1a85ec53L;
value ^= (value >> 33);
return value;
}
uint64_t Murmur3::hash64(const uint8_t *data, uint32_t len) {
return hash64(data, len, DEFAULT_SEED);
}
DIAGNOSTIC_PUSH
#if defined(__clang__)
DIAGNOSTIC_IGNORE("-Wimplicit-fallthrough")
#endif
uint64_t Murmur3::hash64(const uint8_t *data, uint32_t len, uint32_t seed) {
uint64_t h = seed;
uint32_t blocks = len >> 3;
const uint64_t* src = reinterpret_cast<const uint64_t*>(data);
uint64_t c1 = 0x87c37b91114253d5L;
uint64_t c2 = 0x4cf5ad432745937fL;
for (uint32_t i = 0; i < blocks; i++) {
uint64_t k = src[i];
k *= c1;
k = ROTL64(k, 31);
k *= c2;
h ^= k;
h = ROTL64(h, 27);
h = h * 5 + 0x52dce729;
}
uint64_t k = 0;
uint32_t idx = blocks << 3;
switch (len - idx) {
case 7:
k ^= static_cast<uint64_t>(data[idx + 6]) << 48;
case 6:
k ^= static_cast<uint64_t>(data[idx + 5]) << 40;
case 5:
k ^= static_cast<uint64_t>(data[idx + 4]) << 32;
case 4:
k ^= static_cast<uint64_t>(data[idx + 3]) << 24;
case 3:
k ^= static_cast<uint64_t>(data[idx + 2]) << 16;
case 2:
k ^= static_cast<uint64_t>(data[idx + 1]) << 8;
case 1:
k ^= static_cast<uint64_t>(data[idx + 0]);
k *= c1;
k = ROTL64(k, 31);
k *= c2;
h ^= k;
}
h ^= len;
h = fmix64(h);
return h;
}
DIAGNOSTIC_POP
}