X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=crc%2Ffnv.c;h=4cd06501fd2e1b92bed2bb8d5e9eff0a85c74ddc;hp=04c0560c9f421bea6796b1f3aef680bc5eb80827;hb=855f03627f2bce6a7f725fe6cc92e7ebe8d39deb;hpb=41177ed32fe815545061f7d10ce13559f1e9eb98 diff --git a/crc/fnv.c b/crc/fnv.c index 04c0560c..4cd06501 100644 --- a/crc/fnv.c +++ b/crc/fnv.c @@ -2,14 +2,32 @@ #define FNV_PRIME 0x100000001b3ULL +/* + * 64-bit fnv, but don't require 64-bit multiples of data. Use bytes + * for the last unaligned chunk. + */ uint64_t fnv(const void *buf, uint32_t len, uint64_t hval) { const uint64_t *ptr = buf; - const uint64_t *end = (void *) buf + len; - while (ptr < end) { + while (len) { hval *= FNV_PRIME; - hval ^= (uint64_t) *ptr++; + if (len >= sizeof(uint64_t)) { + hval ^= (uint64_t) *ptr++; + len -= sizeof(uint64_t); + continue; + } else { + const uint8_t *ptr8 = (const uint8_t *) ptr; + uint64_t val = 0; + int i; + + for (i = 0; i < len; i++) { + val <<= 8; + val |= (uint8_t) *ptr8++; + } + hval ^= val; + break; + } } return hval;