cannam@226
|
1 /*
|
cannam@226
|
2 Copyright 2012-2014 David Robillard <http://drobilla.net>
|
cannam@226
|
3
|
cannam@226
|
4 Permission to use, copy, modify, and/or distribute this software for any
|
cannam@226
|
5 purpose with or without fee is hereby granted, provided that the above
|
cannam@226
|
6 copyright notice and this permission notice appear in all copies.
|
cannam@226
|
7
|
cannam@226
|
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
cannam@226
|
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
cannam@226
|
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
cannam@226
|
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
cannam@226
|
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
cannam@226
|
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
cannam@226
|
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
cannam@226
|
15 */
|
cannam@226
|
16
|
cannam@245
|
17 #include "digest.h"
|
cannam@226
|
18
|
cannam@226
|
19 #ifdef __SSE4_2__
|
cannam@226
|
20 # include <smmintrin.h>
|
cannam@226
|
21 #endif
|
cannam@226
|
22
|
cannam@226
|
23 ZIX_API uint32_t
|
cannam@226
|
24 zix_digest_start(void)
|
cannam@226
|
25 {
|
cannam@226
|
26 #ifdef __SSE4_2__
|
cannam@226
|
27 return 1; // CRC32 initial value
|
cannam@226
|
28 #else
|
cannam@226
|
29 return 5381; // DJB hash initial value
|
cannam@226
|
30 #endif
|
cannam@226
|
31 }
|
cannam@226
|
32
|
cannam@226
|
33 ZIX_API uint32_t
|
cannam@226
|
34 zix_digest_add(uint32_t hash, const void* const buf, const size_t len)
|
cannam@226
|
35 {
|
cannam@226
|
36 const uint8_t* str = (const uint8_t*)buf;
|
cannam@226
|
37 #ifdef __SSE4_2__
|
cannam@226
|
38 // SSE 4.2 CRC32
|
cannam@226
|
39 for (size_t i = 0; i < (len / sizeof(uint32_t)); ++i) {
|
cannam@226
|
40 hash = _mm_crc32_u32(hash, *(const uint32_t*)str);
|
cannam@226
|
41 str += sizeof(uint32_t);
|
cannam@226
|
42 }
|
cannam@226
|
43 if (len & sizeof(uint16_t)) {
|
cannam@226
|
44 hash = _mm_crc32_u16(hash, *(const uint16_t*)str);
|
cannam@226
|
45 str += sizeof(uint16_t);
|
cannam@226
|
46 }
|
cannam@226
|
47 if (len & sizeof(uint8_t)) {
|
cannam@226
|
48 hash = _mm_crc32_u8(hash, *(const uint8_t*)str);
|
cannam@226
|
49 }
|
cannam@226
|
50 #else
|
cannam@226
|
51 // Classic DJB hash
|
cannam@226
|
52 for (size_t i = 0; i < len; ++i) {
|
cannam@226
|
53 hash = (hash << 5) + hash + str[i];
|
cannam@226
|
54 }
|
cannam@226
|
55 #endif
|
cannam@226
|
56 return hash;
|
cannam@226
|
57 }
|