cannam@226: /* cannam@226: Copyright 2012-2014 David Robillard cannam@226: cannam@226: Permission to use, copy, modify, and/or distribute this software for any cannam@226: purpose with or without fee is hereby granted, provided that the above cannam@226: copyright notice and this permission notice appear in all copies. cannam@226: cannam@226: THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES cannam@226: WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF cannam@226: MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR cannam@226: ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES cannam@226: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN cannam@226: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF cannam@226: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. cannam@226: */ cannam@226: cannam@245: #include "digest.h" cannam@226: cannam@226: #ifdef __SSE4_2__ cannam@226: # include cannam@226: #endif cannam@226: cannam@226: ZIX_API uint32_t cannam@226: zix_digest_start(void) cannam@226: { cannam@226: #ifdef __SSE4_2__ cannam@226: return 1; // CRC32 initial value cannam@226: #else cannam@226: return 5381; // DJB hash initial value cannam@226: #endif cannam@226: } cannam@226: cannam@226: ZIX_API uint32_t cannam@226: zix_digest_add(uint32_t hash, const void* const buf, const size_t len) cannam@226: { cannam@226: const uint8_t* str = (const uint8_t*)buf; cannam@226: #ifdef __SSE4_2__ cannam@226: // SSE 4.2 CRC32 cannam@226: for (size_t i = 0; i < (len / sizeof(uint32_t)); ++i) { cannam@226: hash = _mm_crc32_u32(hash, *(const uint32_t*)str); cannam@226: str += sizeof(uint32_t); cannam@226: } cannam@226: if (len & sizeof(uint16_t)) { cannam@226: hash = _mm_crc32_u16(hash, *(const uint16_t*)str); cannam@226: str += sizeof(uint16_t); cannam@226: } cannam@226: if (len & sizeof(uint8_t)) { cannam@226: hash = _mm_crc32_u8(hash, *(const uint8_t*)str); cannam@226: } cannam@226: #else cannam@226: // Classic DJB hash cannam@226: for (size_t i = 0; i < len; ++i) { cannam@226: hash = (hash << 5) + hash + str[i]; cannam@226: } cannam@226: #endif cannam@226: return hash; cannam@226: }