[1950] | 1 | #ifndef BYTE_COMPARE_HPP |
---|
| 2 | #define BYTE_COMPARE_HPP |
---|
| 3 | |
---|
| 4 | /*============================================================================= |
---|
[1816] | 5 | byte_compare - Byte comparison methods. |
---|
| 6 | |
---|
| 7 | Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy. |
---|
| 8 | Licensed to the public under the Open Software License 3.0. |
---|
| 9 | Licensed to International Characters Inc. |
---|
[1950] | 10 | under the Academic Free License version 3.0. |
---|
[2093] | 11 | |
---|
| 12 | Created on: |
---|
| 13 | Author: Ken Herdy |
---|
[1950] | 14 | =============================================================================*/ |
---|
[1829] | 15 | |
---|
[1950] | 16 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 17 | // |
---|
| 18 | // WARNING: L (Length) |
---|
| 19 | // |
---|
| 20 | // for L is 1, choose T = uint8_t |
---|
| 21 | // for L in [2,3], choose T = uint16_t |
---|
| 22 | // for L in [4,7], choose T = uint32_t |
---|
[2093] | 23 | // for L in [8,15], choose T = uint64_t |
---|
| 24 | // for L in [16,), choose T = BitBlock |
---|
[1950] | 25 | // |
---|
[2093] | 26 | // WARNING: sizeof(T) <= L in the due to pointer cast. |
---|
| 27 | // i.e !( (T*) p1 ^ (T*) p2) logic |
---|
[1950] | 28 | // |
---|
| 29 | /////////////////////////////////////////////////////////////////////////////// |
---|
[1829] | 30 | |
---|
[1852] | 31 | #include "bitblock.hpp" |
---|
[1816] | 32 | #include <string.h> |
---|
| 33 | #include <stdint.h> |
---|
[1827] | 34 | #include <iostream> |
---|
[1816] | 35 | |
---|
[1852] | 36 | template<class T, uint32_t L> IDISA_ALWAYS_INLINE bool overlap_compare(const uint8_t * x, const uint8_t * y); |
---|
| 37 | template<class T> IDISA_ALWAYS_INLINE bool overlap_compare(const uint8_t * x, const uint8_t * y, uint32_t lgth); |
---|
| 38 | template<class T> IDISA_ALWAYS_INLINE bool compare(const uint8_t * x, const uint8_t * y, const uint32_t offset); |
---|
[1837] | 39 | IDISA_ALWAYS_INLINE bool mem_compare(const unsigned char * x, const unsigned char * y, uint32_t lgth); |
---|
[1816] | 40 | |
---|
[2093] | 41 | // WARNING: sizeof(T) <= L |
---|
[2046] | 42 | template<uint32_t L, class T> |
---|
[1852] | 43 | IDISA_ALWAYS_INLINE bool overlap_compare(const uint8_t * x, const uint8_t * y) { |
---|
[1833] | 44 | |
---|
[1816] | 45 | bool accum = true; |
---|
[1852] | 46 | uint8_t * p_x = (uint8_t*)x; |
---|
| 47 | uint8_t * p_y = (uint8_t*)y; |
---|
[1827] | 48 | |
---|
[1816] | 49 | for(int i=0; i < L/sizeof(T); i++) { |
---|
[1852] | 50 | accum = accum && compare<T>(p_x,p_y,0); |
---|
| 51 | p_x+=sizeof(T); |
---|
| 52 | p_y+=sizeof(T); |
---|
[1816] | 53 | } |
---|
| 54 | if(L & (sizeof(T)-1)) { |
---|
[1852] | 55 | accum = accum && compare<T>(x,y,L-sizeof(T)); |
---|
[1828] | 56 | } |
---|
[1816] | 57 | return accum; |
---|
| 58 | } |
---|
| 59 | |
---|
[2093] | 60 | // WARNING: sizeof(T) <= L |
---|
[1816] | 61 | template<class T> |
---|
[1852] | 62 | IDISA_ALWAYS_INLINE bool overlap_compare(const uint8_t * x, const uint8_t * y, uint32_t lgth) { |
---|
[1837] | 63 | |
---|
| 64 | bool accum = true; |
---|
[1852] | 65 | uint8_t * p_x = (uint8_t*)x; |
---|
| 66 | uint8_t * p_y = (uint8_t*)y; |
---|
[1837] | 67 | |
---|
| 68 | for(int i=0; i < lgth/sizeof(T); i++) { |
---|
[1852] | 69 | accum = accum && compare<T>(p_x,p_y,0); |
---|
| 70 | p_x+=sizeof(T); |
---|
| 71 | p_y+=sizeof(T); |
---|
[1837] | 72 | } |
---|
| 73 | if(lgth & (sizeof(T)-1)) { |
---|
[1852] | 74 | accum = accum && compare<T>(x,y,lgth-sizeof(T)); |
---|
[1837] | 75 | } |
---|
| 76 | return accum; |
---|
| 77 | } |
---|
| 78 | |
---|
[2093] | 79 | // WARNING: sizeof(T) <= L |
---|
[1837] | 80 | template<class T> |
---|
[1852] | 81 | IDISA_ALWAYS_INLINE bool compare(const uint8_t * x, const uint8_t * y, const uint32_t offset) { |
---|
[1816] | 82 | return !((*((T*)((uint8_t *)x + offset))) ^ |
---|
[2093] | 83 | (*((T*)((uint8_t *)y + offset)))); // << offset |
---|
[1816] | 84 | } |
---|
| 85 | |
---|
| 86 | template<> |
---|
[1852] | 87 | IDISA_ALWAYS_INLINE bool compare<BitBlock>(const uint8_t * x, const uint8_t * y, const uint32_t offset) { |
---|
[1831] | 88 | BitBlock temp = simd_xor(bitblock::load_unaligned((BitBlock*) ((uint8_t *)x + offset)), |
---|
[2093] | 89 | bitblock::load_unaligned((BitBlock*) ((uint8_t *)y + offset))); // << shift offset |
---|
[1816] | 90 | return bitblock::all(simd_not(temp)); |
---|
| 91 | } |
---|
| 92 | |
---|
[1837] | 93 | IDISA_ALWAYS_INLINE bool mem_compare(const unsigned char * x, const unsigned char * y, uint32_t lgth) { |
---|
| 94 | return (0 == memcmp(x, y, lgth)); |
---|
| 95 | } |
---|
| 96 | |
---|
| 97 | |
---|
[1816] | 98 | #endif // BYTE_COMPARE_HPP |
---|
| 99 | |
---|
| 100 | |
---|