keyboard stuff

Generic wear-leveling algorithm (#16996)

* Initial import of wear-leveling algorithm.

* Alignment.

* Docs tweaks.

* Lock/unlock.

* Update quantum/wear_leveling/wear_leveling_internal.h

Co-authored-by: Stefan Kerkmann <karlk90@pm.me>

* More tests, fix issue with consolidation when unlocked.

* More tests.

* Review comments.

* Add plumbing for FNV1a.

* Another test checking that checksum mismatch clears the cache.

* Check that the write log still gets played back.

Co-authored-by: Stefan Kerkmann <karlk90@pm.me>

authored by

Nick Brassel
Stefan Kerkmann
and committed by
GitHub
01ecf332 0d013a21

+7519
+1
builddefs/build_test.mk
··· 63 63 include $(QUANTUM_PATH)/debounce/tests/rules.mk 64 64 include $(QUANTUM_PATH)/encoder/tests/rules.mk 65 65 include $(QUANTUM_PATH)/sequencer/tests/rules.mk 66 + include $(QUANTUM_PATH)/wear_leveling/tests/rules.mk 66 67 include $(PLATFORM_PATH)/test/rules.mk 67 68 ifneq ($(filter $(FULL_TESTS),$(TEST)),) 68 69 include $(BUILDDEFS_PATH)/build_full_test.mk
+6
builddefs/common_features.mk
··· 650 650 SRC += crc.c 651 651 endif 652 652 653 + ifeq ($(strip $(FNV_ENABLE)), yes) 654 + OPT_DEFS += -DFNV_ENABLE 655 + VPATH += $(LIB_PATH)/fnv 656 + SRC += qmk_fnv_type_validation.c hash_32a.c hash_64a.c 657 + endif 658 + 653 659 ifeq ($(strip $(HAPTIC_ENABLE)),yes) 654 660 COMMON_VPATH += $(DRIVER_PATH)/haptic 655 661
+1
builddefs/testlist.mk
··· 4 4 include $(QUANTUM_PATH)/debounce/tests/testlist.mk 5 5 include $(QUANTUM_PATH)/encoder/tests/testlist.mk 6 6 include $(QUANTUM_PATH)/sequencer/tests/testlist.mk 7 + include $(QUANTUM_PATH)/wear_leveling/tests/testlist.mk 7 8 include $(PLATFORM_PATH)/test/testlist.mk 8 9 9 10 define VALIDATE_TEST_LIST
+304
lib/fnv/Makefile
··· 1 + #!/bin/make 2 + # 3 + # hash - makefile for FNV hash tools 4 + # 5 + # @(#) $Revision: 5.2 $ 6 + # @(#) $Id: Makefile,v 5.2 2012/03/21 01:42:15 chongo Exp $ 7 + # @(#) $Source: /usr/local/src/cmd/fnv/RCS/Makefile,v $ 8 + # 9 + # See: 10 + # http://www.isthe.com/chongo/tech/comp/fnv/index.html 11 + # 12 + # for the most up to date copy of this code and the FNV hash home page. 13 + # 14 + # Please do not copyright this code. This code is in the public domain. 15 + # 16 + # LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 + # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 18 + # EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 + # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 20 + # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21 + # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 + # PERFORMANCE OF THIS SOFTWARE. 23 + # 24 + # By: 25 + # chongo <Landon Curt Noll> /\oo/\ 26 + # http://www.isthe.com/chongo/ 27 + # 28 + # Share and Enjoy! :-) 29 + 30 + # make tools 31 + # 32 + SHELL= /bin/sh 33 + CFLAGS= -O3 -g3 34 + #CFLAGS= -O2 -g3 35 + #CC= cc 36 + AR= ar 37 + TAR= tar 38 + EGREP= egrep 39 + GZIP_BIN= gzip 40 + INSTALL= install 41 + 42 + # If your system needs ranlib use: 43 + # RANLIB= ranlib 44 + # otherwise use: 45 + # RANLIB= : 46 + # 47 + #RANLIB= ranlib 48 + RANLIB= : 49 + 50 + # where to install things 51 + # 52 + DESTBIN= /usr/local/bin 53 + DESTLIB= /usr/local/lib 54 + DESTINC= /usr/local/include 55 + 56 + # what to build 57 + # 58 + SRC= hash_32.c hash_32a.c hash_64.c hash_64a.c \ 59 + fnv32.c fnv64.c \ 60 + have_ulong64.c test_fnv.c 61 + NO64BIT_SRC= no64bit_fnv64.c no64bit_hash_64.c \ 62 + no64bit_hash_64a.c no64bit_test_fnv.c 63 + HSRC= fnv.h \ 64 + longlong.h 65 + ALL= ${SRC} ${HSRC} \ 66 + README Makefile 67 + PROGS= fnv032 fnv064 fnv132 fnv164 fnv1a32 fnv1a64 68 + OBSOLETE_PROGS= fnv0_32 fnv0_64 fnv1_32 fnv1_64 fnv1a_32 fnv1a_64 69 + NO64BIT_PROGS= no64bit_fnv064 no64bit_fnv164 no64bit_fnv1a64 70 + LIBS= libfnv.a 71 + LIBOBJ= hash_32.o hash_64.o hash_32a.o hash_64a.o test_fnv.o 72 + NO64BIT_OBJ= no64bit_fnv64.o no64bit_hash_64.o \ 73 + no64bit_hash_64a.o no64bit_test_fnv.o 74 + OTHEROBJ= fnv32.o fnv64.o 75 + TARGETS= ${LIBOBJ} ${LIBS} ${PROGS} 76 + 77 + # default rule 78 + # 79 + all: ${TARGETS} 80 + 81 + # things to build 82 + # 83 + hash_32.o: hash_32.c longlong.h fnv.h 84 + ${CC} ${CFLAGS} hash_32.c -c 85 + 86 + hash_64.o: hash_64.c longlong.h fnv.h 87 + ${CC} ${CFLAGS} hash_64.c -c 88 + 89 + hash_32a.o: hash_32a.c longlong.h fnv.h 90 + ${CC} ${CFLAGS} hash_32a.c -c 91 + 92 + hash_64a.o: hash_64a.c longlong.h fnv.h 93 + ${CC} ${CFLAGS} hash_64a.c -c 94 + 95 + test_fnv.o: test_fnv.c longlong.h fnv.h 96 + ${CC} ${CFLAGS} test_fnv.c -c 97 + 98 + fnv32.o: fnv32.c longlong.h fnv.h 99 + ${CC} ${CFLAGS} fnv32.c -c 100 + 101 + fnv032: fnv32.o libfnv.a 102 + ${CC} fnv32.o libfnv.a -o fnv032 103 + 104 + fnv64.o: fnv64.c longlong.h fnv.h 105 + ${CC} ${CFLAGS} fnv64.c -c 106 + 107 + fnv064: fnv64.o libfnv.a 108 + ${CC} fnv64.o libfnv.a -o fnv064 109 + 110 + libfnv.a: ${LIBOBJ} 111 + rm -f $@ 112 + ${AR} rv $@ ${LIBOBJ} 113 + ${RANLIB} $@ 114 + 115 + fnv132: fnv032 116 + -rm -f $@ 117 + -cp -f $? $@ 118 + 119 + fnv1a32: fnv032 120 + -rm -f $@ 121 + -cp -f $? $@ 122 + 123 + fnv164: fnv064 124 + -rm -f $@ 125 + -cp -f $? $@ 126 + 127 + fnv1a64: fnv064 128 + -rm -f $@ 129 + -cp -f $? $@ 130 + 131 + longlong.h: have_ulong64.c Makefile 132 + -@rm -f have_ulong64 have_ulong64.o ll_tmp longlong.h 133 + @echo 'forming longlong.h' 134 + @echo '/*' > longlong.h 135 + @echo ' * DO NOT EDIT -- generated by the Makefile' >> longlong.h 136 + @echo ' */' >> longlong.h 137 + @echo '' >> longlong.h 138 + @echo '#if !defined(__LONGLONG_H__)' >> longlong.h 139 + @echo '#define __LONGLONG_H__' >> longlong.h 140 + @echo '' >> longlong.h 141 + @echo '/* do we have/want to use a long long type? */' >> longlong.h 142 + -@rm -f have_ulong64.o have_ulong64 143 + -@${CC} ${CFLAGS} have_ulong64.c -c 2>/dev/null; true 144 + -@${CC} ${CFLAGS} have_ulong64.o -o have_ulong64 2>/dev/null; true 145 + -@${SHELL} -c "./have_ulong64 > ll_tmp 2>/dev/null" \ 146 + >/dev/null 2>&1; true 147 + -@if [ -s ll_tmp ]; then \ 148 + cat ll_tmp >> longlong.h; \ 149 + else \ 150 + echo '#undef HAVE_64BIT_LONG_LONG /* no */' >> longlong.h; \ 151 + fi 152 + @echo '' >> longlong.h 153 + @echo '/*' >> longlong.h 154 + @echo ' * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG' >> longlong.h 155 + @echo ' */' >> longlong.h 156 + @echo '#if defined(NO64BIT_LONG_LONG)' >> longlong.h 157 + @echo '#undef HAVE_64BIT_LONG_LONG' >> longlong.h 158 + @echo '#endif /* NO64BIT_LONG_LONG */' >> longlong.h 159 + @echo '' >> longlong.h 160 + @echo '#endif /* !__LONGLONG_H__ */' >> longlong.h 161 + -@rm -f have_ulong64 have_ulong64.o ll_tmp 162 + @echo 'longlong.h formed' 163 + 164 + # utilities 165 + # 166 + install: all 167 + -@if [ -d "${DESTBIN}" ]; then \ 168 + echo " mkdir -p ${DESTBIN}"; \ 169 + mkdir -p ${DESTBIN}; \ 170 + fi 171 + -@if [ -d "${DESTLIB}" ]; then \ 172 + echo " mkdir -p ${DESTLIB}"; \ 173 + mkdir -p ${DESTLIB}; \ 174 + fi 175 + -@if [ -d "${DESTINC}" ]; then \ 176 + echo " mkdir -p ${DESTINC}"; \ 177 + mkdir -p ${DESTINC}; \ 178 + fi 179 + ${INSTALL} -m 0755 ${PROGS} ${DESTBIN} 180 + ${INSTALL} -m 0644 ${LIBS} ${DESTLIB} 181 + ${RANLIB} ${DESTLIB}/libfnv.a 182 + ${INSTALL} -m 0644 ${HSRC} ${DESTINC} 183 + @# remove osolete programs 184 + for i in ${OBSOLETE_PROGS}; do \ 185 + if [ -f "${DESTBIN}/$$i" ]; then \ 186 + echo "rm -f ${DESTBIN}/$$i"; \ 187 + rm -f "${DESTBIN}/$$i"; \ 188 + fi; \ 189 + done 190 + 191 + clean: 192 + -rm -f have_ulong64 have_ulong64.o ll_tmp ll_tmp2 longlong.h 193 + -rm -f ${LIBOBJ} 194 + -rm -f ${OTHEROBJ} 195 + 196 + clobber: clean 197 + -rm -f ${TARGETS} 198 + -rm -f ${OBSOLETE_PROGS} lltmp lltmp2 ll_tmp 199 + -rm -f ${NO64BIT_SRC} 200 + -rm -f ${NO64BIT_OBJ} 201 + -rm -f ${NO64BIT_PROGS} 202 + -rm -f vector.c 203 + 204 + check: ${PROGS} 205 + @echo -n "FNV-0 32 bit tests: " 206 + @./fnv032 -t 1 -v 207 + @echo -n "FNV-1 32 bit tests: " 208 + @./fnv132 -t 1 -v 209 + @echo -n "FNV-1a 32 bit tests: " 210 + @./fnv1a32 -t 1 -v 211 + @echo -n "FNV-0 64 bit tests: " 212 + @./fnv064 -t 1 -v 213 + @echo -n "FNV-1 64 bit tests: " 214 + @./fnv164 -t 1 -v 215 + @echo -n "FNV-1a 64 bit tests: " 216 + @./fnv1a64 -t 1 -v 217 + 218 + ############################### 219 + # generate test vector source # 220 + ############################### 221 + 222 + no64bit_fnv64.c: fnv64.c 223 + -rm -f $@ 224 + -cp -f $? $@ 225 + 226 + no64bit_hash_64.c: hash_64.c 227 + -rm -f $@ 228 + -cp -f $? $@ 229 + 230 + no64bit_hash_64a.c: hash_64a.c 231 + -rm -f $@ 232 + -cp -f $? $@ 233 + 234 + no64bit_test_fnv.c: test_fnv.c 235 + -rm -f $@ 236 + -cp -f $? $@ 237 + 238 + no64bit_fnv64.o: no64bit_fnv64.c longlong.h fnv.h 239 + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_fnv64.c -c 240 + 241 + no64bit_hash_64.o: no64bit_hash_64.c longlong.h fnv.h 242 + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64.c -c 243 + 244 + no64bit_hash_64a.o: no64bit_hash_64a.c longlong.h fnv.h 245 + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64a.c -c 246 + 247 + no64bit_test_fnv.o: no64bit_test_fnv.c longlong.h fnv.h 248 + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_test_fnv.c -c 249 + 250 + no64bit_fnv064: no64bit_fnv64.o no64bit_hash_64.o \ 251 + no64bit_hash_64a.o no64bit_test_fnv.o 252 + ${CC} ${CFLAGS} no64bit_fnv64.o no64bit_hash_64.o \ 253 + no64bit_hash_64a.o no64bit_test_fnv.o -o $@ 254 + 255 + no64bit_fnv164: no64bit_fnv064 256 + -rm -f $@ 257 + -cp -f $? $@ 258 + 259 + no64bit_fnv1a64: no64bit_fnv064 260 + -rm -f $@ 261 + -cp -f $? $@ 262 + 263 + vector.c: ${PROGS} ${NO64BIT_PROGS} 264 + -rm -f $@ 265 + echo '/* start of output generated by make $@ */' >> $@ 266 + echo '' >> $@ 267 + #@ 268 + echo '/* FNV-0 32 bit test vectors */' >> $@ 269 + ./fnv032 -t 0 >> $@ 270 + echo '' >> $@ 271 + #@ 272 + echo '/* FNV-1 32 bit test vectors */' >> $@ 273 + ./fnv132 -t 0 >> $@ 274 + echo '' >> $@ 275 + #@ 276 + echo '/* FNV-1a 32 bit test vectors */' >> $@ 277 + ./fnv1a32 -t 0 >> $@ 278 + echo '' >> $@ 279 + #@ 280 + echo '/* FNV-0 64 bit test vectors */' >> $@ 281 + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ 282 + ./fnv064 -t 0 >> $@ 283 + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ 284 + ./no64bit_fnv064 -t 0 >> $@ 285 + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ 286 + echo '' >> $@ 287 + #@ 288 + echo '/* FNV-1 64 bit test vectors */' >> $@ 289 + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ 290 + ./fnv164 -t 0 >> $@ 291 + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ 292 + ./no64bit_fnv164 -t 0 >> $@ 293 + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ 294 + echo '' >> $@ 295 + #@ 296 + echo '/* FNV-1a 64 bit test vectors */' >> $@ 297 + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ 298 + ./fnv1a64 -t 0 >> $@ 299 + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ 300 + ./no64bit_fnv1a64 -t 0 >> $@ 301 + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ 302 + echo '' >> $@ 303 + #@ 304 + echo '/* end of output generated by make $@ */' >> $@
+158
lib/fnv/README
··· 1 + #=====================# 2 + # Fowler/Noll/Vo hash # 3 + #=====================# 4 + 5 + The basis of this hash algorithm was taken from an idea sent 6 + as reviewer comments to the IEEE POSIX P1003.2 committee by: 7 + 8 + Phong Vo (http://www.research.att.com/info/kpv) 9 + Glenn Fowler (http://www.research.att.com/~gsf/) 10 + 11 + In a subsequent ballot round: 12 + 13 + Landon Curt Noll (http://www.isthe.com/chongo) 14 + 15 + improved on their algorithm. Some people tried this hash 16 + and found that it worked rather well. In an EMail message 17 + to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 18 + 19 + FNV hashes are designed to be fast while maintaining a low 20 + collision rate. The FNV speed allows one to quickly hash lots 21 + of data while maintaining a reasonable collision rate. See: 22 + 23 + http://www.isthe.com/chongo/tech/comp/fnv/index.html 24 + 25 + for more details as well as other forms of the FNV hash. 26 + Comments, questions, bug fixes and suggestions welcome at 27 + the address given in the above URL. 28 + 29 + 30 + #==================# 31 + # FNV hash utility # 32 + #==================# 33 + 34 + Two hash utilities (32 bit and 64 bit) are provided: 35 + 36 + fnv032 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 37 + fnv132 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 38 + fnv1a32 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 39 + 40 + fnv064 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 41 + fnv164 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 42 + fnv1a64 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] 43 + 44 + -b bcnt mask off all but the lower bcnt bits (default: 32) 45 + -m multiple hashes, one per line for each arg 46 + -s hash arg as a string (ignoring terminating NUL bytes) 47 + -t code 0 ==> generate test vectors, 1 ==> test FNV hash 48 + -v verbose mode, print arg after hash (implies -m) 49 + arg string (if -s was given) or filename (default stdin) 50 + 51 + The fnv032, fnv064 implement the historic FNV-0 hash. 52 + The fnv132, fnv164 implement the recommended FNV-1 hash. 53 + The fnv1a32, fnv1a64 implement the recommended FNV-1a hash. 54 + 55 + This is the original historic FNV algorithm with a 0 offset basis. 56 + It is recommended that FNV-1, with a non-0 offset basis be used instead. 57 + 58 + To test FNV hashes, try: 59 + 60 + fnv032 -t 1 -v 61 + fnv132 -t 1 -v 62 + fnv1a32 -t 1 -v 63 + 64 + fnv064 -t 1 -v 65 + fnv164 -t 1 -v 66 + fnv1a64 -t 1 -v 67 + 68 + If you are compiling, try: 69 + 70 + make check 71 + 72 + 73 + #==================# 74 + # FNV hash library # 75 + #==================# 76 + 77 + The libfnv.a library implements both a 32 bit and a 64 bit FNV hash 78 + on collections of bytes, a NUL terminated strings or on an open file 79 + descriptor. 80 + 81 + Here is the 32 bit FNV 1 hash: 82 + 83 + Fnv32_t fnv_32_buf(void *buf, int len, Fnv32_t hval); /* byte buf */ 84 + Fnv32_t fnv_32_str(char *string, Fnv32_t hval); /* string */ 85 + 86 + Here is the 32 bit FNV 1a hash: 87 + 88 + Fnv32_t fnv_32a_buf(void *buf, int len, Fnv32_t hval); /* byte buf */ 89 + Fnv32_t fnv_32a_str(char *string, Fnv32_t hval); /* string */ 90 + 91 + Here is the 64 bit FNV 1 hash: 92 + 93 + Fnv64_t fnv_64_buf(void *buf, int len, Fnv64_t hval); /* byte buf */ 94 + Fnv64_t fnv_64_str(char *string, Fnv64_t hval); /* string */ 95 + 96 + Here is the 64 bit FNV 1a hash: 97 + 98 + Fnv64_t fnv_64a_buf(void *buf, int len, Fnv64_t hval); /* byte buf */ 99 + Fnv64_t fnv_64a_str(char *string, Fnv64_t hval); /* string */ 100 + 101 + On the first call to a hash function, one must supply the initial basis 102 + that is appropriate for the hash in question: 103 + 104 + FNV-0: (not recommended) 105 + 106 + FNV0_32_INIT /* 32 bit FNV-0 initial basis */ 107 + FNV0_64_INIT /* 64 bit FNV-0 initial basis */ 108 + 109 + FNV-1: 110 + 111 + FNV1_32_INIT /* 32 bit FNV-1 initial basis */ 112 + FNV1_64_INIT /* 64 bit FNV-1 initial basis */ 113 + 114 + FNV-1a: 115 + 116 + FNV1A_32_INIT /* 32 bit FNV-1a initial basis */ 117 + FNV1A_64_INIT /* 64 bit FNV-1a initial basis */ 118 + 119 + For example to perform a 64 bit FNV-1 hash: 120 + 121 + #include "fnv.h" 122 + 123 + Fnv64_t hash_val; 124 + 125 + hash_val = fnv_64_str("a string", FNV1_64_INIT); 126 + hash_val = fnv_64_str("more string", hash_val); 127 + 128 + produces the same final hash value as: 129 + 130 + hash_val = fnv_64_str("a stringmore string", FNV1_64_INIT); 131 + 132 + NOTE: If one used 'FNV0_64_INIT' instead of 'FNV1_64_INIT' one would get the 133 + historic FNV-0 hash instead recommended FNV-1 hash. 134 + 135 + To perform a 32 bit FNV-1 hash: 136 + 137 + #include "fnv.h" 138 + 139 + Fnv32_t hash_val; 140 + 141 + hash_val = fnv_32_buf(buf, length_of_buf, FNV1_32_INIT); 142 + hash_val = fnv_32_str("more data", hash_val); 143 + 144 + To perform a 64 bit FNV-1a hash: 145 + 146 + #include "fnv.h" 147 + 148 + Fnv64_t hash_val; 149 + 150 + hash_val = fnv_64a_buf(buf, length_of_buf, FNV1_64_INIT); 151 + hash_val = fnv_64a_str("more data", hash_val); 152 + 153 + =-= 154 + 155 + chongo <Landon Curt Noll> /\oo/\ 156 + http://www.isthe.com/chongo 157 + 158 + Share and Enjoy!
+249
lib/fnv/fnv.h
··· 1 + /* 2 + * fnv - Fowler/Noll/Vo- hash code 3 + * 4 + * @(#) $Revision: 5.4 $ 5 + * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo- hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * NOTE: The FNV-0 historic hash is not recommended. One should use 37 + * the FNV-1 hash instead. 38 + * 39 + * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 40 + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 41 + * 42 + * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the 43 + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 44 + * 45 + * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 46 + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 47 + * 48 + * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the 49 + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 50 + * 51 + * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the 52 + * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). 53 + * 54 + * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the 55 + * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). 56 + * 57 + *** 58 + * 59 + * Please do not copyright this code. This code is in the public domain. 60 + * 61 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 62 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 63 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 64 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 65 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 66 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 67 + * PERFORMANCE OF THIS SOFTWARE. 68 + * 69 + * By: 70 + * chongo <Landon Curt Noll> /\oo/\ 71 + * http://www.isthe.com/chongo/ 72 + * 73 + * Share and Enjoy! :-) 74 + */ 75 + 76 + #if !defined(__FNV_H__) 77 + #define __FNV_H__ 78 + 79 + #include <sys/types.h> 80 + 81 + #define FNV_VERSION "5.0.2" /* @(#) FNV Version */ 82 + 83 + 84 + /* 85 + * 32 bit FNV-0 hash type 86 + */ 87 + typedef u_int32_t Fnv32_t; 88 + 89 + 90 + /* 91 + * 32 bit FNV-0 zero initial basis 92 + * 93 + * This historic hash is not recommended. One should use 94 + * the FNV-1 hash and initial basis instead. 95 + */ 96 + #define FNV0_32_INIT ((Fnv32_t)0) 97 + 98 + 99 + /* 100 + * 32 bit FNV-1 and FNV-1a non-zero initial basis 101 + * 102 + * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: 103 + * 104 + * chongo <Landon Curt Noll> /\../\ 105 + * 106 + * NOTE: The \'s above are not back-slashing escape characters. 107 + * They are literal ASCII backslash 0x5c characters. 108 + * 109 + * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. 110 + */ 111 + #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5) 112 + #define FNV1_32A_INIT FNV1_32_INIT 113 + 114 + 115 + /* 116 + * determine how 64 bit unsigned values are represented 117 + */ 118 + #include "longlong.h" 119 + 120 + 121 + /* 122 + * 64 bit FNV-0 hash 123 + */ 124 + #if defined(HAVE_64BIT_LONG_LONG) 125 + typedef u_int64_t Fnv64_t; 126 + #else /* HAVE_64BIT_LONG_LONG */ 127 + typedef struct { 128 + u_int32_t w32[2]; /* w32[0] is low order, w32[1] is high order word */ 129 + } Fnv64_t; 130 + #endif /* HAVE_64BIT_LONG_LONG */ 131 + 132 + 133 + /* 134 + * 64 bit FNV-0 zero initial basis 135 + * 136 + * This historic hash is not recommended. One should use 137 + * the FNV-1 hash and initial basis instead. 138 + */ 139 + #if defined(HAVE_64BIT_LONG_LONG) 140 + #define FNV0_64_INIT ((Fnv64_t)0) 141 + #else /* HAVE_64BIT_LONG_LONG */ 142 + extern const Fnv64_t fnv0_64_init; 143 + #define FNV0_64_INIT (fnv0_64_init) 144 + #endif /* HAVE_64BIT_LONG_LONG */ 145 + 146 + 147 + /* 148 + * 64 bit FNV-1 non-zero initial basis 149 + * 150 + * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: 151 + * 152 + * chongo <Landon Curt Noll> /\../\ 153 + * 154 + * NOTE: The \'s above are not back-slashing escape characters. 155 + * They are literal ASCII backslash 0x5c characters. 156 + * 157 + * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. 158 + */ 159 + #if defined(HAVE_64BIT_LONG_LONG) 160 + #define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL) 161 + #define FNV1A_64_INIT FNV1_64_INIT 162 + #else /* HAVE_64BIT_LONG_LONG */ 163 + extern const fnv1_64_init; 164 + extern const Fnv64_t fnv1a_64_init; 165 + #define FNV1_64_INIT (fnv1_64_init) 166 + #define FNV1A_64_INIT (fnv1a_64_init) 167 + #endif /* HAVE_64BIT_LONG_LONG */ 168 + 169 + 170 + /* 171 + * hash types 172 + */ 173 + enum fnv_type { 174 + FNV_NONE = 0, /* invalid FNV hash type */ 175 + FNV0_32 = 1, /* FNV-0 32 bit hash */ 176 + FNV1_32 = 2, /* FNV-1 32 bit hash */ 177 + FNV1a_32 = 3, /* FNV-1a 32 bit hash */ 178 + FNV0_64 = 4, /* FNV-0 64 bit hash */ 179 + FNV1_64 = 5, /* FNV-1 64 bit hash */ 180 + FNV1a_64 = 6, /* FNV-1a 64 bit hash */ 181 + }; 182 + 183 + 184 + /* 185 + * these test vectors are used as part o the FNV test suite 186 + */ 187 + struct test_vector { 188 + void *buf; /* start of test vector buffer */ 189 + int len; /* length of test vector */ 190 + }; 191 + struct fnv0_32_test_vector { 192 + struct test_vector *test; /* test vector buffer to hash */ 193 + Fnv32_t fnv0_32; /* expected FNV-0 32 bit hash value */ 194 + }; 195 + struct fnv1_32_test_vector { 196 + struct test_vector *test; /* test vector buffer to hash */ 197 + Fnv32_t fnv1_32; /* expected FNV-1 32 bit hash value */ 198 + }; 199 + struct fnv1a_32_test_vector { 200 + struct test_vector *test; /* test vector buffer to hash */ 201 + Fnv32_t fnv1a_32; /* expected FNV-1a 32 bit hash value */ 202 + }; 203 + struct fnv0_64_test_vector { 204 + struct test_vector *test; /* test vector buffer to hash */ 205 + Fnv64_t fnv0_64; /* expected FNV-0 64 bit hash value */ 206 + }; 207 + struct fnv1_64_test_vector { 208 + struct test_vector *test; /* test vector buffer to hash */ 209 + Fnv64_t fnv1_64; /* expected FNV-1 64 bit hash value */ 210 + }; 211 + struct fnv1a_64_test_vector { 212 + struct test_vector *test; /* test vector buffer to hash */ 213 + Fnv64_t fnv1a_64; /* expected FNV-1a 64 bit hash value */ 214 + }; 215 + 216 + 217 + /* 218 + * external functions 219 + */ 220 + /* hash_32.c */ 221 + extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval); 222 + extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval); 223 + 224 + /* hash_32a.c */ 225 + extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval); 226 + extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval); 227 + 228 + /* hash_64.c */ 229 + extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval); 230 + extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval); 231 + 232 + /* hash_64a.c */ 233 + extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval); 234 + extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval); 235 + 236 + /* test_fnv.c */ 237 + extern struct test_vector fnv_test_str[]; 238 + extern struct fnv0_32_test_vector fnv0_32_vector[]; 239 + extern struct fnv1_32_test_vector fnv1_32_vector[]; 240 + extern struct fnv1a_32_test_vector fnv1a_32_vector[]; 241 + extern struct fnv0_64_test_vector fnv0_64_vector[]; 242 + extern struct fnv1_64_test_vector fnv1_64_vector[]; 243 + extern struct fnv1a_64_test_vector fnv1a_64_vector[]; 244 + extern void unknown_hash_type(char *prog, enum fnv_type type, int code); 245 + extern void print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg); 246 + extern void print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg); 247 + 248 + 249 + #endif /* __FNV_H__ */
+467
lib/fnv/fnv32.c
··· 1 + /* 2 + * fnv32 - 32 bit Fowler/Noll/Vo hash of a buffer or string 3 + * 4 + * @(#) $Revision: 5.5 $ 5 + * @(#) $Id: fnv32.c,v 5.5 2012/03/21 01:38:12 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv32.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * Please do not copyright this code. This code is in the public domain. 37 + * 38 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 39 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 40 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 41 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 42 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 43 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 44 + * PERFORMANCE OF THIS SOFTWARE. 45 + * 46 + * By: 47 + * chongo <Landon Curt Noll> /\oo/\ 48 + * http://www.isthe.com/chongo/ 49 + * 50 + * Share and Enjoy! :-) 51 + */ 52 + 53 + #include <stdio.h> 54 + #include <unistd.h> 55 + #include <stdlib.h> 56 + #include <sys/types.h> 57 + #include <sys/stat.h> 58 + #include <fcntl.h> 59 + #include <string.h> 60 + #include "longlong.h" 61 + #include "fnv.h" 62 + 63 + #define WIDTH 32 /* bit width of hash */ 64 + 65 + #define BUF_SIZE (32*1024) /* number of bytes to hash at a time */ 66 + 67 + static char *usage = 68 + "usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n" 69 + "\n" 70 + "\t-b bcnt\tmask off all but the lower bcnt bits (default 32)\n" 71 + "\t-m\tmultiple hashes, one per line for each arg\n" 72 + "\t-s\thash arg as a string (ignoring terminating NUL bytes)\n" 73 + "\t-t code\t test hash code: (0 ==> generate test vectors\n" 74 + "\t\t\t\t 1 ==> validate against FNV test vectors)\n" 75 + "\t-v\tverbose mode, print arg after hash (implies -m)\n" 76 + "\targ\tstring (if -s was given) or filename (default stdin)\n" 77 + "\n" 78 + "\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n" 79 + "\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n" 80 + "\n" 81 + "\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n" 82 + "\n" 83 + "\t@(#) FNV Version: %s\n"; 84 + static char *program; /* our name */ 85 + 86 + 87 + /* 88 + * test_fnv32 - test the FNV32 hash 89 + * 90 + * given: 91 + * hash_type type of FNV hash to test 92 + * init_hval initial hash value 93 + * mask lower bit mask 94 + * v_flag 1 => print test failure info on stderr 95 + * code 0 ==> generate FNV test vectors 96 + * 1 ==> validate against FNV test vectors 97 + * 98 + * returns: 0 ==> OK, else test vector failure number 99 + */ 100 + static int 101 + test_fnv32(enum fnv_type hash_type, Fnv32_t init_hval, 102 + Fnv32_t mask, int v_flag, int code) 103 + { 104 + struct test_vector *t; /* FNV test vestor */ 105 + Fnv32_t hval; /* current hash value */ 106 + int tstnum; /* test vector that failed, starting at 1 */ 107 + 108 + /* 109 + * print preamble if generating test vectors 110 + */ 111 + if (code == 0) { 112 + switch (hash_type) { 113 + case FNV0_32: 114 + printf("struct fnv0_32_test_vector fnv0_32_vector[] = {\n"); 115 + break; 116 + case FNV1_32: 117 + printf("struct fnv1_32_test_vector fnv1_32_vector[] = {\n"); 118 + break; 119 + case FNV1a_32: 120 + printf("struct fnv1a_32_test_vector fnv1a_32_vector[] = {\n"); 121 + break; 122 + default: 123 + unknown_hash_type(program, hash_type, 12); /* exit(12) */ 124 + /*NOTREACHED*/ 125 + } 126 + } 127 + 128 + /* 129 + * loop thru all test vectors 130 + */ 131 + for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) { 132 + 133 + /* 134 + * compute the FNV hash 135 + */ 136 + hval = init_hval; 137 + switch (hash_type) { 138 + case FNV0_32: 139 + case FNV1_32: 140 + hval = fnv_32_buf(t->buf, t->len, hval); 141 + break; 142 + case FNV1a_32: 143 + hval = fnv_32a_buf(t->buf, t->len, hval); 144 + break; 145 + default: 146 + unknown_hash_type(program, hash_type, 13); /* exit(13) */ 147 + /*NOTREACHED*/ 148 + } 149 + 150 + /* 151 + * print the vector 152 + */ 153 + switch (code) { 154 + case 0: /* generate the test vector */ 155 + printf(" { &fnv_test_str[%d], (Fnv32_t) 0x%08lxUL },\n", 156 + tstnum-1, hval & mask); 157 + break; 158 + case 1: /* validate against test vector */ 159 + switch (hash_type) { 160 + case FNV0_32: 161 + if ((hval&mask) != (fnv0_32_vector[tstnum-1].fnv0_32 & mask)) { 162 + if (v_flag) { 163 + fprintf(stderr, "%s: failed fnv0_32 test # %d\n", 164 + program, tstnum); 165 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 166 + fprintf(stderr, 167 + "%s: expected 0x%08lx != generated: 0x%08lx\n", 168 + program, (hval&mask), 169 + (fnv0_32_vector[tstnum-1].fnv0_32 & mask)); 170 + } 171 + return tstnum; 172 + } 173 + break; 174 + case FNV1_32: 175 + if ((hval&mask) != (fnv1_32_vector[tstnum-1].fnv1_32 & mask)) { 176 + if (v_flag) { 177 + fprintf(stderr, "%s: failed fnv1_32 test # %d\n", 178 + program, tstnum); 179 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 180 + fprintf(stderr, 181 + "%s: expected 0x%08lx != generated: 0x%08lx\n", 182 + program, (hval&mask), 183 + (fnv1_32_vector[tstnum-1].fnv1_32 & mask)); 184 + } 185 + return tstnum; 186 + } 187 + break; 188 + case FNV1a_32: 189 + if ((hval&mask) != (fnv1a_32_vector[tstnum-1].fnv1a_32 &mask)) { 190 + if (v_flag) { 191 + fprintf(stderr, "%s: failed fnv1a_32 test # %d\n", 192 + program, tstnum); 193 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 194 + fprintf(stderr, 195 + "%s: expected 0x%08lx != generated: 0x%08lx\n", 196 + program, (hval&mask), 197 + (fnv1a_32_vector[tstnum-1].fnv1a_32 & mask)); 198 + } 199 + return tstnum; 200 + } 201 + break; 202 + } 203 + break; 204 + default: 205 + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); 206 + exit(14); 207 + } 208 + } 209 + 210 + /* 211 + * print completion if generating test vectors 212 + */ 213 + if (code == 0) { 214 + printf(" { NULL, 0 }\n"); 215 + printf("};\n"); 216 + } 217 + 218 + /* 219 + * no failures, return code 0 ==> all OK 220 + */ 221 + return 0; 222 + } 223 + 224 + 225 + /* 226 + * main - the main function 227 + * 228 + * See the above usage for details. 229 + */ 230 + int 231 + main(int argc, char *argv[]) 232 + { 233 + char buf[BUF_SIZE+1]; /* read buffer */ 234 + int readcnt; /* number of characters written */ 235 + Fnv32_t hval; /* current hash value */ 236 + int s_flag = 0; /* 1 => -s was given, hash args as strings */ 237 + int m_flag = 0; /* 1 => print multiple hashes, one per arg */ 238 + int v_flag = 0; /* 1 => verbose hash print */ 239 + int b_flag = WIDTH; /* -b flag value */ 240 + int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */ 241 + enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */ 242 + Fnv32_t bmask; /* mask to apply to output */ 243 + extern char *optarg; /* option argument */ 244 + extern int optind; /* argv index of the next arg */ 245 + int fd; /* open file to process */ 246 + char *p; 247 + int i; 248 + 249 + /* 250 + * parse args 251 + */ 252 + program = argv[0]; 253 + while ((i = getopt(argc, argv, "b:mst:v")) != -1) { 254 + switch (i) { 255 + case 'b': /* bcnt bit mask count */ 256 + b_flag = atoi(optarg); 257 + break; 258 + case 'm': /* print multiple hashes, one per arg */ 259 + m_flag = 1; 260 + break; 261 + case 's': /* hash args as strings */ 262 + s_flag = 1; 263 + break; 264 + case 't': /* FNV test vector code */ 265 + t_flag = atoi(optarg); 266 + if (t_flag < 0 || t_flag > 1) { 267 + fprintf(stderr, "%s: -t code must be 0 or 1\n", program); 268 + fprintf(stderr, usage, program, FNV_VERSION); 269 + exit(1); 270 + } 271 + m_flag = 1; 272 + break; 273 + case 'v': /* verbose hash print */ 274 + m_flag = 1; 275 + v_flag = 1; 276 + break; 277 + default: 278 + fprintf(stderr, usage, program, FNV_VERSION); 279 + exit(1); 280 + } 281 + } 282 + /* -t code incompatible with -b, -m and args */ 283 + if (t_flag >= 0) { 284 + if (b_flag != WIDTH) { 285 + fprintf(stderr, "%s: -t code incompatible with -b\n", program); 286 + exit(2); 287 + } 288 + if (s_flag != 0) { 289 + fprintf(stderr, "%s: -t code incompatible with -s\n", program); 290 + exit(3); 291 + } 292 + if (optind < argc) { 293 + fprintf(stderr, "%s: -t code incompatible args\n", program); 294 + exit(4); 295 + } 296 + } 297 + /* -s requires at least 1 arg */ 298 + if (s_flag && optind >= argc) { 299 + fprintf(stderr, usage, program, FNV_VERSION); 300 + exit(5); 301 + } 302 + /* limit -b values */ 303 + if (b_flag < 0 || b_flag > WIDTH) { 304 + fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n", 305 + program, b_flag, WIDTH); 306 + exit(6); 307 + } 308 + if (b_flag == WIDTH) { 309 + bmask = (Fnv32_t)0xffffffff; 310 + } else { 311 + bmask = (Fnv32_t)((1 << b_flag) - 1); 312 + } 313 + 314 + /* 315 + * start with the initial basis depending on the hash type 316 + */ 317 + p = strrchr(program, '/'); 318 + if (p == NULL) { 319 + p = program; 320 + } else { 321 + ++p; 322 + } 323 + if (strcmp(p, "fnv032") == 0) { 324 + /* using non-recommended FNV-0 and zero initial basis */ 325 + hval = FNV0_32_INIT; 326 + hash_type = FNV0_32; 327 + } else if (strcmp(p, "fnv132") == 0) { 328 + /* using FNV-1 and non-zero initial basis */ 329 + hval = FNV1_32_INIT; 330 + hash_type = FNV1_32; 331 + } else if (strcmp(p, "fnv1a32") == 0) { 332 + /* start with the FNV-1a initial basis */ 333 + hval = FNV1_32A_INIT; 334 + hash_type = FNV1a_32; 335 + } else { 336 + fprintf(stderr, "%s: unknown program name, unknown hash type\n", 337 + program); 338 + exit(7); 339 + } 340 + 341 + /* 342 + * FNV test vector processing, if needed 343 + */ 344 + if (t_flag >= 0) { 345 + int code; /* test vector that failed, starting at 1 */ 346 + 347 + /* 348 + * perform all tests 349 + */ 350 + code = test_fnv32(hash_type, hval, bmask, v_flag, t_flag); 351 + 352 + /* 353 + * evaluate the tests 354 + */ 355 + if (code == 0) { 356 + if (v_flag) { 357 + printf("passed\n"); 358 + } 359 + exit(0); 360 + } else { 361 + printf("failed vector (1 is 1st test): %d\n", code); 362 + exit(8); 363 + } 364 + } 365 + 366 + /* 367 + * string hashing 368 + */ 369 + if (s_flag) { 370 + 371 + /* hash any other strings */ 372 + for (i=optind; i < argc; ++i) { 373 + switch (hash_type) { 374 + case FNV0_32: 375 + case FNV1_32: 376 + hval = fnv_32_str(argv[i], hval); 377 + break; 378 + case FNV1a_32: 379 + hval = fnv_32a_str(argv[i], hval); 380 + break; 381 + default: 382 + unknown_hash_type(program, hash_type, 9); /* exit(9) */ 383 + /*NOTREACHED*/ 384 + } 385 + if (m_flag) { 386 + print_fnv32(hval, bmask, v_flag, argv[i]); 387 + } 388 + } 389 + 390 + 391 + /* 392 + * file hashing 393 + */ 394 + } else { 395 + 396 + /* 397 + * case: process only stdin 398 + */ 399 + if (optind >= argc) { 400 + 401 + /* case: process only stdin */ 402 + while ((readcnt = read(0, buf, BUF_SIZE)) > 0) { 403 + switch (hash_type) { 404 + case FNV0_32: 405 + case FNV1_32: 406 + hval = fnv_32_buf(buf, readcnt, hval); 407 + break; 408 + case FNV1a_32: 409 + hval = fnv_32a_buf(buf, readcnt, hval); 410 + break; 411 + default: 412 + unknown_hash_type(program, hash_type, 10); /* exit(10) */ 413 + /*NOTREACHED*/ 414 + } 415 + } 416 + if (m_flag) { 417 + print_fnv32(hval, bmask, v_flag, "(stdin)"); 418 + } 419 + 420 + } else { 421 + 422 + /* 423 + * process any other files 424 + */ 425 + for (i=optind; i < argc; ++i) { 426 + 427 + /* open the file */ 428 + fd = open(argv[i], O_RDONLY); 429 + if (fd < 0) { 430 + fprintf(stderr, "%s: unable to open file: %s\n", 431 + program, argv[i]); 432 + exit(4); 433 + } 434 + 435 + /* hash the file */ 436 + while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) { 437 + switch (hash_type) { 438 + case FNV0_32: 439 + case FNV1_32: 440 + hval = fnv_32_buf(buf, readcnt, hval); 441 + break; 442 + case FNV1a_32: 443 + hval = fnv_32a_buf(buf, readcnt, hval); 444 + break; 445 + default: 446 + unknown_hash_type(program, hash_type, 11);/* exit(11) */ 447 + /*NOTREACHED*/ 448 + } 449 + } 450 + 451 + /* finish processing the file */ 452 + if (m_flag) { 453 + print_fnv32(hval, bmask, v_flag, argv[i]); 454 + } 455 + close(fd); 456 + } 457 + } 458 + } 459 + 460 + /* 461 + * report hash and exit 462 + */ 463 + if (!m_flag) { 464 + print_fnv32(hval, bmask, v_flag, ""); 465 + } 466 + return 0; /* exit(0); */ 467 + }
+591
lib/fnv/fnv64.c
··· 1 + /* 2 + * fnv_64 - 64 bit Fowler/Noll/Vo hash of a buffer or string 3 + * 4 + * @(#) $Revision: 5.5 $ 5 + * @(#) $Id: fnv64.c,v 5.5 2012/03/21 01:38:12 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv64.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * Please do not copyright this code. This code is in the public domain. 37 + * 38 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 39 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 40 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 41 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 42 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 43 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 44 + * PERFORMANCE OF THIS SOFTWARE. 45 + * 46 + * By: 47 + * chongo <Landon Curt Noll> /\oo/\ 48 + * http://www.isthe.com/chongo/ 49 + * 50 + * Share and Enjoy! :-) 51 + */ 52 + 53 + #include <stdio.h> 54 + #include <unistd.h> 55 + #include <stdlib.h> 56 + #include <sys/types.h> 57 + #include <sys/stat.h> 58 + #include <fcntl.h> 59 + #include <string.h> 60 + #include "longlong.h" 61 + #include "fnv.h" 62 + 63 + #define WIDTH 64 /* bit width of hash */ 64 + 65 + #define BUF_SIZE (32*1024) /* number of bytes to hash at a time */ 66 + 67 + static char *usage = 68 + "usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n" 69 + "\n" 70 + "\t-b bcnt\tmask off all but the lower bcnt bits (default 64)\n" 71 + "\t-m\tmultiple hashes, one per line for each arg\n" 72 + "\t-s\thash arg as a string (ignoring terminating NUL bytes)\n" 73 + "\t-t code\t test hash code: (0 ==> generate test vectors\n" 74 + "\t\t\t\t 1 ==> validate against FNV test vectors)\n" 75 + "\t-v\tverbose mode, print arg after hash (implies -m)\n" 76 + "\targ\tstring (if -s was given) or filename (default stdin)\n" 77 + "\n" 78 + "\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n" 79 + "\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n" 80 + "\n" 81 + "\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n" 82 + "\n" 83 + "\t@(#) FNV Version: %s\n"; 84 + static char *program; /* our name */ 85 + 86 + 87 + /* 88 + * test_fnv64 - test the FNV64 hash 89 + * 90 + * given: 91 + * hash_type type of FNV hash to test 92 + * init_hval initial hash value 93 + * mask lower bit mask 94 + * v_flag 1 => print test failure info on stderr 95 + * code 0 ==> generate FNV test vectors 96 + * 1 ==> validate against FNV test vectors 97 + * 98 + * returns: 0 ==> OK, else test vector failure number 99 + */ 100 + static int 101 + test_fnv64(enum fnv_type hash_type, Fnv64_t init_hval, 102 + Fnv64_t mask, int v_flag, int code) 103 + { 104 + struct test_vector *t; /* FNV test vestor */ 105 + Fnv64_t hval; /* current hash value */ 106 + int tstnum; /* test vector that failed, starting at 1 */ 107 + 108 + /* 109 + * print preamble if generating test vectors 110 + */ 111 + if (code == 0) { 112 + switch (hash_type) { 113 + case FNV0_64: 114 + printf("struct fnv0_64_test_vector fnv0_64_vector[] = {\n"); 115 + break; 116 + case FNV1_64: 117 + printf("struct fnv1_64_test_vector fnv1_64_vector[] = {\n"); 118 + break; 119 + case FNV1a_64: 120 + printf("struct fnv1a_64_test_vector fnv1a_64_vector[] = {\n"); 121 + break; 122 + default: 123 + unknown_hash_type(program, hash_type, 12); /* exit(12) */ 124 + /*NOTREACHED*/ 125 + } 126 + } 127 + 128 + /* 129 + * loop thru all test vectors 130 + */ 131 + for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) { 132 + 133 + /* 134 + * compute the FNV hash 135 + */ 136 + hval = init_hval; 137 + switch (hash_type) { 138 + case FNV0_64: 139 + case FNV1_64: 140 + hval = fnv_64_buf(t->buf, t->len, hval); 141 + break; 142 + case FNV1a_64: 143 + hval = fnv_64a_buf(t->buf, t->len, hval); 144 + break; 145 + default: 146 + unknown_hash_type(program, hash_type, 13); /* exit(13) */ 147 + /*NOTREACHED*/ 148 + } 149 + 150 + /* 151 + * print the vector 152 + */ 153 + #if defined(HAVE_64BIT_LONG_LONG) 154 + /* 155 + * HAVE_64BIT_LONG_LONG testing 156 + */ 157 + switch (code) { 158 + case 0: /* generate the test vector */ 159 + printf(" { &fnv_test_str[%d], (Fnv64_t) 0x%016llxULL },\n", 160 + tstnum-1, hval & mask); 161 + break; 162 + 163 + case 1: /* validate against test vector */ 164 + switch (hash_type) { 165 + case FNV0_64: 166 + if ((hval&mask) != (fnv0_64_vector[tstnum-1].fnv0_64 & mask)) { 167 + if (v_flag) { 168 + fprintf(stderr, "%s: failed fnv0_64 test # %d\n", 169 + program, tstnum); 170 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 171 + fprintf(stderr, 172 + "%s: expected 0x%016llx != generated: 0x%016llx\n", 173 + program, 174 + (hval&mask), 175 + (fnv0_64_vector[tstnum-1].fnv0_64 & mask)); 176 + } 177 + return tstnum; 178 + } 179 + break; 180 + case FNV1_64: 181 + if ((hval&mask) != (fnv1_64_vector[tstnum-1].fnv1_64 & mask)) { 182 + if (v_flag) { 183 + fprintf(stderr, "%s: failed fnv1_64 test # %d\n", 184 + program, tstnum); 185 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 186 + fprintf(stderr, 187 + "%s: expected 0x%016llx != generated: 0x%016llx\n", 188 + program, 189 + (hval&mask), 190 + (fnv1_64_vector[tstnum-1].fnv1_64 & mask)); 191 + } 192 + return tstnum; 193 + } 194 + break; 195 + case FNV1a_64: 196 + if ((hval&mask) != (fnv1a_64_vector[tstnum-1].fnv1a_64 &mask)) { 197 + if (v_flag) { 198 + fprintf(stderr, "%s: failed fnv1a_64 test # %d\n", 199 + program, tstnum); 200 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 201 + fprintf(stderr, 202 + "%s: expected 0x%016llx != generated: 0x%016llx\n", 203 + program, 204 + (hval&mask), 205 + (fnv1a_64_vector[tstnum-1].fnv1a_64 & mask)); 206 + } 207 + return tstnum; 208 + } 209 + break; 210 + } 211 + break; 212 + 213 + default: 214 + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); 215 + exit(14); 216 + } 217 + #else /* HAVE_64BIT_LONG_LONG */ 218 + /* 219 + * non HAVE_64BIT_LONG_LONG testing 220 + */ 221 + switch (code) { 222 + case 0: /* generate the test vector */ 223 + printf(" { &fnv_test_str[%d], " 224 + "(Fnv64_t) {0x%08lxUL, 0x%08lxUL} },\n", 225 + tstnum-1, 226 + (hval.w32[0] & mask.w32[0]), 227 + (hval.w32[1] & mask.w32[1])); 228 + break; 229 + 230 + case 1: /* validate against test vector */ 231 + switch (hash_type) { 232 + case FNV0_64: 233 + if (((hval.w32[0] & mask.w32[0]) != 234 + (fnv0_64_vector[tstnum-1].fnv0_64.w32[0] & 235 + mask.w32[0])) && 236 + ((hval.w32[1] & mask.w32[1]) != 237 + (fnv0_64_vector[tstnum-1].fnv0_64.w32[1] & 238 + mask.w32[1]))) { 239 + if (v_flag) { 240 + fprintf(stderr, "%s: failed fnv0_64 test # %d\n", 241 + program, tstnum); 242 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 243 + fprintf(stderr, 244 + "%s: expected 0x%08llx%08llx != " 245 + "generated: 0x%08llx%08llx\n", 246 + program, 247 + (hval.w32[0] & mask.w32[0]), 248 + (hval.w32[1] & mask.w32[1]), 249 + ((fnv0_64_vector[tstnum-1].fnv0_64.w32[0] & 250 + mask.w32[0])), 251 + ((fnv0_64_vector[tstnum-1].fnv0_64.w32[1] & 252 + mask.w32[1]))); 253 + } 254 + return tstnum; 255 + } 256 + break; 257 + case FNV1_64: 258 + if (((hval.w32[0] & mask.w32[0]) != 259 + (fnv1_64_vector[tstnum-1].fnv1_64.w32[0] & 260 + mask.w32[0])) && 261 + ((hval.w32[1] & mask.w32[1]) != 262 + (fnv1_64_vector[tstnum-1].fnv1_64.w32[1] & 263 + mask.w32[1]))) { 264 + if (v_flag) { 265 + fprintf(stderr, "%s: failed fnv1_64 test # %d\n", 266 + program, tstnum); 267 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 268 + fprintf(stderr, 269 + "%s: expected 0x%08llx%08llx != " 270 + "generated: 0x%08llx%08llx\n", 271 + program, 272 + (hval.w32[0] & mask.w32[0]), 273 + (hval.w32[1] & mask.w32[1]), 274 + ((fnv1_64_vector[tstnum-1].fnv1_64.w32[0] & 275 + mask.w32[0])), 276 + ((fnv1_64_vector[tstnum-1].fnv1_64.w32[1] & 277 + mask.w32[1]))); 278 + } 279 + return tstnum; 280 + } 281 + break; 282 + case FNV1a_64: 283 + if (((hval.w32[0] & mask.w32[0]) != 284 + (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] & 285 + mask.w32[0])) && 286 + ((hval.w32[1] & mask.w32[1]) != 287 + (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] & 288 + mask.w32[1]))) { 289 + if (v_flag) { 290 + fprintf(stderr, "%s: failed fnv1a_64 test # %d\n", 291 + program, tstnum); 292 + fprintf(stderr, "%s: test # 1 is 1st test\n", program); 293 + fprintf(stderr, 294 + "%s: expected 0x%08llx%08llx != " 295 + "generated: 0x%08llx%08llx\n", 296 + program, 297 + (hval.w32[0] & mask.w32[0]), 298 + (hval.w32[1] & mask.w32[1]), 299 + ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] & 300 + mask.w32[0])), 301 + ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] & 302 + mask.w32[1]))); 303 + } 304 + return tstnum; 305 + } 306 + break; 307 + } 308 + break; 309 + 310 + default: 311 + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); 312 + exit(15); 313 + } 314 + #endif /* HAVE_64BIT_LONG_LONG */ 315 + } 316 + 317 + /* 318 + * print completion if generating test vectors 319 + */ 320 + if (code == 0) { 321 + #if defined(HAVE_64BIT_LONG_LONG) 322 + printf(" { NULL, (Fnv64_t) 0 }\n"); 323 + #else /* HAVE_64BIT_LONG_LONG */ 324 + printf(" { NULL, (Fnv64_t) {0,0} }\n"); 325 + #endif /* HAVE_64BIT_LONG_LONG */ 326 + printf("};\n"); 327 + } 328 + 329 + /* 330 + * no failures, return code 0 ==> all OK 331 + */ 332 + return 0; 333 + } 334 + 335 + 336 + /* 337 + * main - the main function 338 + * 339 + * See the above usage for details. 340 + */ 341 + int 342 + main(int argc, char *argv[]) 343 + { 344 + char buf[BUF_SIZE+1]; /* read buffer */ 345 + int readcnt; /* number of characters written */ 346 + Fnv64_t hval; /* current hash value */ 347 + int s_flag = 0; /* 1 => -s was given, hash args as strings */ 348 + int m_flag = 0; /* 1 => print multiple hashes, one per arg */ 349 + int v_flag = 0; /* 1 => verbose hash print */ 350 + int b_flag = WIDTH; /* -b flag value */ 351 + int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */ 352 + enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */ 353 + Fnv64_t bmask; /* mask to apply to output */ 354 + extern char *optarg; /* option argument */ 355 + extern int optind; /* argv index of the next arg */ 356 + int fd; /* open file to process */ 357 + char *p; 358 + int i; 359 + 360 + /* 361 + * parse args 362 + */ 363 + program = argv[0]; 364 + while ((i = getopt(argc, argv, "b:mst:v")) != -1) { 365 + switch (i) { 366 + case 'b': /* bcnt bit mask count */ 367 + b_flag = atoi(optarg); 368 + break; 369 + case 'm': /* print multiple hashes, one per arg */ 370 + m_flag = 1; 371 + break; 372 + case 's': /* hash args as strings */ 373 + s_flag = 1; 374 + break; 375 + case 't': /* FNV test vector code */ 376 + t_flag = atoi(optarg); 377 + if (t_flag < 0 || t_flag > 1) { 378 + fprintf(stderr, "%s: -t code must be 0 or 1\n", program); 379 + fprintf(stderr, usage, program, FNV_VERSION); 380 + exit(1); 381 + } 382 + m_flag = 1; 383 + break; 384 + case 'v': /* verbose hash print */ 385 + m_flag = 1; 386 + v_flag = 1; 387 + break; 388 + default: 389 + fprintf(stderr, usage, program, FNV_VERSION); 390 + exit(1); 391 + } 392 + } 393 + /* -t code incompatible with -b, -m and args */ 394 + if (t_flag >= 0) { 395 + if (b_flag != WIDTH) { 396 + fprintf(stderr, "%s: -t code incompatible with -b\n", program); 397 + exit(2); 398 + } 399 + if (s_flag != 0) { 400 + fprintf(stderr, "%s: -t code incompatible with -s\n", program); 401 + exit(3); 402 + } 403 + if (optind < argc) { 404 + fprintf(stderr, "%s: -t code incompatible args\n", program); 405 + exit(4); 406 + } 407 + } 408 + /* -s requires at least 1 arg */ 409 + if (s_flag && optind >= argc) { 410 + fprintf(stderr, usage, program, FNV_VERSION); 411 + exit(5); 412 + } 413 + /* limit -b values */ 414 + if (b_flag < 0 || b_flag > WIDTH) { 415 + fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n", 416 + program, b_flag, WIDTH); 417 + exit(6); 418 + } 419 + #if defined(HAVE_64BIT_LONG_LONG) 420 + if (b_flag == WIDTH) { 421 + bmask = (Fnv64_t)0xffffffffffffffffULL; 422 + } else { 423 + bmask = (Fnv64_t)((1ULL << b_flag) - 1ULL); 424 + } 425 + #else /* HAVE_64BIT_LONG_LONG */ 426 + if (b_flag == WIDTH) { 427 + bmask.w32[0] = 0xffffffffUL; 428 + bmask.w32[1] = 0xffffffffUL; 429 + } else if (b_flag >= WIDTH/2) { 430 + bmask.w32[0] = 0xffffffffUL; 431 + bmask.w32[1] = ((1UL << (b_flag-(WIDTH/2))) - 1UL); 432 + } else { 433 + bmask.w32[0] = ((1UL << b_flag) - 1UL); 434 + bmask.w32[1] = 0UL; 435 + } 436 + #endif /* HAVE_64BIT_LONG_LONG */ 437 + 438 + /* 439 + * start with the initial basis depending on the hash type 440 + */ 441 + p = strrchr(program, '/'); 442 + if (p == NULL) { 443 + p = program; 444 + } else { 445 + ++p; 446 + } 447 + if (strcmp(p, "fnv064") == 0 || strcmp(p, "no64bit_fnv064") == 0) { 448 + /* using non-recommended FNV-0 and zero initial basis */ 449 + hval = FNV0_64_INIT; 450 + hash_type = FNV0_64; 451 + } else if (strcmp(p, "fnv164") == 0 || strcmp(p, "no64bit_fnv164") == 0) { 452 + /* using FNV-1 and non-zero initial basis */ 453 + hval = FNV1_64_INIT; 454 + hash_type = FNV1_64; 455 + } else if (strcmp(p, "fnv1a64") == 0 || strcmp(p, "no64bit_fnv1a64") == 0) { 456 + /* start with the FNV-1a initial basis */ 457 + hval = FNV1A_64_INIT; 458 + hash_type = FNV1a_64; 459 + } else { 460 + fprintf(stderr, "%s: unknown program name, unknown hash type\n", 461 + program); 462 + exit(7); 463 + } 464 + 465 + /* 466 + * FNV test vector processing, if needed 467 + */ 468 + if (t_flag >= 0) { 469 + int code; /* test vector that failed, starting at 1 */ 470 + 471 + /* 472 + * perform all tests 473 + */ 474 + code = test_fnv64(hash_type, hval, bmask, v_flag, t_flag); 475 + 476 + /* 477 + * evaluate the tests 478 + */ 479 + if (code == 0) { 480 + if (v_flag) { 481 + printf("passed\n"); 482 + } 483 + exit(0); 484 + } else { 485 + printf("failed vector (1 is 1st test): %d\n", code); 486 + exit(8); 487 + } 488 + } 489 + 490 + /* 491 + * string hashing 492 + */ 493 + if (s_flag) { 494 + 495 + /* hash any other strings */ 496 + for (i=optind; i < argc; ++i) { 497 + switch (hash_type) { 498 + case FNV0_64: 499 + case FNV1_64: 500 + hval = fnv_64_str(argv[i], hval); 501 + break; 502 + case FNV1a_64: 503 + hval = fnv_64a_str(argv[i], hval); 504 + break; 505 + default: 506 + unknown_hash_type(program, hash_type, 9); /* exit(9) */ 507 + /*NOTREACHED*/ 508 + } 509 + if (m_flag) { 510 + print_fnv64(hval, bmask, v_flag, argv[i]); 511 + } 512 + } 513 + 514 + 515 + /* 516 + * file hashing 517 + */ 518 + } else { 519 + 520 + /* 521 + * case: process only stdin 522 + */ 523 + if (optind >= argc) { 524 + 525 + /* case: process only stdin */ 526 + while ((readcnt = read(0, buf, BUF_SIZE)) > 0) { 527 + switch (hash_type) { 528 + case FNV0_64: 529 + case FNV1_64: 530 + hval = fnv_64_buf(buf, readcnt, hval); 531 + break; 532 + case FNV1a_64: 533 + hval = fnv_64a_buf(buf, readcnt, hval); 534 + break; 535 + default: 536 + unknown_hash_type(program, hash_type, 10); /* exit(10) */ 537 + /*NOTREACHED*/ 538 + } 539 + } 540 + if (m_flag) { 541 + print_fnv64(hval, bmask, v_flag, "(stdin)"); 542 + } 543 + 544 + } else { 545 + 546 + /* 547 + * process any other files 548 + */ 549 + for (i=optind; i < argc; ++i) { 550 + 551 + /* open the file */ 552 + fd = open(argv[i], O_RDONLY); 553 + if (fd < 0) { 554 + fprintf(stderr, "%s: unable to open file: %s\n", 555 + program, argv[i]); 556 + exit(4); 557 + } 558 + 559 + /* hash the file */ 560 + while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) { 561 + switch (hash_type) { 562 + case FNV0_64: 563 + case FNV1_64: 564 + hval = fnv_64_buf(buf, readcnt, hval); 565 + break; 566 + case FNV1a_64: 567 + hval = fnv_64a_buf(buf, readcnt, hval); 568 + break; 569 + default: 570 + unknown_hash_type(program, hash_type, 11);/* exit(11) */ 571 + /*NOTREACHED*/ 572 + } 573 + } 574 + 575 + /* finish processing the file */ 576 + if (m_flag) { 577 + print_fnv64(hval, bmask, v_flag, argv[i]); 578 + } 579 + close(fd); 580 + } 581 + } 582 + } 583 + 584 + /* 585 + * report hash and exit 586 + */ 587 + if (!m_flag) { 588 + print_fnv64(hval, bmask, v_flag, ""); 589 + } 590 + return 0; /* exit(0); */ 591 + }
+156
lib/fnv/hash_32.c
··· 1 + /* 2 + * hash_32 - 32 bit Fowler/Noll/Vo hash code 3 + * 4 + * @(#) $Revision: 5.1 $ 5 + * @(#) $Id: hash_32.c,v 5.1 2009/06/30 09:13:32 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + *** 34 + * 35 + * NOTE: The FNV-0 historic hash is not recommended. One should use 36 + * the FNV-1 hash instead. 37 + * 38 + * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 39 + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 40 + * 41 + * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 42 + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 43 + * 44 + *** 45 + * 46 + * Please do not copyright this code. This code is in the public domain. 47 + * 48 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 49 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 50 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 51 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 52 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 53 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 54 + * PERFORMANCE OF THIS SOFTWARE. 55 + * 56 + * By: 57 + * chongo <Landon Curt Noll> /\oo/\ 58 + * http://www.isthe.com/chongo/ 59 + * 60 + * Share and Enjoy! :-) 61 + */ 62 + 63 + #include <stdlib.h> 64 + #include "fnv.h" 65 + 66 + 67 + /* 68 + * 32 bit magic FNV-0 and FNV-1 prime 69 + */ 70 + #define FNV_32_PRIME ((Fnv32_t)0x01000193) 71 + 72 + 73 + /* 74 + * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer 75 + * 76 + * input: 77 + * buf - start of buffer to hash 78 + * len - length of buffer in octets 79 + * hval - previous hash value or 0 if first call 80 + * 81 + * returns: 82 + * 32 bit hash as a static hash type 83 + * 84 + * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 85 + * argument on the first call to either fnv_32_buf() or fnv_32_str(). 86 + * 87 + * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 88 + * argument on the first call to either fnv_32_buf() or fnv_32_str(). 89 + */ 90 + Fnv32_t 91 + fnv_32_buf(void *buf, size_t len, Fnv32_t hval) 92 + { 93 + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 94 + unsigned char *be = bp + len; /* beyond end of buffer */ 95 + 96 + /* 97 + * FNV-1 hash each octet in the buffer 98 + */ 99 + while (bp < be) { 100 + 101 + /* multiply by the 32 bit FNV magic prime mod 2^32 */ 102 + #if defined(NO_FNV_GCC_OPTIMIZATION) 103 + hval *= FNV_32_PRIME; 104 + #else 105 + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 106 + #endif 107 + 108 + /* xor the bottom with the current octet */ 109 + hval ^= (Fnv32_t)*bp++; 110 + } 111 + 112 + /* return our new hash value */ 113 + return hval; 114 + } 115 + 116 + 117 + /* 118 + * fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string 119 + * 120 + * input: 121 + * str - string to hash 122 + * hval - previous hash value or 0 if first call 123 + * 124 + * returns: 125 + * 32 bit hash as a static hash type 126 + * 127 + * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 128 + * argument on the first call to either fnv_32_buf() or fnv_32_str(). 129 + * 130 + * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 131 + * argument on the first call to either fnv_32_buf() or fnv_32_str(). 132 + */ 133 + Fnv32_t 134 + fnv_32_str(char *str, Fnv32_t hval) 135 + { 136 + unsigned char *s = (unsigned char *)str; /* unsigned string */ 137 + 138 + /* 139 + * FNV-1 hash each octet in the buffer 140 + */ 141 + while (*s) { 142 + 143 + /* multiply by the 32 bit FNV magic prime mod 2^32 */ 144 + #if defined(NO_FNV_GCC_OPTIMIZATION) 145 + hval *= FNV_32_PRIME; 146 + #else 147 + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 148 + #endif 149 + 150 + /* xor the bottom with the current octet */ 151 + hval ^= (Fnv32_t)*s++; 152 + } 153 + 154 + /* return our new hash value */ 155 + return hval; 156 + }
+144
lib/fnv/hash_32a.c
··· 1 + /* 2 + * hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code 3 + * 4 + * @(#) $Revision: 5.1 $ 5 + * @(#) $Id: hash_32a.c,v 5.1 2009/06/30 09:13:32 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32a.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + *** 34 + * 35 + * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the 36 + * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). 37 + * 38 + *** 39 + * 40 + * Please do not copyright this code. This code is in the public domain. 41 + * 42 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 43 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 44 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 45 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 46 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 47 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 48 + * PERFORMANCE OF THIS SOFTWARE. 49 + * 50 + * By: 51 + * chongo <Landon Curt Noll> /\oo/\ 52 + * http://www.isthe.com/chongo/ 53 + * 54 + * Share and Enjoy! :-) 55 + */ 56 + 57 + #include <stdlib.h> 58 + #include "fnv.h" 59 + 60 + 61 + /* 62 + * 32 bit magic FNV-1a prime 63 + */ 64 + #define FNV_32_PRIME ((Fnv32_t)0x01000193) 65 + 66 + 67 + /* 68 + * fnv_32a_buf - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a buffer 69 + * 70 + * input: 71 + * buf - start of buffer to hash 72 + * len - length of buffer in octets 73 + * hval - previous hash value or 0 if first call 74 + * 75 + * returns: 76 + * 32 bit hash as a static hash type 77 + * 78 + * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the 79 + * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). 80 + */ 81 + Fnv32_t 82 + fnv_32a_buf(void *buf, size_t len, Fnv32_t hval) 83 + { 84 + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 85 + unsigned char *be = bp + len; /* beyond end of buffer */ 86 + 87 + /* 88 + * FNV-1a hash each octet in the buffer 89 + */ 90 + while (bp < be) { 91 + 92 + /* xor the bottom with the current octet */ 93 + hval ^= (Fnv32_t)*bp++; 94 + 95 + /* multiply by the 32 bit FNV magic prime mod 2^32 */ 96 + #if defined(NO_FNV_GCC_OPTIMIZATION) 97 + hval *= FNV_32_PRIME; 98 + #else 99 + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 100 + #endif 101 + } 102 + 103 + /* return our new hash value */ 104 + return hval; 105 + } 106 + 107 + 108 + /* 109 + * fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string 110 + * 111 + * input: 112 + * str - string to hash 113 + * hval - previous hash value or 0 if first call 114 + * 115 + * returns: 116 + * 32 bit hash as a static hash type 117 + * 118 + * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the 119 + * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). 120 + */ 121 + Fnv32_t 122 + fnv_32a_str(char *str, Fnv32_t hval) 123 + { 124 + unsigned char *s = (unsigned char *)str; /* unsigned string */ 125 + 126 + /* 127 + * FNV-1a hash each octet in the buffer 128 + */ 129 + while (*s) { 130 + 131 + /* xor the bottom with the current octet */ 132 + hval ^= (Fnv32_t)*s++; 133 + 134 + /* multiply by the 32 bit FNV magic prime mod 2^32 */ 135 + #if defined(NO_FNV_GCC_OPTIMIZATION) 136 + hval *= FNV_32_PRIME; 137 + #else 138 + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 139 + #endif 140 + } 141 + 142 + /* return our new hash value */ 143 + return hval; 144 + }
+312
lib/fnv/hash_64.c
··· 1 + /* 2 + * hash_64 - 64 bit Fowler/Noll/Vo-0 hash code 3 + * 4 + * @(#) $Revision: 5.1 $ 5 + * @(#) $Id: hash_64.c,v 5.1 2009/06/30 09:01:38 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * NOTE: The FNV-0 historic hash is not recommended. One should use 37 + * the FNV-1 hash instead. 38 + * 39 + * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the 40 + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 41 + * 42 + * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the 43 + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 44 + * 45 + *** 46 + * 47 + * Please do not copyright this code. This code is in the public domain. 48 + * 49 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 50 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 51 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 52 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 53 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 54 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 55 + * PERFORMANCE OF THIS SOFTWARE. 56 + * 57 + * By: 58 + * chongo <Landon Curt Noll> /\oo/\ 59 + * http://www.isthe.com/chongo/ 60 + * 61 + * Share and Enjoy! :-) 62 + */ 63 + 64 + #include <stdlib.h> 65 + #include "fnv.h" 66 + 67 + 68 + /* 69 + * FNV-0 defines the initial basis to be zero 70 + */ 71 + #if !defined(HAVE_64BIT_LONG_LONG) 72 + const Fnv64_t fnv0_64_init = { 0UL, 0UL }; 73 + #endif /* ! HAVE_64BIT_LONG_LONG */ 74 + 75 + 76 + /* 77 + * FNV-1 defines the initial basis to be non-zero 78 + */ 79 + #if !defined(HAVE_64BIT_LONG_LONG) 80 + const Fnv64_t fnv1_64_init = { 0x84222325UL, 0xcbf29ce4UL }; 81 + #endif /* ! HAVE_64BIT_LONG_LONG */ 82 + 83 + 84 + /* 85 + * 64 bit magic FNV-0 and FNV-1 prime 86 + */ 87 + #if defined(HAVE_64BIT_LONG_LONG) 88 + #define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL) 89 + #else /* HAVE_64BIT_LONG_LONG */ 90 + #define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */ 91 + #define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */ 92 + #endif /* HAVE_64BIT_LONG_LONG */ 93 + 94 + 95 + /* 96 + * fnv_64_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer 97 + * 98 + * input: 99 + * buf - start of buffer to hash 100 + * len - length of buffer in octets 101 + * hval - previous hash value or 0 if first call 102 + * 103 + * returns: 104 + * 64 bit hash as a static hash type 105 + * 106 + * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval 107 + * argument on the first call to either fnv_64_buf() or fnv_64_str(). 108 + * 109 + * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval 110 + * argument on the first call to either fnv_64_buf() or fnv_64_str(). 111 + */ 112 + Fnv64_t 113 + fnv_64_buf(void *buf, size_t len, Fnv64_t hval) 114 + { 115 + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 116 + unsigned char *be = bp + len; /* beyond end of buffer */ 117 + 118 + #if defined(HAVE_64BIT_LONG_LONG) 119 + 120 + /* 121 + * FNV-1 hash each octet of the buffer 122 + */ 123 + while (bp < be) { 124 + 125 + /* multiply by the 64 bit FNV magic prime mod 2^64 */ 126 + #if defined(NO_FNV_GCC_OPTIMIZATION) 127 + hval *= FNV_64_PRIME; 128 + #else /* NO_FNV_GCC_OPTIMIZATION */ 129 + hval += (hval << 1) + (hval << 4) + (hval << 5) + 130 + (hval << 7) + (hval << 8) + (hval << 40); 131 + #endif /* NO_FNV_GCC_OPTIMIZATION */ 132 + 133 + /* xor the bottom with the current octet */ 134 + hval ^= (Fnv64_t)*bp++; 135 + } 136 + 137 + #else /* HAVE_64BIT_LONG_LONG */ 138 + 139 + unsigned long val[4]; /* hash value in base 2^16 */ 140 + unsigned long tmp[4]; /* tmp 64 bit value */ 141 + 142 + /* 143 + * Convert Fnv64_t hval into a base 2^16 array 144 + */ 145 + val[0] = hval.w32[0]; 146 + val[1] = (val[0] >> 16); 147 + val[0] &= 0xffff; 148 + val[2] = hval.w32[1]; 149 + val[3] = (val[2] >> 16); 150 + val[2] &= 0xffff; 151 + 152 + /* 153 + * FNV-1 hash each octet of the buffer 154 + */ 155 + while (bp < be) { 156 + 157 + /* 158 + * multiply by the 64 bit FNV magic prime mod 2^64 159 + * 160 + * Using 0x100000001b3 we have the following digits base 2^16: 161 + * 162 + * 0x0 0x100 0x0 0x1b3 163 + * 164 + * which is the same as: 165 + * 166 + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW 167 + */ 168 + /* multiply by the lowest order digit base 2^16 */ 169 + tmp[0] = val[0] * FNV_64_PRIME_LOW; 170 + tmp[1] = val[1] * FNV_64_PRIME_LOW; 171 + tmp[2] = val[2] * FNV_64_PRIME_LOW; 172 + tmp[3] = val[3] * FNV_64_PRIME_LOW; 173 + /* multiply by the other non-zero digit */ 174 + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ 175 + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ 176 + /* propagate carries */ 177 + tmp[1] += (tmp[0] >> 16); 178 + val[0] = tmp[0] & 0xffff; 179 + tmp[2] += (tmp[1] >> 16); 180 + val[1] = tmp[1] & 0xffff; 181 + val[3] = tmp[3] + (tmp[2] >> 16); 182 + val[2] = tmp[2] & 0xffff; 183 + /* 184 + * Doing a val[3] &= 0xffff; is not really needed since it simply 185 + * removes multiples of 2^64. We can discard these excess bits 186 + * outside of the loop when we convert to Fnv64_t. 187 + */ 188 + 189 + /* xor the bottom with the current octet */ 190 + val[0] ^= (unsigned long)*bp++; 191 + } 192 + 193 + /* 194 + * Convert base 2^16 array back into an Fnv64_t 195 + */ 196 + hval.w32[1] = ((val[3]<<16) | val[2]); 197 + hval.w32[0] = ((val[1]<<16) | val[0]); 198 + 199 + #endif /* HAVE_64BIT_LONG_LONG */ 200 + 201 + /* return our new hash value */ 202 + return hval; 203 + } 204 + 205 + 206 + /* 207 + * fnv_64_str - perform a 64 bit Fowler/Noll/Vo hash on a buffer 208 + * 209 + * input: 210 + * buf - start of buffer to hash 211 + * hval - previous hash value or 0 if first call 212 + * 213 + * returns: 214 + * 64 bit hash as a static hash type 215 + * 216 + * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval 217 + * argument on the first call to either fnv_64_buf() or fnv_64_str(). 218 + * 219 + * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval 220 + * argument on the first call to either fnv_64_buf() or fnv_64_str(). 221 + */ 222 + Fnv64_t 223 + fnv_64_str(char *str, Fnv64_t hval) 224 + { 225 + unsigned char *s = (unsigned char *)str; /* unsigned string */ 226 + 227 + #if defined(HAVE_64BIT_LONG_LONG) 228 + 229 + /* 230 + * FNV-1 hash each octet of the string 231 + */ 232 + while (*s) { 233 + 234 + /* multiply by the 64 bit FNV magic prime mod 2^64 */ 235 + #if defined(NO_FNV_GCC_OPTIMIZATION) 236 + hval *= FNV_64_PRIME; 237 + #else /* NO_FNV_GCC_OPTIMIZATION */ 238 + hval += (hval << 1) + (hval << 4) + (hval << 5) + 239 + (hval << 7) + (hval << 8) + (hval << 40); 240 + #endif /* NO_FNV_GCC_OPTIMIZATION */ 241 + 242 + /* xor the bottom with the current octet */ 243 + hval ^= (Fnv64_t)*s++; 244 + } 245 + 246 + #else /* !HAVE_64BIT_LONG_LONG */ 247 + 248 + unsigned long val[4]; /* hash value in base 2^16 */ 249 + unsigned long tmp[4]; /* tmp 64 bit value */ 250 + 251 + /* 252 + * Convert Fnv64_t hval into a base 2^16 array 253 + */ 254 + val[0] = hval.w32[0]; 255 + val[1] = (val[0] >> 16); 256 + val[0] &= 0xffff; 257 + val[2] = hval.w32[1]; 258 + val[3] = (val[2] >> 16); 259 + val[2] &= 0xffff; 260 + 261 + /* 262 + * FNV-1 hash each octet of the string 263 + */ 264 + while (*s) { 265 + 266 + /* 267 + * multiply by the 64 bit FNV magic prime mod 2^64 268 + * 269 + * Using 1099511628211, we have the following digits base 2^16: 270 + * 271 + * 0x0 0x100 0x0 0x1b3 272 + * 273 + * which is the same as: 274 + * 275 + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW 276 + */ 277 + /* multiply by the lowest order digit base 2^16 */ 278 + tmp[0] = val[0] * FNV_64_PRIME_LOW; 279 + tmp[1] = val[1] * FNV_64_PRIME_LOW; 280 + tmp[2] = val[2] * FNV_64_PRIME_LOW; 281 + tmp[3] = val[3] * FNV_64_PRIME_LOW; 282 + /* multiply by the other non-zero digit */ 283 + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ 284 + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ 285 + /* propagate carries */ 286 + tmp[1] += (tmp[0] >> 16); 287 + val[0] = tmp[0] & 0xffff; 288 + tmp[2] += (tmp[1] >> 16); 289 + val[1] = tmp[1] & 0xffff; 290 + val[3] = tmp[3] + (tmp[2] >> 16); 291 + val[2] = tmp[2] & 0xffff; 292 + /* 293 + * Doing a val[3] &= 0xffff; is not really needed since it simply 294 + * removes multiples of 2^64. We can discard these excess bits 295 + * outside of the loop when we convert to Fnv64_t. 296 + */ 297 + 298 + /* xor the bottom with the current octet */ 299 + val[0] ^= (unsigned long)(*s++); 300 + } 301 + 302 + /* 303 + * Convert base 2^16 array back into an Fnv64_t 304 + */ 305 + hval.w32[1] = ((val[3]<<16) | val[2]); 306 + hval.w32[0] = ((val[1]<<16) | val[0]); 307 + 308 + #endif /* !HAVE_64BIT_LONG_LONG */ 309 + 310 + /* return our new hash value */ 311 + return hval; 312 + }
+291
lib/fnv/hash_64a.c
··· 1 + /* 2 + * hash_64 - 64 bit Fowler/Noll/Vo-0 FNV-1a hash code 3 + * 4 + * @(#) $Revision: 5.1 $ 5 + * @(#) $Id: hash_64a.c,v 5.1 2009/06/30 09:01:38 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64a.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the 37 + * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). 38 + * 39 + *** 40 + * 41 + * Please do not copyright this code. This code is in the public domain. 42 + * 43 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 44 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 45 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 46 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 47 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 48 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 49 + * PERFORMANCE OF THIS SOFTWARE. 50 + * 51 + * By: 52 + * chongo <Landon Curt Noll> /\oo/\ 53 + * http://www.isthe.com/chongo/ 54 + * 55 + * Share and Enjoy! :-) 56 + */ 57 + 58 + #include <stdlib.h> 59 + #include "fnv.h" 60 + 61 + 62 + /* 63 + * FNV-1a defines the initial basis to be non-zero 64 + */ 65 + #if !defined(HAVE_64BIT_LONG_LONG) 66 + const Fnv64_t fnv1a_64_init = { 0x84222325, 0xcbf29ce4 }; 67 + #endif /* ! HAVE_64BIT_LONG_LONG */ 68 + 69 + 70 + /* 71 + * 64 bit magic FNV-1a prime 72 + */ 73 + #if defined(HAVE_64BIT_LONG_LONG) 74 + #define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL) 75 + #else /* HAVE_64BIT_LONG_LONG */ 76 + #define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */ 77 + #define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */ 78 + #endif /* HAVE_64BIT_LONG_LONG */ 79 + 80 + 81 + /* 82 + * fnv_64a_buf - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer 83 + * 84 + * input: 85 + * buf - start of buffer to hash 86 + * len - length of buffer in octets 87 + * hval - previous hash value or 0 if first call 88 + * 89 + * returns: 90 + * 64 bit hash as a static hash type 91 + * 92 + * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the 93 + * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str(). 94 + */ 95 + Fnv64_t 96 + fnv_64a_buf(void *buf, size_t len, Fnv64_t hval) 97 + { 98 + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 99 + unsigned char *be = bp + len; /* beyond end of buffer */ 100 + 101 + #if defined(HAVE_64BIT_LONG_LONG) 102 + /* 103 + * FNV-1a hash each octet of the buffer 104 + */ 105 + while (bp < be) { 106 + 107 + /* xor the bottom with the current octet */ 108 + hval ^= (Fnv64_t)*bp++; 109 + 110 + /* multiply by the 64 bit FNV magic prime mod 2^64 */ 111 + #if defined(NO_FNV_GCC_OPTIMIZATION) 112 + hval *= FNV_64_PRIME; 113 + #else /* NO_FNV_GCC_OPTIMIZATION */ 114 + hval += (hval << 1) + (hval << 4) + (hval << 5) + 115 + (hval << 7) + (hval << 8) + (hval << 40); 116 + #endif /* NO_FNV_GCC_OPTIMIZATION */ 117 + } 118 + 119 + #else /* HAVE_64BIT_LONG_LONG */ 120 + 121 + unsigned long val[4]; /* hash value in base 2^16 */ 122 + unsigned long tmp[4]; /* tmp 64 bit value */ 123 + 124 + /* 125 + * Convert Fnv64_t hval into a base 2^16 array 126 + */ 127 + val[0] = hval.w32[0]; 128 + val[1] = (val[0] >> 16); 129 + val[0] &= 0xffff; 130 + val[2] = hval.w32[1]; 131 + val[3] = (val[2] >> 16); 132 + val[2] &= 0xffff; 133 + 134 + /* 135 + * FNV-1a hash each octet of the buffer 136 + */ 137 + while (bp < be) { 138 + 139 + /* xor the bottom with the current octet */ 140 + val[0] ^= (unsigned long)*bp++; 141 + 142 + /* 143 + * multiply by the 64 bit FNV magic prime mod 2^64 144 + * 145 + * Using 0x100000001b3 we have the following digits base 2^16: 146 + * 147 + * 0x0 0x100 0x0 0x1b3 148 + * 149 + * which is the same as: 150 + * 151 + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW 152 + */ 153 + /* multiply by the lowest order digit base 2^16 */ 154 + tmp[0] = val[0] * FNV_64_PRIME_LOW; 155 + tmp[1] = val[1] * FNV_64_PRIME_LOW; 156 + tmp[2] = val[2] * FNV_64_PRIME_LOW; 157 + tmp[3] = val[3] * FNV_64_PRIME_LOW; 158 + /* multiply by the other non-zero digit */ 159 + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ 160 + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ 161 + /* propagate carries */ 162 + tmp[1] += (tmp[0] >> 16); 163 + val[0] = tmp[0] & 0xffff; 164 + tmp[2] += (tmp[1] >> 16); 165 + val[1] = tmp[1] & 0xffff; 166 + val[3] = tmp[3] + (tmp[2] >> 16); 167 + val[2] = tmp[2] & 0xffff; 168 + /* 169 + * Doing a val[3] &= 0xffff; is not really needed since it simply 170 + * removes multiples of 2^64. We can discard these excess bits 171 + * outside of the loop when we convert to Fnv64_t. 172 + */ 173 + } 174 + 175 + /* 176 + * Convert base 2^16 array back into an Fnv64_t 177 + */ 178 + hval.w32[1] = ((val[3]<<16) | val[2]); 179 + hval.w32[0] = ((val[1]<<16) | val[0]); 180 + 181 + #endif /* HAVE_64BIT_LONG_LONG */ 182 + 183 + /* return our new hash value */ 184 + return hval; 185 + } 186 + 187 + 188 + /* 189 + * fnv_64a_str - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer 190 + * 191 + * input: 192 + * buf - start of buffer to hash 193 + * hval - previous hash value or 0 if first call 194 + * 195 + * returns: 196 + * 64 bit hash as a static hash type 197 + * 198 + * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the 199 + * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str(). 200 + */ 201 + Fnv64_t 202 + fnv_64a_str(char *str, Fnv64_t hval) 203 + { 204 + unsigned char *s = (unsigned char *)str; /* unsigned string */ 205 + 206 + #if defined(HAVE_64BIT_LONG_LONG) 207 + 208 + /* 209 + * FNV-1a hash each octet of the string 210 + */ 211 + while (*s) { 212 + 213 + /* xor the bottom with the current octet */ 214 + hval ^= (Fnv64_t)*s++; 215 + 216 + /* multiply by the 64 bit FNV magic prime mod 2^64 */ 217 + #if defined(NO_FNV_GCC_OPTIMIZATION) 218 + hval *= FNV_64_PRIME; 219 + #else /* NO_FNV_GCC_OPTIMIZATION */ 220 + hval += (hval << 1) + (hval << 4) + (hval << 5) + 221 + (hval << 7) + (hval << 8) + (hval << 40); 222 + #endif /* NO_FNV_GCC_OPTIMIZATION */ 223 + } 224 + 225 + #else /* !HAVE_64BIT_LONG_LONG */ 226 + 227 + unsigned long val[4]; /* hash value in base 2^16 */ 228 + unsigned long tmp[4]; /* tmp 64 bit value */ 229 + 230 + /* 231 + * Convert Fnv64_t hval into a base 2^16 array 232 + */ 233 + val[0] = hval.w32[0]; 234 + val[1] = (val[0] >> 16); 235 + val[0] &= 0xffff; 236 + val[2] = hval.w32[1]; 237 + val[3] = (val[2] >> 16); 238 + val[2] &= 0xffff; 239 + 240 + /* 241 + * FNV-1a hash each octet of the string 242 + */ 243 + while (*s) { 244 + 245 + /* xor the bottom with the current octet */ 246 + 247 + /* 248 + * multiply by the 64 bit FNV magic prime mod 2^64 249 + * 250 + * Using 1099511628211, we have the following digits base 2^16: 251 + * 252 + * 0x0 0x100 0x0 0x1b3 253 + * 254 + * which is the same as: 255 + * 256 + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW 257 + */ 258 + /* multiply by the lowest order digit base 2^16 */ 259 + tmp[0] = val[0] * FNV_64_PRIME_LOW; 260 + tmp[1] = val[1] * FNV_64_PRIME_LOW; 261 + tmp[2] = val[2] * FNV_64_PRIME_LOW; 262 + tmp[3] = val[3] * FNV_64_PRIME_LOW; 263 + /* multiply by the other non-zero digit */ 264 + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ 265 + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ 266 + /* propagate carries */ 267 + tmp[1] += (tmp[0] >> 16); 268 + val[0] = tmp[0] & 0xffff; 269 + tmp[2] += (tmp[1] >> 16); 270 + val[1] = tmp[1] & 0xffff; 271 + val[3] = tmp[3] + (tmp[2] >> 16); 272 + val[2] = tmp[2] & 0xffff; 273 + /* 274 + * Doing a val[3] &= 0xffff; is not really needed since it simply 275 + * removes multiples of 2^64. We can discard these excess bits 276 + * outside of the loop when we convert to Fnv64_t. 277 + */ 278 + val[0] ^= (unsigned long)(*s++); 279 + } 280 + 281 + /* 282 + * Convert base 2^16 array back into an Fnv64_t 283 + */ 284 + hval.w32[1] = ((val[3]<<16) | val[2]); 285 + hval.w32[0] = ((val[1]<<16) | val[0]); 286 + 287 + #endif /* !HAVE_64BIT_LONG_LONG */ 288 + 289 + /* return our new hash value */ 290 + return hval; 291 + }
+58
lib/fnv/have_ulong64.c
··· 1 + /* 2 + * have_ulong64 - Determine if we have a 64 bit unsigned long long 3 + * 4 + * usage: 5 + * have_ulong64 > longlong.h 6 + * 7 + * Not all systems have a 'long long type' so this may not compile on 8 + * your system. 9 + * 10 + * This prog outputs the define: 11 + * 12 + * HAVE_64BIT_LONG_LONG 13 + * defined ==> we have a 64 bit unsigned long long 14 + * undefined ==> we must simulate a 64 bit unsigned long long 15 + */ 16 + /* 17 + * 18 + * Please do not copyright this code. This code is in the public domain. 19 + * 20 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 21 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 22 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 23 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 24 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 25 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 26 + * PERFORMANCE OF THIS SOFTWARE. 27 + * 28 + * By: 29 + * chongo <Landon Curt Noll> /\oo/\ 30 + * http://www.isthe.com/chongo/ 31 + * 32 + * Share and Enjoy! :-) 33 + */ 34 + 35 + /* 36 + * have the compiler try its hand with unsigned and signed long longs 37 + */ 38 + #if ! defined(NO64BIT_LONG_LONG) 39 + unsigned long long val = 1099511628211ULL; 40 + #endif /* NO64BIT_LONG_LONG */ 41 + 42 + int 43 + main(void) 44 + { 45 + /* 46 + * ensure that the length of long long val is what we expect 47 + */ 48 + #if defined(NO64BIT_LONG_LONG) 49 + printf("#undef HAVE_64BIT_LONG_LONG\t/* no */\n"); 50 + #else /* NO64BIT_LONG_LONG */ 51 + if (val == 1099511628211ULL && sizeof(val) == 8) { 52 + printf("#define HAVE_64BIT_LONG_LONG\t/* yes */\n"); 53 + } 54 + #endif /* NO64BIT_LONG_LONG */ 55 + 56 + /* exit(0); */ 57 + return 0; 58 + }
+18
lib/fnv/longlong.h
··· 1 + /* 2 + * DO NOT EDIT -- generated by the Makefile 3 + */ 4 + 5 + #if !defined(__LONGLONG_H__) 6 + #define __LONGLONG_H__ 7 + 8 + /* do we have/want to use a long long type? */ 9 + #define HAVE_64BIT_LONG_LONG /* yes */ 10 + 11 + /* 12 + * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG 13 + */ 14 + #if defined(NO64BIT_LONG_LONG) 15 + #undef HAVE_64BIT_LONG_LONG 16 + #endif /* NO64BIT_LONG_LONG */ 17 + 18 + #endif /* !__LONGLONG_H__ */
+14
lib/fnv/qmk_fnv_type_validation.c
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include "fnv.h" 4 + 5 + // This library was originally sourced from: 6 + // http://www.isthe.com/chongo/tech/comp/fnv/index.html 7 + // 8 + // Version at the time of retrieval on 2022-06-26: v5.0.3 9 + 10 + _Static_assert(sizeof(long long) == 8, "long long should be 64 bits"); 11 + _Static_assert(sizeof(unsigned long long) == 8, "unsigned long long should be 64 bits"); 12 + 13 + _Static_assert(sizeof(Fnv32_t) == 4, "Fnv32_t should be 32 bits"); 14 + _Static_assert(sizeof(Fnv64_t) == 8, "Fnv64_t should be 64 bits");
+2237
lib/fnv/test_fnv.c
··· 1 + /* 2 + * test_fnv - FNV test suite 3 + * 4 + * @(#) $Revision: 5.3 $ 5 + * @(#) $Id: test_fnv.c,v 5.3 2009/06/30 11:50:41 chongo Exp $ 6 + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/test_fnv.c,v $ 7 + * 8 + *** 9 + * 10 + * Fowler/Noll/Vo hash 11 + * 12 + * The basis of this hash algorithm was taken from an idea sent 13 + * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 + * 15 + * Phong Vo (http://www.research.att.com/info/kpv/) 16 + * Glenn Fowler (http://www.research.att.com/~gsf/) 17 + * 18 + * In a subsequent ballot round: 19 + * 20 + * Landon Curt Noll (http://www.isthe.com/chongo/) 21 + * 22 + * improved on their algorithm. Some people tried this hash 23 + * and found that it worked rather well. In an EMail message 24 + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 + * 26 + * FNV hashes are designed to be fast while maintaining a low 27 + * collision rate. The FNV speed allows one to quickly hash lots 28 + * of data while maintaining a reasonable collision rate. See: 29 + * 30 + * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 + * 32 + * for more details as well as other forms of the FNV hash. 33 + * 34 + *** 35 + * 36 + * Please do not copyright this code. This code is in the public domain. 37 + * 38 + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 39 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 40 + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 41 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 42 + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 43 + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 44 + * PERFORMANCE OF THIS SOFTWARE. 45 + * 46 + * By: 47 + * chongo <Landon Curt Noll> /\oo/\ 48 + * http://www.isthe.com/chongo/ 49 + * 50 + * Share and Enjoy! :-) 51 + */ 52 + 53 + #include <stdio.h> 54 + #include "longlong.h" 55 + #include "fnv.h" 56 + 57 + #define LEN(x) (sizeof(x)-1) 58 + /* TEST macro does not include trailing NUL byte in the test vector */ 59 + #define TEST(x) {x, LEN(x)} 60 + /* TEST0 macro includes the trailing NUL byte in the test vector */ 61 + #define TEST0(x) {x, sizeof(x)} 62 + /* REPEAT500 - repeat a string 500 times */ 63 + #define R500(x) R100(x)R100(x)R100(x)R100(x)R100(x) 64 + #define R100(x) R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x) 65 + #define R10(x) x x x x x x x x x x 66 + 67 + /* 68 + * FNV test vectors 69 + * 70 + * NOTE: A NULL pointer marks beyond the end of the test vectors. 71 + * 72 + * NOTE: The order of the fnv_test_str[] test vectors is 1-to-1 with: 73 + * 74 + * struct fnv0_32_test_vector fnv0_32_vector[]; 75 + * struct fnv1_32_test_vector fnv1_32_vector[]; 76 + * struct fnv1a_32_test_vector fnv1a_32_vector[]; 77 + * struct fnv0_64_test_vector fnv0_64_vector[]; 78 + * struct fnv1_64_test_vector fnv1_64_vector[]; 79 + * struct fnv1a_64_test_vector fnv1a_64_vector[]; 80 + * 81 + * IMPORTANT NOTE: 82 + * 83 + * If you change the fnv_test_str[] array, you need 84 + * to also change ALL of the above fnv*_vector arrays!!! 85 + * 86 + * To rebuild, try: 87 + * 88 + * make vector.c 89 + * 90 + * and then fold the results into the source file. 91 + * Of course, you better make sure that the vaules 92 + * produced by the above command are valid, otherwise 93 + * you will be testing against invalid vectors! 94 + */ 95 + struct test_vector fnv_test_str[] = { 96 + TEST(""), 97 + TEST("a"), 98 + TEST("b"), 99 + TEST("c"), 100 + TEST("d"), 101 + TEST("e"), 102 + TEST("f"), 103 + TEST("fo"), 104 + TEST("foo"), 105 + TEST("foob"), 106 + TEST("fooba"), 107 + TEST("foobar"), 108 + TEST0(""), 109 + TEST0("a"), 110 + TEST0("b"), 111 + TEST0("c"), 112 + TEST0("d"), 113 + TEST0("e"), 114 + TEST0("f"), 115 + TEST0("fo"), 116 + TEST0("foo"), 117 + TEST0("foob"), 118 + TEST0("fooba"), 119 + TEST0("foobar"), 120 + TEST("ch"), 121 + TEST("cho"), 122 + TEST("chon"), 123 + TEST("chong"), 124 + TEST("chongo"), 125 + TEST("chongo "), 126 + TEST("chongo w"), 127 + TEST("chongo wa"), 128 + TEST("chongo was"), 129 + TEST("chongo was "), 130 + TEST("chongo was h"), 131 + TEST("chongo was he"), 132 + TEST("chongo was her"), 133 + TEST("chongo was here"), 134 + TEST("chongo was here!"), 135 + TEST("chongo was here!\n"), 136 + TEST0("ch"), 137 + TEST0("cho"), 138 + TEST0("chon"), 139 + TEST0("chong"), 140 + TEST0("chongo"), 141 + TEST0("chongo "), 142 + TEST0("chongo w"), 143 + TEST0("chongo wa"), 144 + TEST0("chongo was"), 145 + TEST0("chongo was "), 146 + TEST0("chongo was h"), 147 + TEST0("chongo was he"), 148 + TEST0("chongo was her"), 149 + TEST0("chongo was here"), 150 + TEST0("chongo was here!"), 151 + TEST0("chongo was here!\n"), 152 + TEST("cu"), 153 + TEST("cur"), 154 + TEST("curd"), 155 + TEST("curds"), 156 + TEST("curds "), 157 + TEST("curds a"), 158 + TEST("curds an"), 159 + TEST("curds and"), 160 + TEST("curds and "), 161 + TEST("curds and w"), 162 + TEST("curds and wh"), 163 + TEST("curds and whe"), 164 + TEST("curds and whey"), 165 + TEST("curds and whey\n"), 166 + TEST0("cu"), 167 + TEST0("cur"), 168 + TEST0("curd"), 169 + TEST0("curds"), 170 + TEST0("curds "), 171 + TEST0("curds a"), 172 + TEST0("curds an"), 173 + TEST0("curds and"), 174 + TEST0("curds and "), 175 + TEST0("curds and w"), 176 + TEST0("curds and wh"), 177 + TEST0("curds and whe"), 178 + TEST0("curds and whey"), 179 + TEST0("curds and whey\n"), 180 + TEST("hi"), TEST0("hi"), 181 + TEST("hello"), TEST0("hello"), 182 + TEST("\xff\x00\x00\x01"), TEST("\x01\x00\x00\xff"), 183 + TEST("\xff\x00\x00\x02"), TEST("\x02\x00\x00\xff"), 184 + TEST("\xff\x00\x00\x03"), TEST("\x03\x00\x00\xff"), 185 + TEST("\xff\x00\x00\x04"), TEST("\x04\x00\x00\xff"), 186 + TEST("\x40\x51\x4e\x44"), TEST("\x44\x4e\x51\x40"), 187 + TEST("\x40\x51\x4e\x4a"), TEST("\x4a\x4e\x51\x40"), 188 + TEST("\x40\x51\x4e\x54"), TEST("\x54\x4e\x51\x40"), 189 + TEST("127.0.0.1"), TEST0("127.0.0.1"), 190 + TEST("127.0.0.2"), TEST0("127.0.0.2"), 191 + TEST("127.0.0.3"), TEST0("127.0.0.3"), 192 + TEST("64.81.78.68"), TEST0("64.81.78.68"), 193 + TEST("64.81.78.74"), TEST0("64.81.78.74"), 194 + TEST("64.81.78.84"), TEST0("64.81.78.84"), 195 + TEST("feedface"), TEST0("feedface"), 196 + TEST("feedfacedaffdeed"), TEST0("feedfacedaffdeed"), 197 + TEST("feedfacedeadbeef"), TEST0("feedfacedeadbeef"), 198 + TEST("line 1\nline 2\nline 3"), 199 + TEST("chongo <Landon Curt Noll> /\\../\\"), 200 + TEST0("chongo <Landon Curt Noll> /\\../\\"), 201 + TEST("chongo (Landon Curt Noll) /\\../\\"), 202 + TEST0("chongo (Landon Curt Noll) /\\../\\"), 203 + TEST("http://antwrp.gsfc.nasa.gov/apod/astropix.html"), 204 + TEST("http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash"), 205 + TEST("http://epod.usra.edu/"), 206 + TEST("http://exoplanet.eu/"), 207 + TEST("http://hvo.wr.usgs.gov/cam3/"), 208 + TEST("http://hvo.wr.usgs.gov/cams/HMcam/"), 209 + TEST("http://hvo.wr.usgs.gov/kilauea/update/deformation.html"), 210 + TEST("http://hvo.wr.usgs.gov/kilauea/update/images.html"), 211 + TEST("http://hvo.wr.usgs.gov/kilauea/update/maps.html"), 212 + TEST("http://hvo.wr.usgs.gov/volcanowatch/current_issue.html"), 213 + TEST("http://neo.jpl.nasa.gov/risk/"), 214 + TEST("http://norvig.com/21-days.html"), 215 + TEST("http://primes.utm.edu/curios/home.php"), 216 + TEST("http://slashdot.org/"), 217 + TEST("http://tux.wr.usgs.gov/Maps/155.25-19.5.html"), 218 + TEST("http://volcano.wr.usgs.gov/kilaueastatus.php"), 219 + TEST("http://www.avo.alaska.edu/activity/Redoubt.php"), 220 + TEST("http://www.dilbert.com/fast/"), 221 + TEST("http://www.fourmilab.ch/gravitation/orbits/"), 222 + TEST("http://www.fpoa.net/"), 223 + TEST("http://www.ioccc.org/index.html"), 224 + TEST("http://www.isthe.com/cgi-bin/number.cgi"), 225 + TEST("http://www.isthe.com/chongo/bio.html"), 226 + TEST("http://www.isthe.com/chongo/index.html"), 227 + TEST("http://www.isthe.com/chongo/src/calc/lucas-calc"), 228 + TEST("http://www.isthe.com/chongo/tech/astro/venus2004.html"), 229 + TEST("http://www.isthe.com/chongo/tech/astro/vita.html"), 230 + TEST("http://www.isthe.com/chongo/tech/comp/c/expert.html"), 231 + TEST("http://www.isthe.com/chongo/tech/comp/calc/index.html"), 232 + TEST("http://www.isthe.com/chongo/tech/comp/fnv/index.html"), 233 + TEST("http://www.isthe.com/chongo/tech/math/number/howhigh.html"), 234 + TEST("http://www.isthe.com/chongo/tech/math/number/number.html"), 235 + TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html"), 236 + TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html#largest"), 237 + TEST("http://www.lavarnd.org/cgi-bin/corpspeak.cgi"), 238 + TEST("http://www.lavarnd.org/cgi-bin/haiku.cgi"), 239 + TEST("http://www.lavarnd.org/cgi-bin/rand-none.cgi"), 240 + TEST("http://www.lavarnd.org/cgi-bin/randdist.cgi"), 241 + TEST("http://www.lavarnd.org/index.html"), 242 + TEST("http://www.lavarnd.org/what/nist-test.html"), 243 + TEST("http://www.macosxhints.com/"), 244 + TEST("http://www.mellis.com/"), 245 + TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/havoalert.cfm"), 246 + TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/timelines_24.cfm"), 247 + TEST("http://www.paulnoll.com/"), 248 + TEST("http://www.pepysdiary.com/"), 249 + TEST("http://www.sciencenews.org/index/home/activity/view"), 250 + TEST("http://www.skyandtelescope.com/"), 251 + TEST("http://www.sput.nl/~rob/sirius.html"), 252 + TEST("http://www.systemexperts.com/"), 253 + TEST("http://www.tq-international.com/phpBB3/index.php"), 254 + TEST("http://www.travelquesttours.com/index.htm"), 255 + TEST("http://www.wunderground.com/global/stations/89606.html"), 256 + TEST(R10("21701")), 257 + TEST(R10("M21701")), 258 + TEST(R10("2^21701-1")), 259 + TEST(R10("\x54\xc5")), 260 + TEST(R10("\xc5\x54")), 261 + TEST(R10("23209")), 262 + TEST(R10("M23209")), 263 + TEST(R10("2^23209-1")), 264 + TEST(R10("\x5a\xa9")), 265 + TEST(R10("\xa9\x5a")), 266 + TEST(R10("391581216093")), 267 + TEST(R10("391581*2^216093-1")), 268 + TEST(R10("\x05\xf9\x9d\x03\x4c\x81")), 269 + TEST(R10("FEDCBA9876543210")), 270 + TEST(R10("\xfe\xdc\xba\x98\x76\x54\x32\x10")), 271 + TEST(R10("EFCDAB8967452301")), 272 + TEST(R10("\xef\xcd\xab\x89\x67\x45\x23\x01")), 273 + TEST(R10("0123456789ABCDEF")), 274 + TEST(R10("\x01\x23\x45\x67\x89\xab\xcd\xef")), 275 + TEST(R10("1032547698BADCFE")), 276 + TEST(R10("\x10\x32\x54\x76\x98\xba\xdc\xfe")), 277 + TEST(R500("\x00")), 278 + TEST(R500("\x07")), 279 + TEST(R500("~")), 280 + TEST(R500("\x7f")), 281 + {NULL, 0} /* MUST BE LAST */ 282 + }; 283 + 284 + 285 + /* 286 + * insert the contents of vector.c below 287 + * 288 + * make vector.c 289 + * :r vector.c 290 + */ 291 + /* start of output generated by make vector.c */ 292 + 293 + /* FNV-0 32 bit test vectors */ 294 + struct fnv0_32_test_vector fnv0_32_vector[] = { 295 + { &fnv_test_str[0], (Fnv32_t) 0x00000000UL }, 296 + { &fnv_test_str[1], (Fnv32_t) 0x00000061UL }, 297 + { &fnv_test_str[2], (Fnv32_t) 0x00000062UL }, 298 + { &fnv_test_str[3], (Fnv32_t) 0x00000063UL }, 299 + { &fnv_test_str[4], (Fnv32_t) 0x00000064UL }, 300 + { &fnv_test_str[5], (Fnv32_t) 0x00000065UL }, 301 + { &fnv_test_str[6], (Fnv32_t) 0x00000066UL }, 302 + { &fnv_test_str[7], (Fnv32_t) 0x6600a0fdUL }, 303 + { &fnv_test_str[8], (Fnv32_t) 0x8ffd6e28UL }, 304 + { &fnv_test_str[9], (Fnv32_t) 0xd3f4689aUL }, 305 + { &fnv_test_str[10], (Fnv32_t) 0x43c0aa0fUL }, 306 + { &fnv_test_str[11], (Fnv32_t) 0xb74bb5efUL }, 307 + { &fnv_test_str[12], (Fnv32_t) 0x00000000UL }, 308 + { &fnv_test_str[13], (Fnv32_t) 0x610098b3UL }, 309 + { &fnv_test_str[14], (Fnv32_t) 0x62009a46UL }, 310 + { &fnv_test_str[15], (Fnv32_t) 0x63009bd9UL }, 311 + { &fnv_test_str[16], (Fnv32_t) 0x64009d6cUL }, 312 + { &fnv_test_str[17], (Fnv32_t) 0x65009effUL }, 313 + { &fnv_test_str[18], (Fnv32_t) 0x6600a092UL }, 314 + { &fnv_test_str[19], (Fnv32_t) 0x8ffd6e47UL }, 315 + { &fnv_test_str[20], (Fnv32_t) 0xd3f468f8UL }, 316 + { &fnv_test_str[21], (Fnv32_t) 0x43c0aa6eUL }, 317 + { &fnv_test_str[22], (Fnv32_t) 0xb74bb59dUL }, 318 + { &fnv_test_str[23], (Fnv32_t) 0x7b2f673dUL }, 319 + { &fnv_test_str[24], (Fnv32_t) 0x63009bb1UL }, 320 + { &fnv_test_str[25], (Fnv32_t) 0x8af517ccUL }, 321 + { &fnv_test_str[26], (Fnv32_t) 0x8bd4764aUL }, 322 + { &fnv_test_str[27], (Fnv32_t) 0x69763619UL }, 323 + { &fnv_test_str[28], (Fnv32_t) 0x1e172934UL }, 324 + { &fnv_test_str[29], (Fnv32_t) 0x9275dcfcUL }, 325 + { &fnv_test_str[30], (Fnv32_t) 0x8b8ae0c3UL }, 326 + { &fnv_test_str[31], (Fnv32_t) 0x6e9fd298UL }, 327 + { &fnv_test_str[32], (Fnv32_t) 0xbd98853bUL }, 328 + { &fnv_test_str[33], (Fnv32_t) 0xb219bbc1UL }, 329 + { &fnv_test_str[34], (Fnv32_t) 0x1f8290bbUL }, 330 + { &fnv_test_str[35], (Fnv32_t) 0x5589d604UL }, 331 + { &fnv_test_str[36], (Fnv32_t) 0xabfbe83eUL }, 332 + { &fnv_test_str[37], (Fnv32_t) 0xfb8e99ffUL }, 333 + { &fnv_test_str[38], (Fnv32_t) 0x007c6c4cUL }, 334 + { &fnv_test_str[39], (Fnv32_t) 0x0fde7baeUL }, 335 + { &fnv_test_str[40], (Fnv32_t) 0x8af517a3UL }, 336 + { &fnv_test_str[41], (Fnv32_t) 0x8bd47624UL }, 337 + { &fnv_test_str[42], (Fnv32_t) 0x6976367eUL }, 338 + { &fnv_test_str[43], (Fnv32_t) 0x1e17295bUL }, 339 + { &fnv_test_str[44], (Fnv32_t) 0x9275dcdcUL }, 340 + { &fnv_test_str[45], (Fnv32_t) 0x8b8ae0b4UL }, 341 + { &fnv_test_str[46], (Fnv32_t) 0x6e9fd2f9UL }, 342 + { &fnv_test_str[47], (Fnv32_t) 0xbd988548UL }, 343 + { &fnv_test_str[48], (Fnv32_t) 0xb219bbe1UL }, 344 + { &fnv_test_str[49], (Fnv32_t) 0x1f8290d3UL }, 345 + { &fnv_test_str[50], (Fnv32_t) 0x5589d661UL }, 346 + { &fnv_test_str[51], (Fnv32_t) 0xabfbe84cUL }, 347 + { &fnv_test_str[52], (Fnv32_t) 0xfb8e999aUL }, 348 + { &fnv_test_str[53], (Fnv32_t) 0x007c6c6dUL }, 349 + { &fnv_test_str[54], (Fnv32_t) 0x0fde7ba4UL }, 350 + { &fnv_test_str[55], (Fnv32_t) 0xa93cb2eaUL }, 351 + { &fnv_test_str[56], (Fnv32_t) 0x63009bacUL }, 352 + { &fnv_test_str[57], (Fnv32_t) 0x85f50fb6UL }, 353 + { &fnv_test_str[58], (Fnv32_t) 0x96c7bbe6UL }, 354 + { &fnv_test_str[59], (Fnv32_t) 0x426ccb61UL }, 355 + { &fnv_test_str[60], (Fnv32_t) 0xf2442993UL }, 356 + { &fnv_test_str[61], (Fnv32_t) 0xf44d7208UL }, 357 + { &fnv_test_str[62], (Fnv32_t) 0x9dea82f6UL }, 358 + { &fnv_test_str[63], (Fnv32_t) 0x8e2c2926UL }, 359 + { &fnv_test_str[64], (Fnv32_t) 0xf584c6f2UL }, 360 + { &fnv_test_str[65], (Fnv32_t) 0x72052e81UL }, 361 + { &fnv_test_str[66], (Fnv32_t) 0xff28357bUL }, 362 + { &fnv_test_str[67], (Fnv32_t) 0x274c30c4UL }, 363 + { &fnv_test_str[68], (Fnv32_t) 0xa0f0c4f5UL }, 364 + { &fnv_test_str[69], (Fnv32_t) 0x50060da5UL }, 365 + { &fnv_test_str[70], (Fnv32_t) 0x85f50fc4UL }, 366 + { &fnv_test_str[71], (Fnv32_t) 0x96c7bb82UL }, 367 + { &fnv_test_str[72], (Fnv32_t) 0x426ccb12UL }, 368 + { &fnv_test_str[73], (Fnv32_t) 0xf24429b3UL }, 369 + { &fnv_test_str[74], (Fnv32_t) 0xf44d7269UL }, 370 + { &fnv_test_str[75], (Fnv32_t) 0x9dea8298UL }, 371 + { &fnv_test_str[76], (Fnv32_t) 0x8e2c2942UL }, 372 + { &fnv_test_str[77], (Fnv32_t) 0xf584c6d2UL }, 373 + { &fnv_test_str[78], (Fnv32_t) 0x72052ef6UL }, 374 + { &fnv_test_str[79], (Fnv32_t) 0xff283513UL }, 375 + { &fnv_test_str[80], (Fnv32_t) 0x274c30a1UL }, 376 + { &fnv_test_str[81], (Fnv32_t) 0xa0f0c48cUL }, 377 + { &fnv_test_str[82], (Fnv32_t) 0x50060dafUL }, 378 + { &fnv_test_str[83], (Fnv32_t) 0x9e877abfUL }, 379 + { &fnv_test_str[84], (Fnv32_t) 0x6800a3d1UL }, 380 + { &fnv_test_str[85], (Fnv32_t) 0x8a01e203UL }, 381 + { &fnv_test_str[86], (Fnv32_t) 0xec6d6be8UL }, 382 + { &fnv_test_str[87], (Fnv32_t) 0x1840de38UL }, 383 + { &fnv_test_str[88], (Fnv32_t) 0xa7cc97b4UL }, 384 + { &fnv_test_str[89], (Fnv32_t) 0x3ee6b3b4UL }, 385 + { &fnv_test_str[90], (Fnv32_t) 0xa7cc97b7UL }, 386 + { &fnv_test_str[91], (Fnv32_t) 0x7dcd6669UL }, 387 + { &fnv_test_str[92], (Fnv32_t) 0xa7cc97b6UL }, 388 + { &fnv_test_str[93], (Fnv32_t) 0xbcb4191eUL }, 389 + { &fnv_test_str[94], (Fnv32_t) 0xa7cc97b1UL }, 390 + { &fnv_test_str[95], (Fnv32_t) 0xfb9acdd3UL }, 391 + { &fnv_test_str[96], (Fnv32_t) 0x89380433UL }, 392 + { &fnv_test_str[97], (Fnv32_t) 0x8acd2855UL }, 393 + { &fnv_test_str[98], (Fnv32_t) 0x8938043dUL }, 394 + { &fnv_test_str[99], (Fnv32_t) 0xcaeed493UL }, 395 + { &fnv_test_str[100], (Fnv32_t) 0x89380423UL }, 396 + { &fnv_test_str[101], (Fnv32_t) 0x59382a25UL }, 397 + { &fnv_test_str[102], (Fnv32_t) 0x567f75d7UL }, 398 + { &fnv_test_str[103], (Fnv32_t) 0x01a68175UL }, 399 + { &fnv_test_str[104], (Fnv32_t) 0x567f75d4UL }, 400 + { &fnv_test_str[105], (Fnv32_t) 0xfea67cbcUL }, 401 + { &fnv_test_str[106], (Fnv32_t) 0x567f75d5UL }, 402 + { &fnv_test_str[107], (Fnv32_t) 0xffa67e4fUL }, 403 + { &fnv_test_str[108], (Fnv32_t) 0xd131b668UL }, 404 + { &fnv_test_str[109], (Fnv32_t) 0xb94225b8UL }, 405 + { &fnv_test_str[110], (Fnv32_t) 0xd231b7d7UL }, 406 + { &fnv_test_str[111], (Fnv32_t) 0xbb446775UL }, 407 + { &fnv_test_str[112], (Fnv32_t) 0xdf31cc6eUL }, 408 + { &fnv_test_str[113], (Fnv32_t) 0xc964d12aUL }, 409 + { &fnv_test_str[114], (Fnv32_t) 0x23af8f9fUL }, 410 + { &fnv_test_str[115], (Fnv32_t) 0xcc5f174dUL }, 411 + { &fnv_test_str[116], (Fnv32_t) 0x96b29b8cUL }, 412 + { &fnv_test_str[117], (Fnv32_t) 0xc72add64UL }, 413 + { &fnv_test_str[118], (Fnv32_t) 0x528fb7efUL }, 414 + { &fnv_test_str[119], (Fnv32_t) 0xe73e8d3dUL }, 415 + { &fnv_test_str[120], (Fnv32_t) 0x876386feUL }, 416 + { &fnv_test_str[121], (Fnv32_t) 0x811c9dc5UL }, 417 + { &fnv_test_str[122], (Fnv32_t) 0x050c5d1fUL }, 418 + { &fnv_test_str[123], (Fnv32_t) 0x14bf7238UL }, 419 + { &fnv_test_str[124], (Fnv32_t) 0xe160ce28UL }, 420 + { &fnv_test_str[125], (Fnv32_t) 0x89dc5a75UL }, 421 + { &fnv_test_str[126], (Fnv32_t) 0xd89b69a0UL }, 422 + { &fnv_test_str[127], (Fnv32_t) 0x94471a88UL }, 423 + { &fnv_test_str[128], (Fnv32_t) 0xe78db65fUL }, 424 + { &fnv_test_str[129], (Fnv32_t) 0x0c3009a2UL }, 425 + { &fnv_test_str[130], (Fnv32_t) 0x122dff03UL }, 426 + { &fnv_test_str[131], (Fnv32_t) 0xb4cd8875UL }, 427 + { &fnv_test_str[132], (Fnv32_t) 0xf4dba725UL }, 428 + { &fnv_test_str[133], (Fnv32_t) 0x41a16560UL }, 429 + { &fnv_test_str[134], (Fnv32_t) 0x9c0f941fUL }, 430 + { &fnv_test_str[135], (Fnv32_t) 0x451a5348UL }, 431 + { &fnv_test_str[136], (Fnv32_t) 0x3f1d1d89UL }, 432 + { &fnv_test_str[137], (Fnv32_t) 0x1b91b57aUL }, 433 + { &fnv_test_str[138], (Fnv32_t) 0x3e99b577UL }, 434 + { &fnv_test_str[139], (Fnv32_t) 0x4c9de07aUL }, 435 + { &fnv_test_str[140], (Fnv32_t) 0x1ddf7572UL }, 436 + { &fnv_test_str[141], (Fnv32_t) 0x64e81976UL }, 437 + { &fnv_test_str[142], (Fnv32_t) 0x1106a888UL }, 438 + { &fnv_test_str[143], (Fnv32_t) 0xa498d8e5UL }, 439 + { &fnv_test_str[144], (Fnv32_t) 0x3c03d2e3UL }, 440 + { &fnv_test_str[145], (Fnv32_t) 0x26568b28UL }, 441 + { &fnv_test_str[146], (Fnv32_t) 0x70d7fb42UL }, 442 + { &fnv_test_str[147], (Fnv32_t) 0xd3ae1d22UL }, 443 + { &fnv_test_str[148], (Fnv32_t) 0xac8ea5f4UL }, 444 + { &fnv_test_str[149], (Fnv32_t) 0x4d0abd60UL }, 445 + { &fnv_test_str[150], (Fnv32_t) 0x48f5e086UL }, 446 + { &fnv_test_str[151], (Fnv32_t) 0xa8f6241bUL }, 447 + { &fnv_test_str[152], (Fnv32_t) 0x572f864fUL }, 448 + { &fnv_test_str[153], (Fnv32_t) 0xa5340803UL }, 449 + { &fnv_test_str[154], (Fnv32_t) 0x22881aa8UL }, 450 + { &fnv_test_str[155], (Fnv32_t) 0xc2e2f5a2UL }, 451 + { &fnv_test_str[156], (Fnv32_t) 0xebf5aec7UL }, 452 + { &fnv_test_str[157], (Fnv32_t) 0x3cdbfb85UL }, 453 + { &fnv_test_str[158], (Fnv32_t) 0xbb859704UL }, 454 + { &fnv_test_str[159], (Fnv32_t) 0xc956fe11UL }, 455 + { &fnv_test_str[160], (Fnv32_t) 0x8f11a7c9UL }, 456 + { &fnv_test_str[161], (Fnv32_t) 0x36c48ecfUL }, 457 + { &fnv_test_str[162], (Fnv32_t) 0x24bfa27eUL }, 458 + { &fnv_test_str[163], (Fnv32_t) 0xf2596ad1UL }, 459 + { &fnv_test_str[164], (Fnv32_t) 0xf14a9b45UL }, 460 + { &fnv_test_str[165], (Fnv32_t) 0x7d45835aUL }, 461 + { &fnv_test_str[166], (Fnv32_t) 0x6e49334dUL }, 462 + { &fnv_test_str[167], (Fnv32_t) 0x71767337UL }, 463 + { &fnv_test_str[168], (Fnv32_t) 0x858a1a8aUL }, 464 + { &fnv_test_str[169], (Fnv32_t) 0x16e75ac2UL }, 465 + { &fnv_test_str[170], (Fnv32_t) 0x409f99dfUL }, 466 + { &fnv_test_str[171], (Fnv32_t) 0x6d6652ddUL }, 467 + { &fnv_test_str[172], (Fnv32_t) 0x2761a9ffUL }, 468 + { &fnv_test_str[173], (Fnv32_t) 0x41f0d616UL }, 469 + { &fnv_test_str[174], (Fnv32_t) 0x0e2d0d0fUL }, 470 + { &fnv_test_str[175], (Fnv32_t) 0x06adc8fdUL }, 471 + { &fnv_test_str[176], (Fnv32_t) 0x60e0d4b9UL }, 472 + { &fnv_test_str[177], (Fnv32_t) 0x5ddc79d3UL }, 473 + { &fnv_test_str[178], (Fnv32_t) 0x1e6d0b46UL }, 474 + { &fnv_test_str[179], (Fnv32_t) 0x1d1514d8UL }, 475 + { &fnv_test_str[180], (Fnv32_t) 0xb1903a4eUL }, 476 + { &fnv_test_str[181], (Fnv32_t) 0x8200c318UL }, 477 + { &fnv_test_str[182], (Fnv32_t) 0x15e22888UL }, 478 + { &fnv_test_str[183], (Fnv32_t) 0x57591760UL }, 479 + { &fnv_test_str[184], (Fnv32_t) 0x02462efcUL }, 480 + { &fnv_test_str[185], (Fnv32_t) 0x7651ec44UL }, 481 + { &fnv_test_str[186], (Fnv32_t) 0x7c24e9d4UL }, 482 + { &fnv_test_str[187], (Fnv32_t) 0x1952a034UL }, 483 + { &fnv_test_str[188], (Fnv32_t) 0xd4c46864UL }, 484 + { &fnv_test_str[189], (Fnv32_t) 0xcb57cde0UL }, 485 + { &fnv_test_str[190], (Fnv32_t) 0x71136a70UL }, 486 + { &fnv_test_str[191], (Fnv32_t) 0x0618fb40UL }, 487 + { &fnv_test_str[192], (Fnv32_t) 0x69a24fc0UL }, 488 + { &fnv_test_str[193], (Fnv32_t) 0x6a9be510UL }, 489 + { &fnv_test_str[194], (Fnv32_t) 0xe0477040UL }, 490 + { &fnv_test_str[195], (Fnv32_t) 0x85aa94b0UL }, 491 + { &fnv_test_str[196], (Fnv32_t) 0xc6d76240UL }, 492 + { &fnv_test_str[197], (Fnv32_t) 0xa9f09e40UL }, 493 + { &fnv_test_str[198], (Fnv32_t) 0xa0291540UL }, 494 + { &fnv_test_str[199], (Fnv32_t) 0x00000000UL }, 495 + { &fnv_test_str[200], (Fnv32_t) 0x2e672aa4UL }, 496 + { &fnv_test_str[201], (Fnv32_t) 0x84b1aa48UL }, 497 + { &fnv_test_str[202], (Fnv32_t) 0xfc24ba24UL }, 498 + { NULL, 0 } 499 + }; 500 + 501 + /* FNV-1 32 bit test vectors */ 502 + struct fnv1_32_test_vector fnv1_32_vector[] = { 503 + { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL }, 504 + { &fnv_test_str[1], (Fnv32_t) 0x050c5d7eUL }, 505 + { &fnv_test_str[2], (Fnv32_t) 0x050c5d7dUL }, 506 + { &fnv_test_str[3], (Fnv32_t) 0x050c5d7cUL }, 507 + { &fnv_test_str[4], (Fnv32_t) 0x050c5d7bUL }, 508 + { &fnv_test_str[5], (Fnv32_t) 0x050c5d7aUL }, 509 + { &fnv_test_str[6], (Fnv32_t) 0x050c5d79UL }, 510 + { &fnv_test_str[7], (Fnv32_t) 0x6b772514UL }, 511 + { &fnv_test_str[8], (Fnv32_t) 0x408f5e13UL }, 512 + { &fnv_test_str[9], (Fnv32_t) 0xb4b1178bUL }, 513 + { &fnv_test_str[10], (Fnv32_t) 0xfdc80fb0UL }, 514 + { &fnv_test_str[11], (Fnv32_t) 0x31f0b262UL }, 515 + { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL }, 516 + { &fnv_test_str[13], (Fnv32_t) 0x70772d5aUL }, 517 + { &fnv_test_str[14], (Fnv32_t) 0x6f772bc7UL }, 518 + { &fnv_test_str[15], (Fnv32_t) 0x6e772a34UL }, 519 + { &fnv_test_str[16], (Fnv32_t) 0x6d7728a1UL }, 520 + { &fnv_test_str[17], (Fnv32_t) 0x6c77270eUL }, 521 + { &fnv_test_str[18], (Fnv32_t) 0x6b77257bUL }, 522 + { &fnv_test_str[19], (Fnv32_t) 0x408f5e7cUL }, 523 + { &fnv_test_str[20], (Fnv32_t) 0xb4b117e9UL }, 524 + { &fnv_test_str[21], (Fnv32_t) 0xfdc80fd1UL }, 525 + { &fnv_test_str[22], (Fnv32_t) 0x31f0b210UL }, 526 + { &fnv_test_str[23], (Fnv32_t) 0xffe8d046UL }, 527 + { &fnv_test_str[24], (Fnv32_t) 0x6e772a5cUL }, 528 + { &fnv_test_str[25], (Fnv32_t) 0x4197aebbUL }, 529 + { &fnv_test_str[26], (Fnv32_t) 0xfcc8100fUL }, 530 + { &fnv_test_str[27], (Fnv32_t) 0xfdf147faUL }, 531 + { &fnv_test_str[28], (Fnv32_t) 0xbcd44ee1UL }, 532 + { &fnv_test_str[29], (Fnv32_t) 0x23382c13UL }, 533 + { &fnv_test_str[30], (Fnv32_t) 0x846d619eUL }, 534 + { &fnv_test_str[31], (Fnv32_t) 0x1630abdbUL }, 535 + { &fnv_test_str[32], (Fnv32_t) 0xc99e89b2UL }, 536 + { &fnv_test_str[33], (Fnv32_t) 0x1692c316UL }, 537 + { &fnv_test_str[34], (Fnv32_t) 0x9f091bcaUL }, 538 + { &fnv_test_str[35], (Fnv32_t) 0x2556be9bUL }, 539 + { &fnv_test_str[36], (Fnv32_t) 0x628e0e73UL }, 540 + { &fnv_test_str[37], (Fnv32_t) 0x98a0bf6cUL }, 541 + { &fnv_test_str[38], (Fnv32_t) 0xb10d5725UL }, 542 + { &fnv_test_str[39], (Fnv32_t) 0xdd002f35UL }, 543 + { &fnv_test_str[40], (Fnv32_t) 0x4197aed4UL }, 544 + { &fnv_test_str[41], (Fnv32_t) 0xfcc81061UL }, 545 + { &fnv_test_str[42], (Fnv32_t) 0xfdf1479dUL }, 546 + { &fnv_test_str[43], (Fnv32_t) 0xbcd44e8eUL }, 547 + { &fnv_test_str[44], (Fnv32_t) 0x23382c33UL }, 548 + { &fnv_test_str[45], (Fnv32_t) 0x846d61e9UL }, 549 + { &fnv_test_str[46], (Fnv32_t) 0x1630abbaUL }, 550 + { &fnv_test_str[47], (Fnv32_t) 0xc99e89c1UL }, 551 + { &fnv_test_str[48], (Fnv32_t) 0x1692c336UL }, 552 + { &fnv_test_str[49], (Fnv32_t) 0x9f091ba2UL }, 553 + { &fnv_test_str[50], (Fnv32_t) 0x2556befeUL }, 554 + { &fnv_test_str[51], (Fnv32_t) 0x628e0e01UL }, 555 + { &fnv_test_str[52], (Fnv32_t) 0x98a0bf09UL }, 556 + { &fnv_test_str[53], (Fnv32_t) 0xb10d5704UL }, 557 + { &fnv_test_str[54], (Fnv32_t) 0xdd002f3fUL }, 558 + { &fnv_test_str[55], (Fnv32_t) 0x1c4a506fUL }, 559 + { &fnv_test_str[56], (Fnv32_t) 0x6e772a41UL }, 560 + { &fnv_test_str[57], (Fnv32_t) 0x26978421UL }, 561 + { &fnv_test_str[58], (Fnv32_t) 0xe184ff97UL }, 562 + { &fnv_test_str[59], (Fnv32_t) 0x9b5e5ac6UL }, 563 + { &fnv_test_str[60], (Fnv32_t) 0x5b88e592UL }, 564 + { &fnv_test_str[61], (Fnv32_t) 0xaa8164b7UL }, 565 + { &fnv_test_str[62], (Fnv32_t) 0x20b18c7bUL }, 566 + { &fnv_test_str[63], (Fnv32_t) 0xf28025c5UL }, 567 + { &fnv_test_str[64], (Fnv32_t) 0x84bb753fUL }, 568 + { &fnv_test_str[65], (Fnv32_t) 0x3219925aUL }, 569 + { &fnv_test_str[66], (Fnv32_t) 0x384163c6UL }, 570 + { &fnv_test_str[67], (Fnv32_t) 0x54f010d7UL }, 571 + { &fnv_test_str[68], (Fnv32_t) 0x8cea820cUL }, 572 + { &fnv_test_str[69], (Fnv32_t) 0xe12ab8eeUL }, 573 + { &fnv_test_str[70], (Fnv32_t) 0x26978453UL }, 574 + { &fnv_test_str[71], (Fnv32_t) 0xe184fff3UL }, 575 + { &fnv_test_str[72], (Fnv32_t) 0x9b5e5ab5UL }, 576 + { &fnv_test_str[73], (Fnv32_t) 0x5b88e5b2UL }, 577 + { &fnv_test_str[74], (Fnv32_t) 0xaa8164d6UL }, 578 + { &fnv_test_str[75], (Fnv32_t) 0x20b18c15UL }, 579 + { &fnv_test_str[76], (Fnv32_t) 0xf28025a1UL }, 580 + { &fnv_test_str[77], (Fnv32_t) 0x84bb751fUL }, 581 + { &fnv_test_str[78], (Fnv32_t) 0x3219922dUL }, 582 + { &fnv_test_str[79], (Fnv32_t) 0x384163aeUL }, 583 + { &fnv_test_str[80], (Fnv32_t) 0x54f010b2UL }, 584 + { &fnv_test_str[81], (Fnv32_t) 0x8cea8275UL }, 585 + { &fnv_test_str[82], (Fnv32_t) 0xe12ab8e4UL }, 586 + { &fnv_test_str[83], (Fnv32_t) 0x64411eaaUL }, 587 + { &fnv_test_str[84], (Fnv32_t) 0x6977223cUL }, 588 + { &fnv_test_str[85], (Fnv32_t) 0x428ae474UL }, 589 + { &fnv_test_str[86], (Fnv32_t) 0xb6fa7167UL }, 590 + { &fnv_test_str[87], (Fnv32_t) 0x73408525UL }, 591 + { &fnv_test_str[88], (Fnv32_t) 0xb78320a1UL }, 592 + { &fnv_test_str[89], (Fnv32_t) 0x0caf4135UL }, 593 + { &fnv_test_str[90], (Fnv32_t) 0xb78320a2UL }, 594 + { &fnv_test_str[91], (Fnv32_t) 0xcdc88e80UL }, 595 + { &fnv_test_str[92], (Fnv32_t) 0xb78320a3UL }, 596 + { &fnv_test_str[93], (Fnv32_t) 0x8ee1dbcbUL }, 597 + { &fnv_test_str[94], (Fnv32_t) 0xb78320a4UL }, 598 + { &fnv_test_str[95], (Fnv32_t) 0x4ffb2716UL }, 599 + { &fnv_test_str[96], (Fnv32_t) 0x860632aaUL }, 600 + { &fnv_test_str[97], (Fnv32_t) 0xcc2c5c64UL }, 601 + { &fnv_test_str[98], (Fnv32_t) 0x860632a4UL }, 602 + { &fnv_test_str[99], (Fnv32_t) 0x2a7ec4a6UL }, 603 + { &fnv_test_str[100], (Fnv32_t) 0x860632baUL }, 604 + { &fnv_test_str[101], (Fnv32_t) 0xfefe8e14UL }, 605 + { &fnv_test_str[102], (Fnv32_t) 0x0a3cffd8UL }, 606 + { &fnv_test_str[103], (Fnv32_t) 0xf606c108UL }, 607 + { &fnv_test_str[104], (Fnv32_t) 0x0a3cffdbUL }, 608 + { &fnv_test_str[105], (Fnv32_t) 0xf906c5c1UL }, 609 + { &fnv_test_str[106], (Fnv32_t) 0x0a3cffdaUL }, 610 + { &fnv_test_str[107], (Fnv32_t) 0xf806c42eUL }, 611 + { &fnv_test_str[108], (Fnv32_t) 0xc07167d7UL }, 612 + { &fnv_test_str[109], (Fnv32_t) 0xc9867775UL }, 613 + { &fnv_test_str[110], (Fnv32_t) 0xbf716668UL }, 614 + { &fnv_test_str[111], (Fnv32_t) 0xc78435b8UL }, 615 + { &fnv_test_str[112], (Fnv32_t) 0xc6717155UL }, 616 + { &fnv_test_str[113], (Fnv32_t) 0xb99568cfUL }, 617 + { &fnv_test_str[114], (Fnv32_t) 0x7662e0d6UL }, 618 + { &fnv_test_str[115], (Fnv32_t) 0x33a7f0e2UL }, 619 + { &fnv_test_str[116], (Fnv32_t) 0xc2732f95UL }, 620 + { &fnv_test_str[117], (Fnv32_t) 0xb053e78fUL }, 621 + { &fnv_test_str[118], (Fnv32_t) 0x3a19c02aUL }, 622 + { &fnv_test_str[119], (Fnv32_t) 0xa089821eUL }, 623 + { &fnv_test_str[120], (Fnv32_t) 0x31ae8f83UL }, 624 + { &fnv_test_str[121], (Fnv32_t) 0x995fa9c4UL }, 625 + { &fnv_test_str[122], (Fnv32_t) 0x35983f8cUL }, 626 + { &fnv_test_str[123], (Fnv32_t) 0x5036a251UL }, 627 + { &fnv_test_str[124], (Fnv32_t) 0x97018583UL }, 628 + { &fnv_test_str[125], (Fnv32_t) 0xb4448d60UL }, 629 + { &fnv_test_str[126], (Fnv32_t) 0x025dfe59UL }, 630 + { &fnv_test_str[127], (Fnv32_t) 0xc5eab3afUL }, 631 + { &fnv_test_str[128], (Fnv32_t) 0x7d21ba1eUL }, 632 + { &fnv_test_str[129], (Fnv32_t) 0x7704cddbUL }, 633 + { &fnv_test_str[130], (Fnv32_t) 0xd0071bfeUL }, 634 + { &fnv_test_str[131], (Fnv32_t) 0x0ff3774cUL }, 635 + { &fnv_test_str[132], (Fnv32_t) 0xb0fea0eaUL }, 636 + { &fnv_test_str[133], (Fnv32_t) 0x58177303UL }, 637 + { &fnv_test_str[134], (Fnv32_t) 0x4f599cdaUL }, 638 + { &fnv_test_str[135], (Fnv32_t) 0x3e590a47UL }, 639 + { &fnv_test_str[136], (Fnv32_t) 0x965595f8UL }, 640 + { &fnv_test_str[137], (Fnv32_t) 0xc37f178dUL }, 641 + { &fnv_test_str[138], (Fnv32_t) 0x9711dd26UL }, 642 + { &fnv_test_str[139], (Fnv32_t) 0x23c99b7fUL }, 643 + { &fnv_test_str[140], (Fnv32_t) 0x6e568b17UL }, 644 + { &fnv_test_str[141], (Fnv32_t) 0x43f0245bUL }, 645 + { &fnv_test_str[142], (Fnv32_t) 0xbcb7a001UL }, 646 + { &fnv_test_str[143], (Fnv32_t) 0x12e6dffeUL }, 647 + { &fnv_test_str[144], (Fnv32_t) 0x0792f2d6UL }, 648 + { &fnv_test_str[145], (Fnv32_t) 0xb966936bUL }, 649 + { &fnv_test_str[146], (Fnv32_t) 0x46439ac5UL }, 650 + { &fnv_test_str[147], (Fnv32_t) 0x728d49afUL }, 651 + { &fnv_test_str[148], (Fnv32_t) 0xd33745c9UL }, 652 + { &fnv_test_str[149], (Fnv32_t) 0xbc382a57UL }, 653 + { &fnv_test_str[150], (Fnv32_t) 0x4bda1d31UL }, 654 + { &fnv_test_str[151], (Fnv32_t) 0xce35ccaeUL }, 655 + { &fnv_test_str[152], (Fnv32_t) 0x3b6eed94UL }, 656 + { &fnv_test_str[153], (Fnv32_t) 0x445c9c58UL }, 657 + { &fnv_test_str[154], (Fnv32_t) 0x3db8bf9dUL }, 658 + { &fnv_test_str[155], (Fnv32_t) 0x2dee116dUL }, 659 + { &fnv_test_str[156], (Fnv32_t) 0xc18738daUL }, 660 + { &fnv_test_str[157], (Fnv32_t) 0x5b156176UL }, 661 + { &fnv_test_str[158], (Fnv32_t) 0x2aa7d593UL }, 662 + { &fnv_test_str[159], (Fnv32_t) 0xb2409658UL }, 663 + { &fnv_test_str[160], (Fnv32_t) 0xe1489528UL }, 664 + { &fnv_test_str[161], (Fnv32_t) 0xfe1ee07eUL }, 665 + { &fnv_test_str[162], (Fnv32_t) 0xe8842315UL }, 666 + { &fnv_test_str[163], (Fnv32_t) 0x3a6a63a2UL }, 667 + { &fnv_test_str[164], (Fnv32_t) 0x06d2c18cUL }, 668 + { &fnv_test_str[165], (Fnv32_t) 0xf8ef7225UL }, 669 + { &fnv_test_str[166], (Fnv32_t) 0x843d3300UL }, 670 + { &fnv_test_str[167], (Fnv32_t) 0xbb24f7aeUL }, 671 + { &fnv_test_str[168], (Fnv32_t) 0x878c0ec9UL }, 672 + { &fnv_test_str[169], (Fnv32_t) 0xb557810fUL }, 673 + { &fnv_test_str[170], (Fnv32_t) 0x57423246UL }, 674 + { &fnv_test_str[171], (Fnv32_t) 0x87f7505eUL }, 675 + { &fnv_test_str[172], (Fnv32_t) 0xbb809f20UL }, 676 + { &fnv_test_str[173], (Fnv32_t) 0x8932abb5UL }, 677 + { &fnv_test_str[174], (Fnv32_t) 0x0a9b3aa0UL }, 678 + { &fnv_test_str[175], (Fnv32_t) 0xb8682a24UL }, 679 + { &fnv_test_str[176], (Fnv32_t) 0xa7ac1c56UL }, 680 + { &fnv_test_str[177], (Fnv32_t) 0x11409252UL }, 681 + { &fnv_test_str[178], (Fnv32_t) 0xa987f517UL }, 682 + { &fnv_test_str[179], (Fnv32_t) 0xf309e7edUL }, 683 + { &fnv_test_str[180], (Fnv32_t) 0xc9e8f417UL }, 684 + { &fnv_test_str[181], (Fnv32_t) 0x7f447bddUL }, 685 + { &fnv_test_str[182], (Fnv32_t) 0xb929adc5UL }, 686 + { &fnv_test_str[183], (Fnv32_t) 0x57022879UL }, 687 + { &fnv_test_str[184], (Fnv32_t) 0xdcfd2c49UL }, 688 + { &fnv_test_str[185], (Fnv32_t) 0x6edafff5UL }, 689 + { &fnv_test_str[186], (Fnv32_t) 0xf04fb1f1UL }, 690 + { &fnv_test_str[187], (Fnv32_t) 0xfb7de8b9UL }, 691 + { &fnv_test_str[188], (Fnv32_t) 0xc5f1d7e9UL }, 692 + { &fnv_test_str[189], (Fnv32_t) 0x32c1f439UL }, 693 + { &fnv_test_str[190], (Fnv32_t) 0x7fd3eb7dUL }, 694 + { &fnv_test_str[191], (Fnv32_t) 0x81597da5UL }, 695 + { &fnv_test_str[192], (Fnv32_t) 0x05eb7a25UL }, 696 + { &fnv_test_str[193], (Fnv32_t) 0x9c0fa1b5UL }, 697 + { &fnv_test_str[194], (Fnv32_t) 0x53ccb1c5UL }, 698 + { &fnv_test_str[195], (Fnv32_t) 0xfabece15UL }, 699 + { &fnv_test_str[196], (Fnv32_t) 0x4ad745a5UL }, 700 + { &fnv_test_str[197], (Fnv32_t) 0xe5bdc495UL }, 701 + { &fnv_test_str[198], (Fnv32_t) 0x23b3c0a5UL }, 702 + { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL }, 703 + { &fnv_test_str[200], (Fnv32_t) 0x0c6c58b9UL }, 704 + { &fnv_test_str[201], (Fnv32_t) 0xe2dbccd5UL }, 705 + { &fnv_test_str[202], (Fnv32_t) 0xdb7f50f9UL }, 706 + { NULL, 0 } 707 + }; 708 + 709 + /* FNV-1a 32 bit test vectors */ 710 + struct fnv1a_32_test_vector fnv1a_32_vector[] = { 711 + { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL }, 712 + { &fnv_test_str[1], (Fnv32_t) 0xe40c292cUL }, 713 + { &fnv_test_str[2], (Fnv32_t) 0xe70c2de5UL }, 714 + { &fnv_test_str[3], (Fnv32_t) 0xe60c2c52UL }, 715 + { &fnv_test_str[4], (Fnv32_t) 0xe10c2473UL }, 716 + { &fnv_test_str[5], (Fnv32_t) 0xe00c22e0UL }, 717 + { &fnv_test_str[6], (Fnv32_t) 0xe30c2799UL }, 718 + { &fnv_test_str[7], (Fnv32_t) 0x6222e842UL }, 719 + { &fnv_test_str[8], (Fnv32_t) 0xa9f37ed7UL }, 720 + { &fnv_test_str[9], (Fnv32_t) 0x3f5076efUL }, 721 + { &fnv_test_str[10], (Fnv32_t) 0x39aaa18aUL }, 722 + { &fnv_test_str[11], (Fnv32_t) 0xbf9cf968UL }, 723 + { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL }, 724 + { &fnv_test_str[13], (Fnv32_t) 0x2b24d044UL }, 725 + { &fnv_test_str[14], (Fnv32_t) 0x9d2c3f7fUL }, 726 + { &fnv_test_str[15], (Fnv32_t) 0x7729c516UL }, 727 + { &fnv_test_str[16], (Fnv32_t) 0xb91d6109UL }, 728 + { &fnv_test_str[17], (Fnv32_t) 0x931ae6a0UL }, 729 + { &fnv_test_str[18], (Fnv32_t) 0x052255dbUL }, 730 + { &fnv_test_str[19], (Fnv32_t) 0xbef39fe6UL }, 731 + { &fnv_test_str[20], (Fnv32_t) 0x6150ac75UL }, 732 + { &fnv_test_str[21], (Fnv32_t) 0x9aab3a3dUL }, 733 + { &fnv_test_str[22], (Fnv32_t) 0x519c4c3eUL }, 734 + { &fnv_test_str[23], (Fnv32_t) 0x0c1c9eb8UL }, 735 + { &fnv_test_str[24], (Fnv32_t) 0x5f299f4eUL }, 736 + { &fnv_test_str[25], (Fnv32_t) 0xef8580f3UL }, 737 + { &fnv_test_str[26], (Fnv32_t) 0xac297727UL }, 738 + { &fnv_test_str[27], (Fnv32_t) 0x4546b9c0UL }, 739 + { &fnv_test_str[28], (Fnv32_t) 0xbd564e7dUL }, 740 + { &fnv_test_str[29], (Fnv32_t) 0x6bdd5c67UL }, 741 + { &fnv_test_str[30], (Fnv32_t) 0xdd77ed30UL }, 742 + { &fnv_test_str[31], (Fnv32_t) 0xf4ca9683UL }, 743 + { &fnv_test_str[32], (Fnv32_t) 0x4aeb9bd0UL }, 744 + { &fnv_test_str[33], (Fnv32_t) 0xe0e67ad0UL }, 745 + { &fnv_test_str[34], (Fnv32_t) 0xc2d32fa8UL }, 746 + { &fnv_test_str[35], (Fnv32_t) 0x7f743fb7UL }, 747 + { &fnv_test_str[36], (Fnv32_t) 0x6900631fUL }, 748 + { &fnv_test_str[37], (Fnv32_t) 0xc59c990eUL }, 749 + { &fnv_test_str[38], (Fnv32_t) 0x448524fdUL }, 750 + { &fnv_test_str[39], (Fnv32_t) 0xd49930d5UL }, 751 + { &fnv_test_str[40], (Fnv32_t) 0x1c85c7caUL }, 752 + { &fnv_test_str[41], (Fnv32_t) 0x0229fe89UL }, 753 + { &fnv_test_str[42], (Fnv32_t) 0x2c469265UL }, 754 + { &fnv_test_str[43], (Fnv32_t) 0xce566940UL }, 755 + { &fnv_test_str[44], (Fnv32_t) 0x8bdd8ec7UL }, 756 + { &fnv_test_str[45], (Fnv32_t) 0x34787625UL }, 757 + { &fnv_test_str[46], (Fnv32_t) 0xd3ca6290UL }, 758 + { &fnv_test_str[47], (Fnv32_t) 0xddeaf039UL }, 759 + { &fnv_test_str[48], (Fnv32_t) 0xc0e64870UL }, 760 + { &fnv_test_str[49], (Fnv32_t) 0xdad35570UL }, 761 + { &fnv_test_str[50], (Fnv32_t) 0x5a740578UL }, 762 + { &fnv_test_str[51], (Fnv32_t) 0x5b004d15UL }, 763 + { &fnv_test_str[52], (Fnv32_t) 0x6a9c09cdUL }, 764 + { &fnv_test_str[53], (Fnv32_t) 0x2384f10aUL }, 765 + { &fnv_test_str[54], (Fnv32_t) 0xda993a47UL }, 766 + { &fnv_test_str[55], (Fnv32_t) 0x8227df4fUL }, 767 + { &fnv_test_str[56], (Fnv32_t) 0x4c298165UL }, 768 + { &fnv_test_str[57], (Fnv32_t) 0xfc563735UL }, 769 + { &fnv_test_str[58], (Fnv32_t) 0x8cb91483UL }, 770 + { &fnv_test_str[59], (Fnv32_t) 0x775bf5d0UL }, 771 + { &fnv_test_str[60], (Fnv32_t) 0xd5c428d0UL }, 772 + { &fnv_test_str[61], (Fnv32_t) 0x34cc0ea3UL }, 773 + { &fnv_test_str[62], (Fnv32_t) 0xea3b4cb7UL }, 774 + { &fnv_test_str[63], (Fnv32_t) 0x8e59f029UL }, 775 + { &fnv_test_str[64], (Fnv32_t) 0x2094de2bUL }, 776 + { &fnv_test_str[65], (Fnv32_t) 0xa65a0ad4UL }, 777 + { &fnv_test_str[66], (Fnv32_t) 0x9bbee5f4UL }, 778 + { &fnv_test_str[67], (Fnv32_t) 0xbe836343UL }, 779 + { &fnv_test_str[68], (Fnv32_t) 0x22d5344eUL }, 780 + { &fnv_test_str[69], (Fnv32_t) 0x19a1470cUL }, 781 + { &fnv_test_str[70], (Fnv32_t) 0x4a56b1ffUL }, 782 + { &fnv_test_str[71], (Fnv32_t) 0x70b8e86fUL }, 783 + { &fnv_test_str[72], (Fnv32_t) 0x0a5b4a39UL }, 784 + { &fnv_test_str[73], (Fnv32_t) 0xb5c3f670UL }, 785 + { &fnv_test_str[74], (Fnv32_t) 0x53cc3f70UL }, 786 + { &fnv_test_str[75], (Fnv32_t) 0xc03b0a99UL }, 787 + { &fnv_test_str[76], (Fnv32_t) 0x7259c415UL }, 788 + { &fnv_test_str[77], (Fnv32_t) 0x4095108bUL }, 789 + { &fnv_test_str[78], (Fnv32_t) 0x7559bdb1UL }, 790 + { &fnv_test_str[79], (Fnv32_t) 0xb3bf0bbcUL }, 791 + { &fnv_test_str[80], (Fnv32_t) 0x2183ff1cUL }, 792 + { &fnv_test_str[81], (Fnv32_t) 0x2bd54279UL }, 793 + { &fnv_test_str[82], (Fnv32_t) 0x23a156caUL }, 794 + { &fnv_test_str[83], (Fnv32_t) 0x64e2d7e4UL }, 795 + { &fnv_test_str[84], (Fnv32_t) 0x683af69aUL }, 796 + { &fnv_test_str[85], (Fnv32_t) 0xaed2346eUL }, 797 + { &fnv_test_str[86], (Fnv32_t) 0x4f9f2cabUL }, 798 + { &fnv_test_str[87], (Fnv32_t) 0x02935131UL }, 799 + { &fnv_test_str[88], (Fnv32_t) 0xc48fb86dUL }, 800 + { &fnv_test_str[89], (Fnv32_t) 0x2269f369UL }, 801 + { &fnv_test_str[90], (Fnv32_t) 0xc18fb3b4UL }, 802 + { &fnv_test_str[91], (Fnv32_t) 0x50ef1236UL }, 803 + { &fnv_test_str[92], (Fnv32_t) 0xc28fb547UL }, 804 + { &fnv_test_str[93], (Fnv32_t) 0x96c3bf47UL }, 805 + { &fnv_test_str[94], (Fnv32_t) 0xbf8fb08eUL }, 806 + { &fnv_test_str[95], (Fnv32_t) 0xf3e4d49cUL }, 807 + { &fnv_test_str[96], (Fnv32_t) 0x32179058UL }, 808 + { &fnv_test_str[97], (Fnv32_t) 0x280bfee6UL }, 809 + { &fnv_test_str[98], (Fnv32_t) 0x30178d32UL }, 810 + { &fnv_test_str[99], (Fnv32_t) 0x21addaf8UL }, 811 + { &fnv_test_str[100], (Fnv32_t) 0x4217a988UL }, 812 + { &fnv_test_str[101], (Fnv32_t) 0x772633d6UL }, 813 + { &fnv_test_str[102], (Fnv32_t) 0x08a3d11eUL }, 814 + { &fnv_test_str[103], (Fnv32_t) 0xb7e2323aUL }, 815 + { &fnv_test_str[104], (Fnv32_t) 0x07a3cf8bUL }, 816 + { &fnv_test_str[105], (Fnv32_t) 0x91dfb7d1UL }, 817 + { &fnv_test_str[106], (Fnv32_t) 0x06a3cdf8UL }, 818 + { &fnv_test_str[107], (Fnv32_t) 0x6bdd3d68UL }, 819 + { &fnv_test_str[108], (Fnv32_t) 0x1d5636a7UL }, 820 + { &fnv_test_str[109], (Fnv32_t) 0xd5b808e5UL }, 821 + { &fnv_test_str[110], (Fnv32_t) 0x1353e852UL }, 822 + { &fnv_test_str[111], (Fnv32_t) 0xbf16b916UL }, 823 + { &fnv_test_str[112], (Fnv32_t) 0xa55b89edUL }, 824 + { &fnv_test_str[113], (Fnv32_t) 0x3c1a2017UL }, 825 + { &fnv_test_str[114], (Fnv32_t) 0x0588b13cUL }, 826 + { &fnv_test_str[115], (Fnv32_t) 0xf22f0174UL }, 827 + { &fnv_test_str[116], (Fnv32_t) 0xe83641e1UL }, 828 + { &fnv_test_str[117], (Fnv32_t) 0x6e69b533UL }, 829 + { &fnv_test_str[118], (Fnv32_t) 0xf1760448UL }, 830 + { &fnv_test_str[119], (Fnv32_t) 0x64c8bd58UL }, 831 + { &fnv_test_str[120], (Fnv32_t) 0x97b4ea23UL }, 832 + { &fnv_test_str[121], (Fnv32_t) 0x9a4e92e6UL }, 833 + { &fnv_test_str[122], (Fnv32_t) 0xcfb14012UL }, 834 + { &fnv_test_str[123], (Fnv32_t) 0xf01b2511UL }, 835 + { &fnv_test_str[124], (Fnv32_t) 0x0bbb59c3UL }, 836 + { &fnv_test_str[125], (Fnv32_t) 0xce524afaUL }, 837 + { &fnv_test_str[126], (Fnv32_t) 0xdd16ef45UL }, 838 + { &fnv_test_str[127], (Fnv32_t) 0x60648bb3UL }, 839 + { &fnv_test_str[128], (Fnv32_t) 0x7fa4bcfcUL }, 840 + { &fnv_test_str[129], (Fnv32_t) 0x5053ae17UL }, 841 + { &fnv_test_str[130], (Fnv32_t) 0xc9302890UL }, 842 + { &fnv_test_str[131], (Fnv32_t) 0x956ded32UL }, 843 + { &fnv_test_str[132], (Fnv32_t) 0x9136db84UL }, 844 + { &fnv_test_str[133], (Fnv32_t) 0xdf9d3323UL }, 845 + { &fnv_test_str[134], (Fnv32_t) 0x32bb6cd0UL }, 846 + { &fnv_test_str[135], (Fnv32_t) 0xc8f8385bUL }, 847 + { &fnv_test_str[136], (Fnv32_t) 0xeb08bfbaUL }, 848 + { &fnv_test_str[137], (Fnv32_t) 0x62cc8e3dUL }, 849 + { &fnv_test_str[138], (Fnv32_t) 0xc3e20f5cUL }, 850 + { &fnv_test_str[139], (Fnv32_t) 0x39e97f17UL }, 851 + { &fnv_test_str[140], (Fnv32_t) 0x7837b203UL }, 852 + { &fnv_test_str[141], (Fnv32_t) 0x319e877bUL }, 853 + { &fnv_test_str[142], (Fnv32_t) 0xd3e63f89UL }, 854 + { &fnv_test_str[143], (Fnv32_t) 0x29b50b38UL }, 855 + { &fnv_test_str[144], (Fnv32_t) 0x5ed678b8UL }, 856 + { &fnv_test_str[145], (Fnv32_t) 0xb0d5b793UL }, 857 + { &fnv_test_str[146], (Fnv32_t) 0x52450be5UL }, 858 + { &fnv_test_str[147], (Fnv32_t) 0xfa72d767UL }, 859 + { &fnv_test_str[148], (Fnv32_t) 0x95066709UL }, 860 + { &fnv_test_str[149], (Fnv32_t) 0x7f52e123UL }, 861 + { &fnv_test_str[150], (Fnv32_t) 0x76966481UL }, 862 + { &fnv_test_str[151], (Fnv32_t) 0x063258b0UL }, 863 + { &fnv_test_str[152], (Fnv32_t) 0x2ded6e8aUL }, 864 + { &fnv_test_str[153], (Fnv32_t) 0xb07d7c52UL }, 865 + { &fnv_test_str[154], (Fnv32_t) 0xd0c71b71UL }, 866 + { &fnv_test_str[155], (Fnv32_t) 0xf684f1bdUL }, 867 + { &fnv_test_str[156], (Fnv32_t) 0x868ecfa8UL }, 868 + { &fnv_test_str[157], (Fnv32_t) 0xf794f684UL }, 869 + { &fnv_test_str[158], (Fnv32_t) 0xd19701c3UL }, 870 + { &fnv_test_str[159], (Fnv32_t) 0x346e171eUL }, 871 + { &fnv_test_str[160], (Fnv32_t) 0x91f8f676UL }, 872 + { &fnv_test_str[161], (Fnv32_t) 0x0bf58848UL }, 873 + { &fnv_test_str[162], (Fnv32_t) 0x6317b6d1UL }, 874 + { &fnv_test_str[163], (Fnv32_t) 0xafad4c54UL }, 875 + { &fnv_test_str[164], (Fnv32_t) 0x0f25681eUL }, 876 + { &fnv_test_str[165], (Fnv32_t) 0x91b18d49UL }, 877 + { &fnv_test_str[166], (Fnv32_t) 0x7d61c12eUL }, 878 + { &fnv_test_str[167], (Fnv32_t) 0x5147d25cUL }, 879 + { &fnv_test_str[168], (Fnv32_t) 0x9a8b6805UL }, 880 + { &fnv_test_str[169], (Fnv32_t) 0x4cd2a447UL }, 881 + { &fnv_test_str[170], (Fnv32_t) 0x1e549b14UL }, 882 + { &fnv_test_str[171], (Fnv32_t) 0x2fe1b574UL }, 883 + { &fnv_test_str[172], (Fnv32_t) 0xcf0cd31eUL }, 884 + { &fnv_test_str[173], (Fnv32_t) 0x6c471669UL }, 885 + { &fnv_test_str[174], (Fnv32_t) 0x0e5eef1eUL }, 886 + { &fnv_test_str[175], (Fnv32_t) 0x2bed3602UL }, 887 + { &fnv_test_str[176], (Fnv32_t) 0xb26249e0UL }, 888 + { &fnv_test_str[177], (Fnv32_t) 0x2c9b86a4UL }, 889 + { &fnv_test_str[178], (Fnv32_t) 0xe415e2bbUL }, 890 + { &fnv_test_str[179], (Fnv32_t) 0x18a98d1dUL }, 891 + { &fnv_test_str[180], (Fnv32_t) 0xb7df8b7bUL }, 892 + { &fnv_test_str[181], (Fnv32_t) 0x241e9075UL }, 893 + { &fnv_test_str[182], (Fnv32_t) 0x063f70ddUL }, 894 + { &fnv_test_str[183], (Fnv32_t) 0x0295aed9UL }, 895 + { &fnv_test_str[184], (Fnv32_t) 0x56a7f781UL }, 896 + { &fnv_test_str[185], (Fnv32_t) 0x253bc645UL }, 897 + { &fnv_test_str[186], (Fnv32_t) 0x46610921UL }, 898 + { &fnv_test_str[187], (Fnv32_t) 0x7c1577f9UL }, 899 + { &fnv_test_str[188], (Fnv32_t) 0x512b2851UL }, 900 + { &fnv_test_str[189], (Fnv32_t) 0x76823999UL }, 901 + { &fnv_test_str[190], (Fnv32_t) 0xc0586935UL }, 902 + { &fnv_test_str[191], (Fnv32_t) 0xf3415c85UL }, 903 + { &fnv_test_str[192], (Fnv32_t) 0x0ae4ff65UL }, 904 + { &fnv_test_str[193], (Fnv32_t) 0x58b79725UL }, 905 + { &fnv_test_str[194], (Fnv32_t) 0xdea43aa5UL }, 906 + { &fnv_test_str[195], (Fnv32_t) 0x2bb3be35UL }, 907 + { &fnv_test_str[196], (Fnv32_t) 0xea777a45UL }, 908 + { &fnv_test_str[197], (Fnv32_t) 0x8f21c305UL }, 909 + { &fnv_test_str[198], (Fnv32_t) 0x5c9d0865UL }, 910 + { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL }, 911 + { &fnv_test_str[200], (Fnv32_t) 0x21a27271UL }, 912 + { &fnv_test_str[201], (Fnv32_t) 0x83c5c6d5UL }, 913 + { &fnv_test_str[202], (Fnv32_t) 0x813b0881UL }, 914 + { NULL, 0 } 915 + }; 916 + 917 + /* FNV-0 64 bit test vectors */ 918 + #if defined(HAVE_64BIT_LONG_LONG) 919 + struct fnv0_64_test_vector fnv0_64_vector[] = { 920 + { &fnv_test_str[0], (Fnv64_t) 0x0000000000000000ULL }, 921 + { &fnv_test_str[1], (Fnv64_t) 0x0000000000000061ULL }, 922 + { &fnv_test_str[2], (Fnv64_t) 0x0000000000000062ULL }, 923 + { &fnv_test_str[3], (Fnv64_t) 0x0000000000000063ULL }, 924 + { &fnv_test_str[4], (Fnv64_t) 0x0000000000000064ULL }, 925 + { &fnv_test_str[5], (Fnv64_t) 0x0000000000000065ULL }, 926 + { &fnv_test_str[6], (Fnv64_t) 0x0000000000000066ULL }, 927 + { &fnv_test_str[7], (Fnv64_t) 0x000066000000ad3dULL }, 928 + { &fnv_test_str[8], (Fnv64_t) 0x015a8f0001265ec8ULL }, 929 + { &fnv_test_str[9], (Fnv64_t) 0x733fc501f4330dbaULL }, 930 + { &fnv_test_str[10], (Fnv64_t) 0x08697c51f2c0536fULL }, 931 + { &fnv_test_str[11], (Fnv64_t) 0x0b91ae3f7ccdc5efULL }, 932 + { &fnv_test_str[12], (Fnv64_t) 0x0000000000000000ULL }, 933 + { &fnv_test_str[13], (Fnv64_t) 0x000061000000a4d3ULL }, 934 + { &fnv_test_str[14], (Fnv64_t) 0x000062000000a686ULL }, 935 + { &fnv_test_str[15], (Fnv64_t) 0x000063000000a839ULL }, 936 + { &fnv_test_str[16], (Fnv64_t) 0x000064000000a9ecULL }, 937 + { &fnv_test_str[17], (Fnv64_t) 0x000065000000ab9fULL }, 938 + { &fnv_test_str[18], (Fnv64_t) 0x000066000000ad52ULL }, 939 + { &fnv_test_str[19], (Fnv64_t) 0x015a8f0001265ea7ULL }, 940 + { &fnv_test_str[20], (Fnv64_t) 0x733fc501f4330dd8ULL }, 941 + { &fnv_test_str[21], (Fnv64_t) 0x08697c51f2c0530eULL }, 942 + { &fnv_test_str[22], (Fnv64_t) 0x0b91ae3f7ccdc59dULL }, 943 + { &fnv_test_str[23], (Fnv64_t) 0x765104e111a7551dULL }, 944 + { &fnv_test_str[24], (Fnv64_t) 0x000063000000a851ULL }, 945 + { &fnv_test_str[25], (Fnv64_t) 0x01508a00011e01ccULL }, 946 + { &fnv_test_str[26], (Fnv64_t) 0x59dc4a01e5fd0dcaULL }, 947 + { &fnv_test_str[27], (Fnv64_t) 0xae5f8b39ccfe6e59ULL }, 948 + { &fnv_test_str[28], (Fnv64_t) 0x4ac7ec3754558154ULL }, 949 + { &fnv_test_str[29], (Fnv64_t) 0x6737b6044d4ac19cULL }, 950 + { &fnv_test_str[30], (Fnv64_t) 0xae6be54f5606fc63ULL }, 951 + { &fnv_test_str[31], (Fnv64_t) 0x685308cf2ddedc58ULL }, 952 + { &fnv_test_str[32], (Fnv64_t) 0x23f4500af1b069fbULL }, 953 + { &fnv_test_str[33], (Fnv64_t) 0xc88dfd98aec415a1ULL }, 954 + { &fnv_test_str[34], (Fnv64_t) 0x8d5b8b70f730c0fbULL }, 955 + { &fnv_test_str[35], (Fnv64_t) 0x634eebf407d7eae4ULL }, 956 + { &fnv_test_str[36], (Fnv64_t) 0x9705d3a953e4211eULL }, 957 + { &fnv_test_str[37], (Fnv64_t) 0x8307c6b98ca4459fULL }, 958 + { &fnv_test_str[38], (Fnv64_t) 0x4a7c4c49fb224d0cULL }, 959 + { &fnv_test_str[39], (Fnv64_t) 0xb382adb5bb48eb6eULL }, 960 + { &fnv_test_str[40], (Fnv64_t) 0x01508a00011e01a3ULL }, 961 + { &fnv_test_str[41], (Fnv64_t) 0x59dc4a01e5fd0da4ULL }, 962 + { &fnv_test_str[42], (Fnv64_t) 0xae5f8b39ccfe6e3eULL }, 963 + { &fnv_test_str[43], (Fnv64_t) 0x4ac7ec375455813bULL }, 964 + { &fnv_test_str[44], (Fnv64_t) 0x6737b6044d4ac1bcULL }, 965 + { &fnv_test_str[45], (Fnv64_t) 0xae6be54f5606fc14ULL }, 966 + { &fnv_test_str[46], (Fnv64_t) 0x685308cf2ddedc39ULL }, 967 + { &fnv_test_str[47], (Fnv64_t) 0x23f4500af1b06988ULL }, 968 + { &fnv_test_str[48], (Fnv64_t) 0xc88dfd98aec41581ULL }, 969 + { &fnv_test_str[49], (Fnv64_t) 0x8d5b8b70f730c093ULL }, 970 + { &fnv_test_str[50], (Fnv64_t) 0x634eebf407d7ea81ULL }, 971 + { &fnv_test_str[51], (Fnv64_t) 0x9705d3a953e4216cULL }, 972 + { &fnv_test_str[52], (Fnv64_t) 0x8307c6b98ca445faULL }, 973 + { &fnv_test_str[53], (Fnv64_t) 0x4a7c4c49fb224d2dULL }, 974 + { &fnv_test_str[54], (Fnv64_t) 0xb382adb5bb48eb64ULL }, 975 + { &fnv_test_str[55], (Fnv64_t) 0x4ff899cd3ce80beaULL }, 976 + { &fnv_test_str[56], (Fnv64_t) 0x000063000000a84cULL }, 977 + { &fnv_test_str[57], (Fnv64_t) 0x01508500011df956ULL }, 978 + { &fnv_test_str[58], (Fnv64_t) 0x59cb5501e5eead46ULL }, 979 + { &fnv_test_str[59], (Fnv64_t) 0x832eb839b4906d81ULL }, 980 + { &fnv_test_str[60], (Fnv64_t) 0x78d08b0dd16a1213ULL }, 981 + { &fnv_test_str[61], (Fnv64_t) 0xb46e5b7ad73cb628ULL }, 982 + { &fnv_test_str[62], (Fnv64_t) 0xd43b99bbbc298596ULL }, 983 + { &fnv_test_str[63], (Fnv64_t) 0xcacbd000ba8dfd86ULL }, 984 + { &fnv_test_str[64], (Fnv64_t) 0x264ff73cff45ca92ULL }, 985 + { &fnv_test_str[65], (Fnv64_t) 0x5fabaea5c3973661ULL }, 986 + { &fnv_test_str[66], (Fnv64_t) 0x27f024ab59f166bbULL }, 987 + { &fnv_test_str[67], (Fnv64_t) 0xce750a29d5318fa4ULL }, 988 + { &fnv_test_str[68], (Fnv64_t) 0x026fe915433713d5ULL }, 989 + { &fnv_test_str[69], (Fnv64_t) 0x5b3ce4213696b2e5ULL }, 990 + { &fnv_test_str[70], (Fnv64_t) 0x01508500011df924ULL }, 991 + { &fnv_test_str[71], (Fnv64_t) 0x59cb5501e5eead22ULL }, 992 + { &fnv_test_str[72], (Fnv64_t) 0x832eb839b4906df2ULL }, 993 + { &fnv_test_str[73], (Fnv64_t) 0x78d08b0dd16a1233ULL }, 994 + { &fnv_test_str[74], (Fnv64_t) 0xb46e5b7ad73cb649ULL }, 995 + { &fnv_test_str[75], (Fnv64_t) 0xd43b99bbbc2985f8ULL }, 996 + { &fnv_test_str[76], (Fnv64_t) 0xcacbd000ba8dfde2ULL }, 997 + { &fnv_test_str[77], (Fnv64_t) 0x264ff73cff45cab2ULL }, 998 + { &fnv_test_str[78], (Fnv64_t) 0x5fabaea5c3973616ULL }, 999 + { &fnv_test_str[79], (Fnv64_t) 0x27f024ab59f166d3ULL }, 1000 + { &fnv_test_str[80], (Fnv64_t) 0xce750a29d5318fc1ULL }, 1001 + { &fnv_test_str[81], (Fnv64_t) 0x026fe915433713acULL }, 1002 + { &fnv_test_str[82], (Fnv64_t) 0x5b3ce4213696b2efULL }, 1003 + { &fnv_test_str[83], (Fnv64_t) 0x9f2a896fc211fb1fULL }, 1004 + { &fnv_test_str[84], (Fnv64_t) 0x000068000000b0d1ULL }, 1005 + { &fnv_test_str[85], (Fnv64_t) 0x01618900012c7323ULL }, 1006 + { &fnv_test_str[86], (Fnv64_t) 0x3fa86e63bc7d03c8ULL }, 1007 + { &fnv_test_str[87], (Fnv64_t) 0xa8375b79486d6cd8ULL }, 1008 + { &fnv_test_str[88], (Fnv64_t) 0xa0d18504e316ac54ULL }, 1009 + { &fnv_test_str[89], (Fnv64_t) 0x08a97b0004e7fe54ULL }, 1010 + { &fnv_test_str[90], (Fnv64_t) 0xa0d18504e316ac57ULL }, 1011 + { &fnv_test_str[91], (Fnv64_t) 0x1152f60009cffda9ULL }, 1012 + { &fnv_test_str[92], (Fnv64_t) 0xa0d18504e316ac56ULL }, 1013 + { &fnv_test_str[93], (Fnv64_t) 0x19fc71000eb7fcfeULL }, 1014 + { &fnv_test_str[94], (Fnv64_t) 0xa0d18504e316ac51ULL }, 1015 + { &fnv_test_str[95], (Fnv64_t) 0x22a5ec00139ffa53ULL }, 1016 + { &fnv_test_str[96], (Fnv64_t) 0x29bed00139779a33ULL }, 1017 + { &fnv_test_str[97], (Fnv64_t) 0x4dbc81014e3c19f5ULL }, 1018 + { &fnv_test_str[98], (Fnv64_t) 0x29bed00139779a3dULL }, 1019 + { &fnv_test_str[99], (Fnv64_t) 0x81a72b016b9f7573ULL }, 1020 + { &fnv_test_str[100], (Fnv64_t) 0x29bed00139779a23ULL }, 1021 + { &fnv_test_str[101], (Fnv64_t) 0xd85411019cbbce45ULL }, 1022 + { &fnv_test_str[102], (Fnv64_t) 0xf548616b8621d657ULL }, 1023 + { &fnv_test_str[103], (Fnv64_t) 0xebd3e0b4eb7f35d5ULL }, 1024 + { &fnv_test_str[104], (Fnv64_t) 0xf548616b8621d654ULL }, 1025 + { &fnv_test_str[105], (Fnv64_t) 0xebd3ddb4eb7f30bcULL }, 1026 + { &fnv_test_str[106], (Fnv64_t) 0xf548616b8621d655ULL }, 1027 + { &fnv_test_str[107], (Fnv64_t) 0xebd3deb4eb7f326fULL }, 1028 + { &fnv_test_str[108], (Fnv64_t) 0x581cb60340ab0968ULL }, 1029 + { &fnv_test_str[109], (Fnv64_t) 0x63d2af86e2a0fbb8ULL }, 1030 + { &fnv_test_str[110], (Fnv64_t) 0x581cb70340ab0b37ULL }, 1031 + { &fnv_test_str[111], (Fnv64_t) 0x63d63186e2a40e75ULL }, 1032 + { &fnv_test_str[112], (Fnv64_t) 0x581cc40340ab212eULL }, 1033 + { &fnv_test_str[113], (Fnv64_t) 0x64023f86e2c9612aULL }, 1034 + { &fnv_test_str[114], (Fnv64_t) 0xdbda6a26c33c909fULL }, 1035 + { &fnv_test_str[115], (Fnv64_t) 0xd0b2feddbfe9be2dULL }, 1036 + { &fnv_test_str[116], (Fnv64_t) 0x9c9eae3f5d037decULL }, 1037 + { &fnv_test_str[117], (Fnv64_t) 0x252001ab0ceef804ULL }, 1038 + { &fnv_test_str[118], (Fnv64_t) 0x4456a56f9e05cfefULL }, 1039 + { &fnv_test_str[119], (Fnv64_t) 0x250b0ba983e0531dULL }, 1040 + { &fnv_test_str[120], (Fnv64_t) 0x52b007213b27b33eULL }, 1041 + { &fnv_test_str[121], (Fnv64_t) 0xcbf29ce484222325ULL }, 1042 + { &fnv_test_str[122], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, 1043 + { &fnv_test_str[123], (Fnv64_t) 0x128599ccddae09f8ULL }, 1044 + { &fnv_test_str[124], (Fnv64_t) 0x270e4f1caebaf068ULL }, 1045 + { &fnv_test_str[125], (Fnv64_t) 0x01517d497446a395ULL }, 1046 + { &fnv_test_str[126], (Fnv64_t) 0x9af5a29a89450b40ULL }, 1047 + { &fnv_test_str[127], (Fnv64_t) 0xb502f6c063ba72e8ULL }, 1048 + { &fnv_test_str[128], (Fnv64_t) 0xacf41561498ca7dfULL }, 1049 + { &fnv_test_str[129], (Fnv64_t) 0x6be8c2423a351542ULL }, 1050 + { &fnv_test_str[130], (Fnv64_t) 0xd04f1f6da96ce4a3ULL }, 1051 + { &fnv_test_str[131], (Fnv64_t) 0x69eb9a8f282c7235ULL }, 1052 + { &fnv_test_str[132], (Fnv64_t) 0x6a7e5a418f77cfc5ULL }, 1053 + { &fnv_test_str[133], (Fnv64_t) 0xbcaf568ddc2ecba0ULL }, 1054 + { &fnv_test_str[134], (Fnv64_t) 0xb03b5cc4c38f8b1fULL }, 1055 + { &fnv_test_str[135], (Fnv64_t) 0xf89a9f51432db828ULL }, 1056 + { &fnv_test_str[136], (Fnv64_t) 0x549e856be6103429ULL }, 1057 + { &fnv_test_str[137], (Fnv64_t) 0x3cf50d224d29377aULL }, 1058 + { &fnv_test_str[138], (Fnv64_t) 0xdb762df418c10c37ULL }, 1059 + { &fnv_test_str[139], (Fnv64_t) 0xfeeb4226b0e9a6baULL }, 1060 + { &fnv_test_str[140], (Fnv64_t) 0x7004a4cd9310c052ULL }, 1061 + { &fnv_test_str[141], (Fnv64_t) 0xd1c727d7f5329276ULL }, 1062 + { &fnv_test_str[142], (Fnv64_t) 0xbe313796596ce908ULL }, 1063 + { &fnv_test_str[143], (Fnv64_t) 0x768f67ede090fcc5ULL }, 1064 + { &fnv_test_str[144], (Fnv64_t) 0xa81563cc9db9bfc3ULL }, 1065 + { &fnv_test_str[145], (Fnv64_t) 0x47194043c55197a8ULL }, 1066 + { &fnv_test_str[146], (Fnv64_t) 0xc99d81864aebab02ULL }, 1067 + { &fnv_test_str[147], (Fnv64_t) 0xcc1f161b235ea4a2ULL }, 1068 + { &fnv_test_str[148], (Fnv64_t) 0xaadab0c420ecd434ULL }, 1069 + { &fnv_test_str[149], (Fnv64_t) 0x6b3c034d6f44d740ULL }, 1070 + { &fnv_test_str[150], (Fnv64_t) 0x73a45e850602cbc6ULL }, 1071 + { &fnv_test_str[151], (Fnv64_t) 0x72360f04f0cd227bULL }, 1072 + { &fnv_test_str[152], (Fnv64_t) 0xa9ca80be384a778fULL }, 1073 + { &fnv_test_str[153], (Fnv64_t) 0xd4085e66906889e3ULL }, 1074 + { &fnv_test_str[154], (Fnv64_t) 0x93aa8b2748efdbc8ULL }, 1075 + { &fnv_test_str[155], (Fnv64_t) 0x6f8cd678407436a2ULL }, 1076 + { &fnv_test_str[156], (Fnv64_t) 0xf39a43d4dc8be4c7ULL }, 1077 + { &fnv_test_str[157], (Fnv64_t) 0xd7f5cec91125d245ULL }, 1078 + { &fnv_test_str[158], (Fnv64_t) 0x691d7b73be18adc4ULL }, 1079 + { &fnv_test_str[159], (Fnv64_t) 0xf4361e01caf6b691ULL }, 1080 + { &fnv_test_str[160], (Fnv64_t) 0xde7d8264f64be089ULL }, 1081 + { &fnv_test_str[161], (Fnv64_t) 0xa34ff43e5545c06fULL }, 1082 + { &fnv_test_str[162], (Fnv64_t) 0x181f0b8e908a2bdeULL }, 1083 + { &fnv_test_str[163], (Fnv64_t) 0x28a965b78ddbc071ULL }, 1084 + { &fnv_test_str[164], (Fnv64_t) 0xead9cea0e3cc6ae5ULL }, 1085 + { &fnv_test_str[165], (Fnv64_t) 0x0b6743153b43ebbaULL }, 1086 + { &fnv_test_str[166], (Fnv64_t) 0xa7aa3f012c74528dULL }, 1087 + { &fnv_test_str[167], (Fnv64_t) 0x2d5d8ad7f9dffeb7ULL }, 1088 + { &fnv_test_str[168], (Fnv64_t) 0x00750fb6e19624eaULL }, 1089 + { &fnv_test_str[169], (Fnv64_t) 0x01c125a4e6c76c82ULL }, 1090 + { &fnv_test_str[170], (Fnv64_t) 0x3fde3afac0722f1fULL }, 1091 + { &fnv_test_str[171], (Fnv64_t) 0xd7c3eaf4abaa379dULL }, 1092 + { &fnv_test_str[172], (Fnv64_t) 0xd2217e1c923c9f3fULL }, 1093 + { &fnv_test_str[173], (Fnv64_t) 0x82d0a2e3b725caf6ULL }, 1094 + { &fnv_test_str[174], (Fnv64_t) 0x0a10bee8eeb72e4fULL }, 1095 + { &fnv_test_str[175], (Fnv64_t) 0xc530e8723e72c6fdULL }, 1096 + { &fnv_test_str[176], (Fnv64_t) 0xd8d34dcd2e7bad99ULL }, 1097 + { &fnv_test_str[177], (Fnv64_t) 0xecf77466e9a2baf3ULL }, 1098 + { &fnv_test_str[178], (Fnv64_t) 0xde3d2ddb043b9666ULL }, 1099 + { &fnv_test_str[179], (Fnv64_t) 0xd1cc824e1a8157d8ULL }, 1100 + { &fnv_test_str[180], (Fnv64_t) 0x7d5c68ecbc90512eULL }, 1101 + { &fnv_test_str[181], (Fnv64_t) 0x2f7c691b1d7c76d8ULL }, 1102 + { &fnv_test_str[182], (Fnv64_t) 0x5d88c2bad3a46bc8ULL }, 1103 + { &fnv_test_str[183], (Fnv64_t) 0xdf107320276647a0ULL }, 1104 + { &fnv_test_str[184], (Fnv64_t) 0x0f78f22e7e70e9bcULL }, 1105 + { &fnv_test_str[185], (Fnv64_t) 0x8c67be5c80f67d04ULL }, 1106 + { &fnv_test_str[186], (Fnv64_t) 0x07c1adfa4d019194ULL }, 1107 + { &fnv_test_str[187], (Fnv64_t) 0xce1312420c5b1af4ULL }, 1108 + { &fnv_test_str[188], (Fnv64_t) 0x043a41b2dc53ab24ULL }, 1109 + { &fnv_test_str[189], (Fnv64_t) 0x0b038eebf7340860ULL }, 1110 + { &fnv_test_str[190], (Fnv64_t) 0x1bcd837353fb69b0ULL }, 1111 + { &fnv_test_str[191], (Fnv64_t) 0x46f992fc59eff180ULL }, 1112 + { &fnv_test_str[192], (Fnv64_t) 0x497678ee29ae79c0ULL }, 1113 + { &fnv_test_str[193], (Fnv64_t) 0xb10a62280ddd4450ULL }, 1114 + { &fnv_test_str[194], (Fnv64_t) 0x35eb228db4d68140ULL }, 1115 + { &fnv_test_str[195], (Fnv64_t) 0x8b350e86d9470870ULL }, 1116 + { &fnv_test_str[196], (Fnv64_t) 0x4e1fbdb2812e9540ULL }, 1117 + { &fnv_test_str[197], (Fnv64_t) 0x051e080df69a0600ULL }, 1118 + { &fnv_test_str[198], (Fnv64_t) 0x45e1e8ae54dadb40ULL }, 1119 + { &fnv_test_str[199], (Fnv64_t) 0x0000000000000000ULL }, 1120 + { &fnv_test_str[200], (Fnv64_t) 0xcd73806290557064ULL }, 1121 + { &fnv_test_str[201], (Fnv64_t) 0x2613a37bbe0317c8ULL }, 1122 + { &fnv_test_str[202], (Fnv64_t) 0x1480e21fcf2ae5e4ULL }, 1123 + { NULL, (Fnv64_t) 0 } 1124 + }; 1125 + #else /* HAVE_64BIT_LONG_LONG */ 1126 + struct fnv0_64_test_vector fnv0_64_vector[] = { 1127 + { &fnv_test_str[0], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, 1128 + { &fnv_test_str[1], (Fnv64_t) {0x00000061UL, 0x00000000UL} }, 1129 + { &fnv_test_str[2], (Fnv64_t) {0x00000062UL, 0x00000000UL} }, 1130 + { &fnv_test_str[3], (Fnv64_t) {0x00000063UL, 0x00000000UL} }, 1131 + { &fnv_test_str[4], (Fnv64_t) {0x00000064UL, 0x00000000UL} }, 1132 + { &fnv_test_str[5], (Fnv64_t) {0x00000065UL, 0x00000000UL} }, 1133 + { &fnv_test_str[6], (Fnv64_t) {0x00000066UL, 0x00000000UL} }, 1134 + { &fnv_test_str[7], (Fnv64_t) {0x0000ad3dUL, 0x00006600UL} }, 1135 + { &fnv_test_str[8], (Fnv64_t) {0x01265ec8UL, 0x015a8f00UL} }, 1136 + { &fnv_test_str[9], (Fnv64_t) {0xf4330dbaUL, 0x733fc501UL} }, 1137 + { &fnv_test_str[10], (Fnv64_t) {0xf2c0536fUL, 0x08697c51UL} }, 1138 + { &fnv_test_str[11], (Fnv64_t) {0x7ccdc5efUL, 0x0b91ae3fUL} }, 1139 + { &fnv_test_str[12], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, 1140 + { &fnv_test_str[13], (Fnv64_t) {0x0000a4d3UL, 0x00006100UL} }, 1141 + { &fnv_test_str[14], (Fnv64_t) {0x0000a686UL, 0x00006200UL} }, 1142 + { &fnv_test_str[15], (Fnv64_t) {0x0000a839UL, 0x00006300UL} }, 1143 + { &fnv_test_str[16], (Fnv64_t) {0x0000a9ecUL, 0x00006400UL} }, 1144 + { &fnv_test_str[17], (Fnv64_t) {0x0000ab9fUL, 0x00006500UL} }, 1145 + { &fnv_test_str[18], (Fnv64_t) {0x0000ad52UL, 0x00006600UL} }, 1146 + { &fnv_test_str[19], (Fnv64_t) {0x01265ea7UL, 0x015a8f00UL} }, 1147 + { &fnv_test_str[20], (Fnv64_t) {0xf4330dd8UL, 0x733fc501UL} }, 1148 + { &fnv_test_str[21], (Fnv64_t) {0xf2c0530eUL, 0x08697c51UL} }, 1149 + { &fnv_test_str[22], (Fnv64_t) {0x7ccdc59dUL, 0x0b91ae3fUL} }, 1150 + { &fnv_test_str[23], (Fnv64_t) {0x11a7551dUL, 0x765104e1UL} }, 1151 + { &fnv_test_str[24], (Fnv64_t) {0x0000a851UL, 0x00006300UL} }, 1152 + { &fnv_test_str[25], (Fnv64_t) {0x011e01ccUL, 0x01508a00UL} }, 1153 + { &fnv_test_str[26], (Fnv64_t) {0xe5fd0dcaUL, 0x59dc4a01UL} }, 1154 + { &fnv_test_str[27], (Fnv64_t) {0xccfe6e59UL, 0xae5f8b39UL} }, 1155 + { &fnv_test_str[28], (Fnv64_t) {0x54558154UL, 0x4ac7ec37UL} }, 1156 + { &fnv_test_str[29], (Fnv64_t) {0x4d4ac19cUL, 0x6737b604UL} }, 1157 + { &fnv_test_str[30], (Fnv64_t) {0x5606fc63UL, 0xae6be54fUL} }, 1158 + { &fnv_test_str[31], (Fnv64_t) {0x2ddedc58UL, 0x685308cfUL} }, 1159 + { &fnv_test_str[32], (Fnv64_t) {0xf1b069fbUL, 0x23f4500aUL} }, 1160 + { &fnv_test_str[33], (Fnv64_t) {0xaec415a1UL, 0xc88dfd98UL} }, 1161 + { &fnv_test_str[34], (Fnv64_t) {0xf730c0fbUL, 0x8d5b8b70UL} }, 1162 + { &fnv_test_str[35], (Fnv64_t) {0x07d7eae4UL, 0x634eebf4UL} }, 1163 + { &fnv_test_str[36], (Fnv64_t) {0x53e4211eUL, 0x9705d3a9UL} }, 1164 + { &fnv_test_str[37], (Fnv64_t) {0x8ca4459fUL, 0x8307c6b9UL} }, 1165 + { &fnv_test_str[38], (Fnv64_t) {0xfb224d0cUL, 0x4a7c4c49UL} }, 1166 + { &fnv_test_str[39], (Fnv64_t) {0xbb48eb6eUL, 0xb382adb5UL} }, 1167 + { &fnv_test_str[40], (Fnv64_t) {0x011e01a3UL, 0x01508a00UL} }, 1168 + { &fnv_test_str[41], (Fnv64_t) {0xe5fd0da4UL, 0x59dc4a01UL} }, 1169 + { &fnv_test_str[42], (Fnv64_t) {0xccfe6e3eUL, 0xae5f8b39UL} }, 1170 + { &fnv_test_str[43], (Fnv64_t) {0x5455813bUL, 0x4ac7ec37UL} }, 1171 + { &fnv_test_str[44], (Fnv64_t) {0x4d4ac1bcUL, 0x6737b604UL} }, 1172 + { &fnv_test_str[45], (Fnv64_t) {0x5606fc14UL, 0xae6be54fUL} }, 1173 + { &fnv_test_str[46], (Fnv64_t) {0x2ddedc39UL, 0x685308cfUL} }, 1174 + { &fnv_test_str[47], (Fnv64_t) {0xf1b06988UL, 0x23f4500aUL} }, 1175 + { &fnv_test_str[48], (Fnv64_t) {0xaec41581UL, 0xc88dfd98UL} }, 1176 + { &fnv_test_str[49], (Fnv64_t) {0xf730c093UL, 0x8d5b8b70UL} }, 1177 + { &fnv_test_str[50], (Fnv64_t) {0x07d7ea81UL, 0x634eebf4UL} }, 1178 + { &fnv_test_str[51], (Fnv64_t) {0x53e4216cUL, 0x9705d3a9UL} }, 1179 + { &fnv_test_str[52], (Fnv64_t) {0x8ca445faUL, 0x8307c6b9UL} }, 1180 + { &fnv_test_str[53], (Fnv64_t) {0xfb224d2dUL, 0x4a7c4c49UL} }, 1181 + { &fnv_test_str[54], (Fnv64_t) {0xbb48eb64UL, 0xb382adb5UL} }, 1182 + { &fnv_test_str[55], (Fnv64_t) {0x3ce80beaUL, 0x4ff899cdUL} }, 1183 + { &fnv_test_str[56], (Fnv64_t) {0x0000a84cUL, 0x00006300UL} }, 1184 + { &fnv_test_str[57], (Fnv64_t) {0x011df956UL, 0x01508500UL} }, 1185 + { &fnv_test_str[58], (Fnv64_t) {0xe5eead46UL, 0x59cb5501UL} }, 1186 + { &fnv_test_str[59], (Fnv64_t) {0xb4906d81UL, 0x832eb839UL} }, 1187 + { &fnv_test_str[60], (Fnv64_t) {0xd16a1213UL, 0x78d08b0dUL} }, 1188 + { &fnv_test_str[61], (Fnv64_t) {0xd73cb628UL, 0xb46e5b7aUL} }, 1189 + { &fnv_test_str[62], (Fnv64_t) {0xbc298596UL, 0xd43b99bbUL} }, 1190 + { &fnv_test_str[63], (Fnv64_t) {0xba8dfd86UL, 0xcacbd000UL} }, 1191 + { &fnv_test_str[64], (Fnv64_t) {0xff45ca92UL, 0x264ff73cUL} }, 1192 + { &fnv_test_str[65], (Fnv64_t) {0xc3973661UL, 0x5fabaea5UL} }, 1193 + { &fnv_test_str[66], (Fnv64_t) {0x59f166bbUL, 0x27f024abUL} }, 1194 + { &fnv_test_str[67], (Fnv64_t) {0xd5318fa4UL, 0xce750a29UL} }, 1195 + { &fnv_test_str[68], (Fnv64_t) {0x433713d5UL, 0x026fe915UL} }, 1196 + { &fnv_test_str[69], (Fnv64_t) {0x3696b2e5UL, 0x5b3ce421UL} }, 1197 + { &fnv_test_str[70], (Fnv64_t) {0x011df924UL, 0x01508500UL} }, 1198 + { &fnv_test_str[71], (Fnv64_t) {0xe5eead22UL, 0x59cb5501UL} }, 1199 + { &fnv_test_str[72], (Fnv64_t) {0xb4906df2UL, 0x832eb839UL} }, 1200 + { &fnv_test_str[73], (Fnv64_t) {0xd16a1233UL, 0x78d08b0dUL} }, 1201 + { &fnv_test_str[74], (Fnv64_t) {0xd73cb649UL, 0xb46e5b7aUL} }, 1202 + { &fnv_test_str[75], (Fnv64_t) {0xbc2985f8UL, 0xd43b99bbUL} }, 1203 + { &fnv_test_str[76], (Fnv64_t) {0xba8dfde2UL, 0xcacbd000UL} }, 1204 + { &fnv_test_str[77], (Fnv64_t) {0xff45cab2UL, 0x264ff73cUL} }, 1205 + { &fnv_test_str[78], (Fnv64_t) {0xc3973616UL, 0x5fabaea5UL} }, 1206 + { &fnv_test_str[79], (Fnv64_t) {0x59f166d3UL, 0x27f024abUL} }, 1207 + { &fnv_test_str[80], (Fnv64_t) {0xd5318fc1UL, 0xce750a29UL} }, 1208 + { &fnv_test_str[81], (Fnv64_t) {0x433713acUL, 0x026fe915UL} }, 1209 + { &fnv_test_str[82], (Fnv64_t) {0x3696b2efUL, 0x5b3ce421UL} }, 1210 + { &fnv_test_str[83], (Fnv64_t) {0xc211fb1fUL, 0x9f2a896fUL} }, 1211 + { &fnv_test_str[84], (Fnv64_t) {0x0000b0d1UL, 0x00006800UL} }, 1212 + { &fnv_test_str[85], (Fnv64_t) {0x012c7323UL, 0x01618900UL} }, 1213 + { &fnv_test_str[86], (Fnv64_t) {0xbc7d03c8UL, 0x3fa86e63UL} }, 1214 + { &fnv_test_str[87], (Fnv64_t) {0x486d6cd8UL, 0xa8375b79UL} }, 1215 + { &fnv_test_str[88], (Fnv64_t) {0xe316ac54UL, 0xa0d18504UL} }, 1216 + { &fnv_test_str[89], (Fnv64_t) {0x04e7fe54UL, 0x08a97b00UL} }, 1217 + { &fnv_test_str[90], (Fnv64_t) {0xe316ac57UL, 0xa0d18504UL} }, 1218 + { &fnv_test_str[91], (Fnv64_t) {0x09cffda9UL, 0x1152f600UL} }, 1219 + { &fnv_test_str[92], (Fnv64_t) {0xe316ac56UL, 0xa0d18504UL} }, 1220 + { &fnv_test_str[93], (Fnv64_t) {0x0eb7fcfeUL, 0x19fc7100UL} }, 1221 + { &fnv_test_str[94], (Fnv64_t) {0xe316ac51UL, 0xa0d18504UL} }, 1222 + { &fnv_test_str[95], (Fnv64_t) {0x139ffa53UL, 0x22a5ec00UL} }, 1223 + { &fnv_test_str[96], (Fnv64_t) {0x39779a33UL, 0x29bed001UL} }, 1224 + { &fnv_test_str[97], (Fnv64_t) {0x4e3c19f5UL, 0x4dbc8101UL} }, 1225 + { &fnv_test_str[98], (Fnv64_t) {0x39779a3dUL, 0x29bed001UL} }, 1226 + { &fnv_test_str[99], (Fnv64_t) {0x6b9f7573UL, 0x81a72b01UL} }, 1227 + { &fnv_test_str[100], (Fnv64_t) {0x39779a23UL, 0x29bed001UL} }, 1228 + { &fnv_test_str[101], (Fnv64_t) {0x9cbbce45UL, 0xd8541101UL} }, 1229 + { &fnv_test_str[102], (Fnv64_t) {0x8621d657UL, 0xf548616bUL} }, 1230 + { &fnv_test_str[103], (Fnv64_t) {0xeb7f35d5UL, 0xebd3e0b4UL} }, 1231 + { &fnv_test_str[104], (Fnv64_t) {0x8621d654UL, 0xf548616bUL} }, 1232 + { &fnv_test_str[105], (Fnv64_t) {0xeb7f30bcUL, 0xebd3ddb4UL} }, 1233 + { &fnv_test_str[106], (Fnv64_t) {0x8621d655UL, 0xf548616bUL} }, 1234 + { &fnv_test_str[107], (Fnv64_t) {0xeb7f326fUL, 0xebd3deb4UL} }, 1235 + { &fnv_test_str[108], (Fnv64_t) {0x40ab0968UL, 0x581cb603UL} }, 1236 + { &fnv_test_str[109], (Fnv64_t) {0xe2a0fbb8UL, 0x63d2af86UL} }, 1237 + { &fnv_test_str[110], (Fnv64_t) {0x40ab0b37UL, 0x581cb703UL} }, 1238 + { &fnv_test_str[111], (Fnv64_t) {0xe2a40e75UL, 0x63d63186UL} }, 1239 + { &fnv_test_str[112], (Fnv64_t) {0x40ab212eUL, 0x581cc403UL} }, 1240 + { &fnv_test_str[113], (Fnv64_t) {0xe2c9612aUL, 0x64023f86UL} }, 1241 + { &fnv_test_str[114], (Fnv64_t) {0xc33c909fUL, 0xdbda6a26UL} }, 1242 + { &fnv_test_str[115], (Fnv64_t) {0xbfe9be2dUL, 0xd0b2feddUL} }, 1243 + { &fnv_test_str[116], (Fnv64_t) {0x5d037decUL, 0x9c9eae3fUL} }, 1244 + { &fnv_test_str[117], (Fnv64_t) {0x0ceef804UL, 0x252001abUL} }, 1245 + { &fnv_test_str[118], (Fnv64_t) {0x9e05cfefUL, 0x4456a56fUL} }, 1246 + { &fnv_test_str[119], (Fnv64_t) {0x83e0531dUL, 0x250b0ba9UL} }, 1247 + { &fnv_test_str[120], (Fnv64_t) {0x3b27b33eUL, 0x52b00721UL} }, 1248 + { &fnv_test_str[121], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, 1249 + { &fnv_test_str[122], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, 1250 + { &fnv_test_str[123], (Fnv64_t) {0xddae09f8UL, 0x128599ccUL} }, 1251 + { &fnv_test_str[124], (Fnv64_t) {0xaebaf068UL, 0x270e4f1cUL} }, 1252 + { &fnv_test_str[125], (Fnv64_t) {0x7446a395UL, 0x01517d49UL} }, 1253 + { &fnv_test_str[126], (Fnv64_t) {0x89450b40UL, 0x9af5a29aUL} }, 1254 + { &fnv_test_str[127], (Fnv64_t) {0x63ba72e8UL, 0xb502f6c0UL} }, 1255 + { &fnv_test_str[128], (Fnv64_t) {0x498ca7dfUL, 0xacf41561UL} }, 1256 + { &fnv_test_str[129], (Fnv64_t) {0x3a351542UL, 0x6be8c242UL} }, 1257 + { &fnv_test_str[130], (Fnv64_t) {0xa96ce4a3UL, 0xd04f1f6dUL} }, 1258 + { &fnv_test_str[131], (Fnv64_t) {0x282c7235UL, 0x69eb9a8fUL} }, 1259 + { &fnv_test_str[132], (Fnv64_t) {0x8f77cfc5UL, 0x6a7e5a41UL} }, 1260 + { &fnv_test_str[133], (Fnv64_t) {0xdc2ecba0UL, 0xbcaf568dUL} }, 1261 + { &fnv_test_str[134], (Fnv64_t) {0xc38f8b1fUL, 0xb03b5cc4UL} }, 1262 + { &fnv_test_str[135], (Fnv64_t) {0x432db828UL, 0xf89a9f51UL} }, 1263 + { &fnv_test_str[136], (Fnv64_t) {0xe6103429UL, 0x549e856bUL} }, 1264 + { &fnv_test_str[137], (Fnv64_t) {0x4d29377aUL, 0x3cf50d22UL} }, 1265 + { &fnv_test_str[138], (Fnv64_t) {0x18c10c37UL, 0xdb762df4UL} }, 1266 + { &fnv_test_str[139], (Fnv64_t) {0xb0e9a6baUL, 0xfeeb4226UL} }, 1267 + { &fnv_test_str[140], (Fnv64_t) {0x9310c052UL, 0x7004a4cdUL} }, 1268 + { &fnv_test_str[141], (Fnv64_t) {0xf5329276UL, 0xd1c727d7UL} }, 1269 + { &fnv_test_str[142], (Fnv64_t) {0x596ce908UL, 0xbe313796UL} }, 1270 + { &fnv_test_str[143], (Fnv64_t) {0xe090fcc5UL, 0x768f67edUL} }, 1271 + { &fnv_test_str[144], (Fnv64_t) {0x9db9bfc3UL, 0xa81563ccUL} }, 1272 + { &fnv_test_str[145], (Fnv64_t) {0xc55197a8UL, 0x47194043UL} }, 1273 + { &fnv_test_str[146], (Fnv64_t) {0x4aebab02UL, 0xc99d8186UL} }, 1274 + { &fnv_test_str[147], (Fnv64_t) {0x235ea4a2UL, 0xcc1f161bUL} }, 1275 + { &fnv_test_str[148], (Fnv64_t) {0x20ecd434UL, 0xaadab0c4UL} }, 1276 + { &fnv_test_str[149], (Fnv64_t) {0x6f44d740UL, 0x6b3c034dUL} }, 1277 + { &fnv_test_str[150], (Fnv64_t) {0x0602cbc6UL, 0x73a45e85UL} }, 1278 + { &fnv_test_str[151], (Fnv64_t) {0xf0cd227bUL, 0x72360f04UL} }, 1279 + { &fnv_test_str[152], (Fnv64_t) {0x384a778fUL, 0xa9ca80beUL} }, 1280 + { &fnv_test_str[153], (Fnv64_t) {0x906889e3UL, 0xd4085e66UL} }, 1281 + { &fnv_test_str[154], (Fnv64_t) {0x48efdbc8UL, 0x93aa8b27UL} }, 1282 + { &fnv_test_str[155], (Fnv64_t) {0x407436a2UL, 0x6f8cd678UL} }, 1283 + { &fnv_test_str[156], (Fnv64_t) {0xdc8be4c7UL, 0xf39a43d4UL} }, 1284 + { &fnv_test_str[157], (Fnv64_t) {0x1125d245UL, 0xd7f5cec9UL} }, 1285 + { &fnv_test_str[158], (Fnv64_t) {0xbe18adc4UL, 0x691d7b73UL} }, 1286 + { &fnv_test_str[159], (Fnv64_t) {0xcaf6b691UL, 0xf4361e01UL} }, 1287 + { &fnv_test_str[160], (Fnv64_t) {0xf64be089UL, 0xde7d8264UL} }, 1288 + { &fnv_test_str[161], (Fnv64_t) {0x5545c06fUL, 0xa34ff43eUL} }, 1289 + { &fnv_test_str[162], (Fnv64_t) {0x908a2bdeUL, 0x181f0b8eUL} }, 1290 + { &fnv_test_str[163], (Fnv64_t) {0x8ddbc071UL, 0x28a965b7UL} }, 1291 + { &fnv_test_str[164], (Fnv64_t) {0xe3cc6ae5UL, 0xead9cea0UL} }, 1292 + { &fnv_test_str[165], (Fnv64_t) {0x3b43ebbaUL, 0x0b674315UL} }, 1293 + { &fnv_test_str[166], (Fnv64_t) {0x2c74528dUL, 0xa7aa3f01UL} }, 1294 + { &fnv_test_str[167], (Fnv64_t) {0xf9dffeb7UL, 0x2d5d8ad7UL} }, 1295 + { &fnv_test_str[168], (Fnv64_t) {0xe19624eaUL, 0x00750fb6UL} }, 1296 + { &fnv_test_str[169], (Fnv64_t) {0xe6c76c82UL, 0x01c125a4UL} }, 1297 + { &fnv_test_str[170], (Fnv64_t) {0xc0722f1fUL, 0x3fde3afaUL} }, 1298 + { &fnv_test_str[171], (Fnv64_t) {0xabaa379dUL, 0xd7c3eaf4UL} }, 1299 + { &fnv_test_str[172], (Fnv64_t) {0x923c9f3fUL, 0xd2217e1cUL} }, 1300 + { &fnv_test_str[173], (Fnv64_t) {0xb725caf6UL, 0x82d0a2e3UL} }, 1301 + { &fnv_test_str[174], (Fnv64_t) {0xeeb72e4fUL, 0x0a10bee8UL} }, 1302 + { &fnv_test_str[175], (Fnv64_t) {0x3e72c6fdUL, 0xc530e872UL} }, 1303 + { &fnv_test_str[176], (Fnv64_t) {0x2e7bad99UL, 0xd8d34dcdUL} }, 1304 + { &fnv_test_str[177], (Fnv64_t) {0xe9a2baf3UL, 0xecf77466UL} }, 1305 + { &fnv_test_str[178], (Fnv64_t) {0x043b9666UL, 0xde3d2ddbUL} }, 1306 + { &fnv_test_str[179], (Fnv64_t) {0x1a8157d8UL, 0xd1cc824eUL} }, 1307 + { &fnv_test_str[180], (Fnv64_t) {0xbc90512eUL, 0x7d5c68ecUL} }, 1308 + { &fnv_test_str[181], (Fnv64_t) {0x1d7c76d8UL, 0x2f7c691bUL} }, 1309 + { &fnv_test_str[182], (Fnv64_t) {0xd3a46bc8UL, 0x5d88c2baUL} }, 1310 + { &fnv_test_str[183], (Fnv64_t) {0x276647a0UL, 0xdf107320UL} }, 1311 + { &fnv_test_str[184], (Fnv64_t) {0x7e70e9bcUL, 0x0f78f22eUL} }, 1312 + { &fnv_test_str[185], (Fnv64_t) {0x80f67d04UL, 0x8c67be5cUL} }, 1313 + { &fnv_test_str[186], (Fnv64_t) {0x4d019194UL, 0x07c1adfaUL} }, 1314 + { &fnv_test_str[187], (Fnv64_t) {0x0c5b1af4UL, 0xce131242UL} }, 1315 + { &fnv_test_str[188], (Fnv64_t) {0xdc53ab24UL, 0x043a41b2UL} }, 1316 + { &fnv_test_str[189], (Fnv64_t) {0xf7340860UL, 0x0b038eebUL} }, 1317 + { &fnv_test_str[190], (Fnv64_t) {0x53fb69b0UL, 0x1bcd8373UL} }, 1318 + { &fnv_test_str[191], (Fnv64_t) {0x59eff180UL, 0x46f992fcUL} }, 1319 + { &fnv_test_str[192], (Fnv64_t) {0x29ae79c0UL, 0x497678eeUL} }, 1320 + { &fnv_test_str[193], (Fnv64_t) {0x0ddd4450UL, 0xb10a6228UL} }, 1321 + { &fnv_test_str[194], (Fnv64_t) {0xb4d68140UL, 0x35eb228dUL} }, 1322 + { &fnv_test_str[195], (Fnv64_t) {0xd9470870UL, 0x8b350e86UL} }, 1323 + { &fnv_test_str[196], (Fnv64_t) {0x812e9540UL, 0x4e1fbdb2UL} }, 1324 + { &fnv_test_str[197], (Fnv64_t) {0xf69a0600UL, 0x051e080dUL} }, 1325 + { &fnv_test_str[198], (Fnv64_t) {0x54dadb40UL, 0x45e1e8aeUL} }, 1326 + { &fnv_test_str[199], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, 1327 + { &fnv_test_str[200], (Fnv64_t) {0x90557064UL, 0xcd738062UL} }, 1328 + { &fnv_test_str[201], (Fnv64_t) {0xbe0317c8UL, 0x2613a37bUL} }, 1329 + { &fnv_test_str[202], (Fnv64_t) {0xcf2ae5e4UL, 0x1480e21fUL} }, 1330 + { NULL, (Fnv64_t) {0,0} } 1331 + }; 1332 + #endif /* HAVE_64BIT_LONG_LONG */ 1333 + 1334 + /* FNV-1 64 bit test vectors */ 1335 + #if defined(HAVE_64BIT_LONG_LONG) 1336 + struct fnv1_64_test_vector fnv1_64_vector[] = { 1337 + { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL }, 1338 + { &fnv_test_str[1], (Fnv64_t) 0xaf63bd4c8601b7beULL }, 1339 + { &fnv_test_str[2], (Fnv64_t) 0xaf63bd4c8601b7bdULL }, 1340 + { &fnv_test_str[3], (Fnv64_t) 0xaf63bd4c8601b7bcULL }, 1341 + { &fnv_test_str[4], (Fnv64_t) 0xaf63bd4c8601b7bbULL }, 1342 + { &fnv_test_str[5], (Fnv64_t) 0xaf63bd4c8601b7baULL }, 1343 + { &fnv_test_str[6], (Fnv64_t) 0xaf63bd4c8601b7b9ULL }, 1344 + { &fnv_test_str[7], (Fnv64_t) 0x08326207b4eb2f34ULL }, 1345 + { &fnv_test_str[8], (Fnv64_t) 0xd8cbc7186ba13533ULL }, 1346 + { &fnv_test_str[9], (Fnv64_t) 0x0378817ee2ed65cbULL }, 1347 + { &fnv_test_str[10], (Fnv64_t) 0xd329d59b9963f790ULL }, 1348 + { &fnv_test_str[11], (Fnv64_t) 0x340d8765a4dda9c2ULL }, 1349 + { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, 1350 + { &fnv_test_str[13], (Fnv64_t) 0x08326707b4eb37daULL }, 1351 + { &fnv_test_str[14], (Fnv64_t) 0x08326607b4eb3627ULL }, 1352 + { &fnv_test_str[15], (Fnv64_t) 0x08326507b4eb3474ULL }, 1353 + { &fnv_test_str[16], (Fnv64_t) 0x08326407b4eb32c1ULL }, 1354 + { &fnv_test_str[17], (Fnv64_t) 0x08326307b4eb310eULL }, 1355 + { &fnv_test_str[18], (Fnv64_t) 0x08326207b4eb2f5bULL }, 1356 + { &fnv_test_str[19], (Fnv64_t) 0xd8cbc7186ba1355cULL }, 1357 + { &fnv_test_str[20], (Fnv64_t) 0x0378817ee2ed65a9ULL }, 1358 + { &fnv_test_str[21], (Fnv64_t) 0xd329d59b9963f7f1ULL }, 1359 + { &fnv_test_str[22], (Fnv64_t) 0x340d8765a4dda9b0ULL }, 1360 + { &fnv_test_str[23], (Fnv64_t) 0x50a6d3b724a774a6ULL }, 1361 + { &fnv_test_str[24], (Fnv64_t) 0x08326507b4eb341cULL }, 1362 + { &fnv_test_str[25], (Fnv64_t) 0xd8d5c8186ba98bfbULL }, 1363 + { &fnv_test_str[26], (Fnv64_t) 0x1ccefc7ef118dbefULL }, 1364 + { &fnv_test_str[27], (Fnv64_t) 0x0c92fab3ad3db77aULL }, 1365 + { &fnv_test_str[28], (Fnv64_t) 0x9b77794f5fdec421ULL }, 1366 + { &fnv_test_str[29], (Fnv64_t) 0x0ac742dfe7874433ULL }, 1367 + { &fnv_test_str[30], (Fnv64_t) 0xd7dad5766ad8e2deULL }, 1368 + { &fnv_test_str[31], (Fnv64_t) 0xa1bb96378e897f5bULL }, 1369 + { &fnv_test_str[32], (Fnv64_t) 0x5b3f9b6733a367d2ULL }, 1370 + { &fnv_test_str[33], (Fnv64_t) 0xb07ce25cbea969f6ULL }, 1371 + { &fnv_test_str[34], (Fnv64_t) 0x8d9e9997f9df0d6aULL }, 1372 + { &fnv_test_str[35], (Fnv64_t) 0x838c673d9603cb7bULL }, 1373 + { &fnv_test_str[36], (Fnv64_t) 0x8b5ee8a5e872c273ULL }, 1374 + { &fnv_test_str[37], (Fnv64_t) 0x4507c4e9fb00690cULL }, 1375 + { &fnv_test_str[38], (Fnv64_t) 0x4c9ca59581b27f45ULL }, 1376 + { &fnv_test_str[39], (Fnv64_t) 0xe0aca20b624e4235ULL }, 1377 + { &fnv_test_str[40], (Fnv64_t) 0xd8d5c8186ba98b94ULL }, 1378 + { &fnv_test_str[41], (Fnv64_t) 0x1ccefc7ef118db81ULL }, 1379 + { &fnv_test_str[42], (Fnv64_t) 0x0c92fab3ad3db71dULL }, 1380 + { &fnv_test_str[43], (Fnv64_t) 0x9b77794f5fdec44eULL }, 1381 + { &fnv_test_str[44], (Fnv64_t) 0x0ac742dfe7874413ULL }, 1382 + { &fnv_test_str[45], (Fnv64_t) 0xd7dad5766ad8e2a9ULL }, 1383 + { &fnv_test_str[46], (Fnv64_t) 0xa1bb96378e897f3aULL }, 1384 + { &fnv_test_str[47], (Fnv64_t) 0x5b3f9b6733a367a1ULL }, 1385 + { &fnv_test_str[48], (Fnv64_t) 0xb07ce25cbea969d6ULL }, 1386 + { &fnv_test_str[49], (Fnv64_t) 0x8d9e9997f9df0d02ULL }, 1387 + { &fnv_test_str[50], (Fnv64_t) 0x838c673d9603cb1eULL }, 1388 + { &fnv_test_str[51], (Fnv64_t) 0x8b5ee8a5e872c201ULL }, 1389 + { &fnv_test_str[52], (Fnv64_t) 0x4507c4e9fb006969ULL }, 1390 + { &fnv_test_str[53], (Fnv64_t) 0x4c9ca59581b27f64ULL }, 1391 + { &fnv_test_str[54], (Fnv64_t) 0xe0aca20b624e423fULL }, 1392 + { &fnv_test_str[55], (Fnv64_t) 0x13998e580afa800fULL }, 1393 + { &fnv_test_str[56], (Fnv64_t) 0x08326507b4eb3401ULL }, 1394 + { &fnv_test_str[57], (Fnv64_t) 0xd8d5ad186ba95dc1ULL }, 1395 + { &fnv_test_str[58], (Fnv64_t) 0x1c72e17ef0ca4e97ULL }, 1396 + { &fnv_test_str[59], (Fnv64_t) 0x2183c1b327c38ae6ULL }, 1397 + { &fnv_test_str[60], (Fnv64_t) 0xb66d096c914504f2ULL }, 1398 + { &fnv_test_str[61], (Fnv64_t) 0x404bf57ad8476757ULL }, 1399 + { &fnv_test_str[62], (Fnv64_t) 0x887976bd815498bbULL }, 1400 + { &fnv_test_str[63], (Fnv64_t) 0x3afd7f02c2bf85a5ULL }, 1401 + { &fnv_test_str[64], (Fnv64_t) 0xfc4476b0eb70177fULL }, 1402 + { &fnv_test_str[65], (Fnv64_t) 0x186d2da00f77ecbaULL }, 1403 + { &fnv_test_str[66], (Fnv64_t) 0xf97140fa48c74066ULL }, 1404 + { &fnv_test_str[67], (Fnv64_t) 0xa2b1cf49aa926d37ULL }, 1405 + { &fnv_test_str[68], (Fnv64_t) 0x0690712cd6cf940cULL }, 1406 + { &fnv_test_str[69], (Fnv64_t) 0xf7045b3102b8906eULL }, 1407 + { &fnv_test_str[70], (Fnv64_t) 0xd8d5ad186ba95db3ULL }, 1408 + { &fnv_test_str[71], (Fnv64_t) 0x1c72e17ef0ca4ef3ULL }, 1409 + { &fnv_test_str[72], (Fnv64_t) 0x2183c1b327c38a95ULL }, 1410 + { &fnv_test_str[73], (Fnv64_t) 0xb66d096c914504d2ULL }, 1411 + { &fnv_test_str[74], (Fnv64_t) 0x404bf57ad8476736ULL }, 1412 + { &fnv_test_str[75], (Fnv64_t) 0x887976bd815498d5ULL }, 1413 + { &fnv_test_str[76], (Fnv64_t) 0x3afd7f02c2bf85c1ULL }, 1414 + { &fnv_test_str[77], (Fnv64_t) 0xfc4476b0eb70175fULL }, 1415 + { &fnv_test_str[78], (Fnv64_t) 0x186d2da00f77eccdULL }, 1416 + { &fnv_test_str[79], (Fnv64_t) 0xf97140fa48c7400eULL }, 1417 + { &fnv_test_str[80], (Fnv64_t) 0xa2b1cf49aa926d52ULL }, 1418 + { &fnv_test_str[81], (Fnv64_t) 0x0690712cd6cf9475ULL }, 1419 + { &fnv_test_str[82], (Fnv64_t) 0xf7045b3102b89064ULL }, 1420 + { &fnv_test_str[83], (Fnv64_t) 0x74f762479f9d6aeaULL }, 1421 + { &fnv_test_str[84], (Fnv64_t) 0x08326007b4eb2b9cULL }, 1422 + { &fnv_test_str[85], (Fnv64_t) 0xd8c4c9186b9b1a14ULL }, 1423 + { &fnv_test_str[86], (Fnv64_t) 0x7b495389bdbdd4c7ULL }, 1424 + { &fnv_test_str[87], (Fnv64_t) 0x3b6dba0d69908e25ULL }, 1425 + { &fnv_test_str[88], (Fnv64_t) 0xd6b2b17bf4b71261ULL }, 1426 + { &fnv_test_str[89], (Fnv64_t) 0x447bfb7f98e615b5ULL }, 1427 + { &fnv_test_str[90], (Fnv64_t) 0xd6b2b17bf4b71262ULL }, 1428 + { &fnv_test_str[91], (Fnv64_t) 0x3bd2807f93fe1660ULL }, 1429 + { &fnv_test_str[92], (Fnv64_t) 0xd6b2b17bf4b71263ULL }, 1430 + { &fnv_test_str[93], (Fnv64_t) 0x3329057f8f16170bULL }, 1431 + { &fnv_test_str[94], (Fnv64_t) 0xd6b2b17bf4b71264ULL }, 1432 + { &fnv_test_str[95], (Fnv64_t) 0x2a7f8a7f8a2e19b6ULL }, 1433 + { &fnv_test_str[96], (Fnv64_t) 0x23d3767e64b2f98aULL }, 1434 + { &fnv_test_str[97], (Fnv64_t) 0xff768d7e4f9d86a4ULL }, 1435 + { &fnv_test_str[98], (Fnv64_t) 0x23d3767e64b2f984ULL }, 1436 + { &fnv_test_str[99], (Fnv64_t) 0xccd1837e334e4aa6ULL }, 1437 + { &fnv_test_str[100], (Fnv64_t) 0x23d3767e64b2f99aULL }, 1438 + { &fnv_test_str[101], (Fnv64_t) 0x7691fd7e028f6754ULL }, 1439 + { &fnv_test_str[102], (Fnv64_t) 0x34ad3b1041204318ULL }, 1440 + { &fnv_test_str[103], (Fnv64_t) 0xa29e749ea9d201c8ULL }, 1441 + { &fnv_test_str[104], (Fnv64_t) 0x34ad3b104120431bULL }, 1442 + { &fnv_test_str[105], (Fnv64_t) 0xa29e779ea9d206e1ULL }, 1443 + { &fnv_test_str[106], (Fnv64_t) 0x34ad3b104120431aULL }, 1444 + { &fnv_test_str[107], (Fnv64_t) 0xa29e769ea9d2052eULL }, 1445 + { &fnv_test_str[108], (Fnv64_t) 0x02a17ebca4aa3497ULL }, 1446 + { &fnv_test_str[109], (Fnv64_t) 0x229ef18bcd375c95ULL }, 1447 + { &fnv_test_str[110], (Fnv64_t) 0x02a17dbca4aa32c8ULL }, 1448 + { &fnv_test_str[111], (Fnv64_t) 0x229b6f8bcd3449d8ULL }, 1449 + { &fnv_test_str[112], (Fnv64_t) 0x02a184bca4aa3ed5ULL }, 1450 + { &fnv_test_str[113], (Fnv64_t) 0x22b3618bcd48c3efULL }, 1451 + { &fnv_test_str[114], (Fnv64_t) 0x5c2c346706186f36ULL }, 1452 + { &fnv_test_str[115], (Fnv64_t) 0xb78c410f5b84f8c2ULL }, 1453 + { &fnv_test_str[116], (Fnv64_t) 0xed9478212b267395ULL }, 1454 + { &fnv_test_str[117], (Fnv64_t) 0xd9bbb55c5256662fULL }, 1455 + { &fnv_test_str[118], (Fnv64_t) 0x8c54f0203249438aULL }, 1456 + { &fnv_test_str[119], (Fnv64_t) 0xbd9790b5727dc37eULL }, 1457 + { &fnv_test_str[120], (Fnv64_t) 0xa64e5f36c9e2b0e3ULL }, 1458 + { &fnv_test_str[121], (Fnv64_t) 0x8fd0680da3088a04ULL }, 1459 + { &fnv_test_str[122], (Fnv64_t) 0x67aad32c078284ccULL }, 1460 + { &fnv_test_str[123], (Fnv64_t) 0xb37d55d81c57b331ULL }, 1461 + { &fnv_test_str[124], (Fnv64_t) 0x55ac0f3829057c43ULL }, 1462 + { &fnv_test_str[125], (Fnv64_t) 0xcb27f4b8e1b6cc20ULL }, 1463 + { &fnv_test_str[126], (Fnv64_t) 0x26caf88bcbef2d19ULL }, 1464 + { &fnv_test_str[127], (Fnv64_t) 0x8e6e063b97e61b8fULL }, 1465 + { &fnv_test_str[128], (Fnv64_t) 0xb42750f7f3b7c37eULL }, 1466 + { &fnv_test_str[129], (Fnv64_t) 0xf3c6ba64cf7ca99bULL }, 1467 + { &fnv_test_str[130], (Fnv64_t) 0xebfb69b427ea80feULL }, 1468 + { &fnv_test_str[131], (Fnv64_t) 0x39b50c3ed970f46cULL }, 1469 + { &fnv_test_str[132], (Fnv64_t) 0x5b9b177aa3eb3e8aULL }, 1470 + { &fnv_test_str[133], (Fnv64_t) 0x6510063ecf4ec903ULL }, 1471 + { &fnv_test_str[134], (Fnv64_t) 0x2b3bbd2c00797c7aULL }, 1472 + { &fnv_test_str[135], (Fnv64_t) 0xf1d6204ff5cb4aa7ULL }, 1473 + { &fnv_test_str[136], (Fnv64_t) 0x4836e27ccf099f38ULL }, 1474 + { &fnv_test_str[137], (Fnv64_t) 0x82efbb0dd073b44dULL }, 1475 + { &fnv_test_str[138], (Fnv64_t) 0x4a80c282ffd7d4c6ULL }, 1476 + { &fnv_test_str[139], (Fnv64_t) 0x305d1a9c9ee43bdfULL }, 1477 + { &fnv_test_str[140], (Fnv64_t) 0x15c366948ffc6997ULL }, 1478 + { &fnv_test_str[141], (Fnv64_t) 0x80153ae218916e7bULL }, 1479 + { &fnv_test_str[142], (Fnv64_t) 0xfa23e2bdf9e2a9e1ULL }, 1480 + { &fnv_test_str[143], (Fnv64_t) 0xd47e8d8a2333c6deULL }, 1481 + { &fnv_test_str[144], (Fnv64_t) 0x7e128095f688b056ULL }, 1482 + { &fnv_test_str[145], (Fnv64_t) 0x2f5356890efcedabULL }, 1483 + { &fnv_test_str[146], (Fnv64_t) 0x95c2b383014f55c5ULL }, 1484 + { &fnv_test_str[147], (Fnv64_t) 0x4727a5339ce6070fULL }, 1485 + { &fnv_test_str[148], (Fnv64_t) 0xb0555ecd575108e9ULL }, 1486 + { &fnv_test_str[149], (Fnv64_t) 0x48d785770bb4af37ULL }, 1487 + { &fnv_test_str[150], (Fnv64_t) 0x09d4701c12af02b1ULL }, 1488 + { &fnv_test_str[151], (Fnv64_t) 0x79f031e78f3cf62eULL }, 1489 + { &fnv_test_str[152], (Fnv64_t) 0x52a1ee85db1b5a94ULL }, 1490 + { &fnv_test_str[153], (Fnv64_t) 0x6bd95b2eb37fa6b8ULL }, 1491 + { &fnv_test_str[154], (Fnv64_t) 0x74971b7077aef85dULL }, 1492 + { &fnv_test_str[155], (Fnv64_t) 0xb4e4fae2ffcc1aadULL }, 1493 + { &fnv_test_str[156], (Fnv64_t) 0x2bd48bd898b8f63aULL }, 1494 + { &fnv_test_str[157], (Fnv64_t) 0xe9966ac1556257f6ULL }, 1495 + { &fnv_test_str[158], (Fnv64_t) 0x92a3d1cd078ba293ULL }, 1496 + { &fnv_test_str[159], (Fnv64_t) 0xf81175a482e20ab8ULL }, 1497 + { &fnv_test_str[160], (Fnv64_t) 0x5bbb3de722e73048ULL }, 1498 + { &fnv_test_str[161], (Fnv64_t) 0x6b4f363492b9f2beULL }, 1499 + { &fnv_test_str[162], (Fnv64_t) 0xc2d559df73d59875ULL }, 1500 + { &fnv_test_str[163], (Fnv64_t) 0xf75f62284bc7a8c2ULL }, 1501 + { &fnv_test_str[164], (Fnv64_t) 0xda8dd8e116a9f1ccULL }, 1502 + { &fnv_test_str[165], (Fnv64_t) 0xbdc1e6ab76057885ULL }, 1503 + { &fnv_test_str[166], (Fnv64_t) 0xfec6a4238a1224a0ULL }, 1504 + { &fnv_test_str[167], (Fnv64_t) 0xc03f40f3223e290eULL }, 1505 + { &fnv_test_str[168], (Fnv64_t) 0x1ed21673466ffda9ULL }, 1506 + { &fnv_test_str[169], (Fnv64_t) 0xdf70f906bb0dd2afULL }, 1507 + { &fnv_test_str[170], (Fnv64_t) 0xf3dcda369f2af666ULL }, 1508 + { &fnv_test_str[171], (Fnv64_t) 0x9ebb11573cdcebdeULL }, 1509 + { &fnv_test_str[172], (Fnv64_t) 0x81c72d9077fedca0ULL }, 1510 + { &fnv_test_str[173], (Fnv64_t) 0x0ec074a31be5fb15ULL }, 1511 + { &fnv_test_str[174], (Fnv64_t) 0x2a8b3280b6c48f20ULL }, 1512 + { &fnv_test_str[175], (Fnv64_t) 0xfd31777513309344ULL }, 1513 + { &fnv_test_str[176], (Fnv64_t) 0x194534a86ad006b6ULL }, 1514 + { &fnv_test_str[177], (Fnv64_t) 0x3be6fdf46e0cfe12ULL }, 1515 + { &fnv_test_str[178], (Fnv64_t) 0x017cc137a07eb057ULL }, 1516 + { &fnv_test_str[179], (Fnv64_t) 0x9428fc6e7d26b54dULL }, 1517 + { &fnv_test_str[180], (Fnv64_t) 0x9aaa2e3603ef8ad7ULL }, 1518 + { &fnv_test_str[181], (Fnv64_t) 0x82c6d3f3a0ccdf7dULL }, 1519 + { &fnv_test_str[182], (Fnv64_t) 0xc86eeea00cf09b65ULL }, 1520 + { &fnv_test_str[183], (Fnv64_t) 0x705f8189dbb58299ULL }, 1521 + { &fnv_test_str[184], (Fnv64_t) 0x415a7f554391ca69ULL }, 1522 + { &fnv_test_str[185], (Fnv64_t) 0xcfe3d49fa2bdc555ULL }, 1523 + { &fnv_test_str[186], (Fnv64_t) 0xf0f9c56039b25191ULL }, 1524 + { &fnv_test_str[187], (Fnv64_t) 0x7075cb6abd1d32d9ULL }, 1525 + { &fnv_test_str[188], (Fnv64_t) 0x43c94e2c8b277509ULL }, 1526 + { &fnv_test_str[189], (Fnv64_t) 0x3cbfd4e4ea670359ULL }, 1527 + { &fnv_test_str[190], (Fnv64_t) 0xc05887810f4d019dULL }, 1528 + { &fnv_test_str[191], (Fnv64_t) 0x14468ff93ac22dc5ULL }, 1529 + { &fnv_test_str[192], (Fnv64_t) 0xebed699589d99c05ULL }, 1530 + { &fnv_test_str[193], (Fnv64_t) 0x6d99f6df321ca5d5ULL }, 1531 + { &fnv_test_str[194], (Fnv64_t) 0x0cd410d08c36d625ULL }, 1532 + { &fnv_test_str[195], (Fnv64_t) 0xef1b2a2c86831d35ULL }, 1533 + { &fnv_test_str[196], (Fnv64_t) 0x3b349c4d69ee5f05ULL }, 1534 + { &fnv_test_str[197], (Fnv64_t) 0x55248ce88f45f035ULL }, 1535 + { &fnv_test_str[198], (Fnv64_t) 0xaa69ca6a18a4c885ULL }, 1536 + { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL }, 1537 + { &fnv_test_str[200], (Fnv64_t) 0x0289a488a8df69d9ULL }, 1538 + { &fnv_test_str[201], (Fnv64_t) 0x15e96e1613df98b5ULL }, 1539 + { &fnv_test_str[202], (Fnv64_t) 0xe6be57375ad89b99ULL }, 1540 + { NULL, (Fnv64_t) 0 } 1541 + }; 1542 + #else /* HAVE_64BIT_LONG_LONG */ 1543 + struct fnv1_64_test_vector fnv1_64_vector[] = { 1544 + { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, 1545 + { &fnv_test_str[1], (Fnv64_t) {0x8601b7beUL, 0xaf63bd4cUL} }, 1546 + { &fnv_test_str[2], (Fnv64_t) {0x8601b7bdUL, 0xaf63bd4cUL} }, 1547 + { &fnv_test_str[3], (Fnv64_t) {0x8601b7bcUL, 0xaf63bd4cUL} }, 1548 + { &fnv_test_str[4], (Fnv64_t) {0x8601b7bbUL, 0xaf63bd4cUL} }, 1549 + { &fnv_test_str[5], (Fnv64_t) {0x8601b7baUL, 0xaf63bd4cUL} }, 1550 + { &fnv_test_str[6], (Fnv64_t) {0x8601b7b9UL, 0xaf63bd4cUL} }, 1551 + { &fnv_test_str[7], (Fnv64_t) {0xb4eb2f34UL, 0x08326207UL} }, 1552 + { &fnv_test_str[8], (Fnv64_t) {0x6ba13533UL, 0xd8cbc718UL} }, 1553 + { &fnv_test_str[9], (Fnv64_t) {0xe2ed65cbUL, 0x0378817eUL} }, 1554 + { &fnv_test_str[10], (Fnv64_t) {0x9963f790UL, 0xd329d59bUL} }, 1555 + { &fnv_test_str[11], (Fnv64_t) {0xa4dda9c2UL, 0x340d8765UL} }, 1556 + { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, 1557 + { &fnv_test_str[13], (Fnv64_t) {0xb4eb37daUL, 0x08326707UL} }, 1558 + { &fnv_test_str[14], (Fnv64_t) {0xb4eb3627UL, 0x08326607UL} }, 1559 + { &fnv_test_str[15], (Fnv64_t) {0xb4eb3474UL, 0x08326507UL} }, 1560 + { &fnv_test_str[16], (Fnv64_t) {0xb4eb32c1UL, 0x08326407UL} }, 1561 + { &fnv_test_str[17], (Fnv64_t) {0xb4eb310eUL, 0x08326307UL} }, 1562 + { &fnv_test_str[18], (Fnv64_t) {0xb4eb2f5bUL, 0x08326207UL} }, 1563 + { &fnv_test_str[19], (Fnv64_t) {0x6ba1355cUL, 0xd8cbc718UL} }, 1564 + { &fnv_test_str[20], (Fnv64_t) {0xe2ed65a9UL, 0x0378817eUL} }, 1565 + { &fnv_test_str[21], (Fnv64_t) {0x9963f7f1UL, 0xd329d59bUL} }, 1566 + { &fnv_test_str[22], (Fnv64_t) {0xa4dda9b0UL, 0x340d8765UL} }, 1567 + { &fnv_test_str[23], (Fnv64_t) {0x24a774a6UL, 0x50a6d3b7UL} }, 1568 + { &fnv_test_str[24], (Fnv64_t) {0xb4eb341cUL, 0x08326507UL} }, 1569 + { &fnv_test_str[25], (Fnv64_t) {0x6ba98bfbUL, 0xd8d5c818UL} }, 1570 + { &fnv_test_str[26], (Fnv64_t) {0xf118dbefUL, 0x1ccefc7eUL} }, 1571 + { &fnv_test_str[27], (Fnv64_t) {0xad3db77aUL, 0x0c92fab3UL} }, 1572 + { &fnv_test_str[28], (Fnv64_t) {0x5fdec421UL, 0x9b77794fUL} }, 1573 + { &fnv_test_str[29], (Fnv64_t) {0xe7874433UL, 0x0ac742dfUL} }, 1574 + { &fnv_test_str[30], (Fnv64_t) {0x6ad8e2deUL, 0xd7dad576UL} }, 1575 + { &fnv_test_str[31], (Fnv64_t) {0x8e897f5bUL, 0xa1bb9637UL} }, 1576 + { &fnv_test_str[32], (Fnv64_t) {0x33a367d2UL, 0x5b3f9b67UL} }, 1577 + { &fnv_test_str[33], (Fnv64_t) {0xbea969f6UL, 0xb07ce25cUL} }, 1578 + { &fnv_test_str[34], (Fnv64_t) {0xf9df0d6aUL, 0x8d9e9997UL} }, 1579 + { &fnv_test_str[35], (Fnv64_t) {0x9603cb7bUL, 0x838c673dUL} }, 1580 + { &fnv_test_str[36], (Fnv64_t) {0xe872c273UL, 0x8b5ee8a5UL} }, 1581 + { &fnv_test_str[37], (Fnv64_t) {0xfb00690cUL, 0x4507c4e9UL} }, 1582 + { &fnv_test_str[38], (Fnv64_t) {0x81b27f45UL, 0x4c9ca595UL} }, 1583 + { &fnv_test_str[39], (Fnv64_t) {0x624e4235UL, 0xe0aca20bUL} }, 1584 + { &fnv_test_str[40], (Fnv64_t) {0x6ba98b94UL, 0xd8d5c818UL} }, 1585 + { &fnv_test_str[41], (Fnv64_t) {0xf118db81UL, 0x1ccefc7eUL} }, 1586 + { &fnv_test_str[42], (Fnv64_t) {0xad3db71dUL, 0x0c92fab3UL} }, 1587 + { &fnv_test_str[43], (Fnv64_t) {0x5fdec44eUL, 0x9b77794fUL} }, 1588 + { &fnv_test_str[44], (Fnv64_t) {0xe7874413UL, 0x0ac742dfUL} }, 1589 + { &fnv_test_str[45], (Fnv64_t) {0x6ad8e2a9UL, 0xd7dad576UL} }, 1590 + { &fnv_test_str[46], (Fnv64_t) {0x8e897f3aUL, 0xa1bb9637UL} }, 1591 + { &fnv_test_str[47], (Fnv64_t) {0x33a367a1UL, 0x5b3f9b67UL} }, 1592 + { &fnv_test_str[48], (Fnv64_t) {0xbea969d6UL, 0xb07ce25cUL} }, 1593 + { &fnv_test_str[49], (Fnv64_t) {0xf9df0d02UL, 0x8d9e9997UL} }, 1594 + { &fnv_test_str[50], (Fnv64_t) {0x9603cb1eUL, 0x838c673dUL} }, 1595 + { &fnv_test_str[51], (Fnv64_t) {0xe872c201UL, 0x8b5ee8a5UL} }, 1596 + { &fnv_test_str[52], (Fnv64_t) {0xfb006969UL, 0x4507c4e9UL} }, 1597 + { &fnv_test_str[53], (Fnv64_t) {0x81b27f64UL, 0x4c9ca595UL} }, 1598 + { &fnv_test_str[54], (Fnv64_t) {0x624e423fUL, 0xe0aca20bUL} }, 1599 + { &fnv_test_str[55], (Fnv64_t) {0x0afa800fUL, 0x13998e58UL} }, 1600 + { &fnv_test_str[56], (Fnv64_t) {0xb4eb3401UL, 0x08326507UL} }, 1601 + { &fnv_test_str[57], (Fnv64_t) {0x6ba95dc1UL, 0xd8d5ad18UL} }, 1602 + { &fnv_test_str[58], (Fnv64_t) {0xf0ca4e97UL, 0x1c72e17eUL} }, 1603 + { &fnv_test_str[59], (Fnv64_t) {0x27c38ae6UL, 0x2183c1b3UL} }, 1604 + { &fnv_test_str[60], (Fnv64_t) {0x914504f2UL, 0xb66d096cUL} }, 1605 + { &fnv_test_str[61], (Fnv64_t) {0xd8476757UL, 0x404bf57aUL} }, 1606 + { &fnv_test_str[62], (Fnv64_t) {0x815498bbUL, 0x887976bdUL} }, 1607 + { &fnv_test_str[63], (Fnv64_t) {0xc2bf85a5UL, 0x3afd7f02UL} }, 1608 + { &fnv_test_str[64], (Fnv64_t) {0xeb70177fUL, 0xfc4476b0UL} }, 1609 + { &fnv_test_str[65], (Fnv64_t) {0x0f77ecbaUL, 0x186d2da0UL} }, 1610 + { &fnv_test_str[66], (Fnv64_t) {0x48c74066UL, 0xf97140faUL} }, 1611 + { &fnv_test_str[67], (Fnv64_t) {0xaa926d37UL, 0xa2b1cf49UL} }, 1612 + { &fnv_test_str[68], (Fnv64_t) {0xd6cf940cUL, 0x0690712cUL} }, 1613 + { &fnv_test_str[69], (Fnv64_t) {0x02b8906eUL, 0xf7045b31UL} }, 1614 + { &fnv_test_str[70], (Fnv64_t) {0x6ba95db3UL, 0xd8d5ad18UL} }, 1615 + { &fnv_test_str[71], (Fnv64_t) {0xf0ca4ef3UL, 0x1c72e17eUL} }, 1616 + { &fnv_test_str[72], (Fnv64_t) {0x27c38a95UL, 0x2183c1b3UL} }, 1617 + { &fnv_test_str[73], (Fnv64_t) {0x914504d2UL, 0xb66d096cUL} }, 1618 + { &fnv_test_str[74], (Fnv64_t) {0xd8476736UL, 0x404bf57aUL} }, 1619 + { &fnv_test_str[75], (Fnv64_t) {0x815498d5UL, 0x887976bdUL} }, 1620 + { &fnv_test_str[76], (Fnv64_t) {0xc2bf85c1UL, 0x3afd7f02UL} }, 1621 + { &fnv_test_str[77], (Fnv64_t) {0xeb70175fUL, 0xfc4476b0UL} }, 1622 + { &fnv_test_str[78], (Fnv64_t) {0x0f77eccdUL, 0x186d2da0UL} }, 1623 + { &fnv_test_str[79], (Fnv64_t) {0x48c7400eUL, 0xf97140faUL} }, 1624 + { &fnv_test_str[80], (Fnv64_t) {0xaa926d52UL, 0xa2b1cf49UL} }, 1625 + { &fnv_test_str[81], (Fnv64_t) {0xd6cf9475UL, 0x0690712cUL} }, 1626 + { &fnv_test_str[82], (Fnv64_t) {0x02b89064UL, 0xf7045b31UL} }, 1627 + { &fnv_test_str[83], (Fnv64_t) {0x9f9d6aeaUL, 0x74f76247UL} }, 1628 + { &fnv_test_str[84], (Fnv64_t) {0xb4eb2b9cUL, 0x08326007UL} }, 1629 + { &fnv_test_str[85], (Fnv64_t) {0x6b9b1a14UL, 0xd8c4c918UL} }, 1630 + { &fnv_test_str[86], (Fnv64_t) {0xbdbdd4c7UL, 0x7b495389UL} }, 1631 + { &fnv_test_str[87], (Fnv64_t) {0x69908e25UL, 0x3b6dba0dUL} }, 1632 + { &fnv_test_str[88], (Fnv64_t) {0xf4b71261UL, 0xd6b2b17bUL} }, 1633 + { &fnv_test_str[89], (Fnv64_t) {0x98e615b5UL, 0x447bfb7fUL} }, 1634 + { &fnv_test_str[90], (Fnv64_t) {0xf4b71262UL, 0xd6b2b17bUL} }, 1635 + { &fnv_test_str[91], (Fnv64_t) {0x93fe1660UL, 0x3bd2807fUL} }, 1636 + { &fnv_test_str[92], (Fnv64_t) {0xf4b71263UL, 0xd6b2b17bUL} }, 1637 + { &fnv_test_str[93], (Fnv64_t) {0x8f16170bUL, 0x3329057fUL} }, 1638 + { &fnv_test_str[94], (Fnv64_t) {0xf4b71264UL, 0xd6b2b17bUL} }, 1639 + { &fnv_test_str[95], (Fnv64_t) {0x8a2e19b6UL, 0x2a7f8a7fUL} }, 1640 + { &fnv_test_str[96], (Fnv64_t) {0x64b2f98aUL, 0x23d3767eUL} }, 1641 + { &fnv_test_str[97], (Fnv64_t) {0x4f9d86a4UL, 0xff768d7eUL} }, 1642 + { &fnv_test_str[98], (Fnv64_t) {0x64b2f984UL, 0x23d3767eUL} }, 1643 + { &fnv_test_str[99], (Fnv64_t) {0x334e4aa6UL, 0xccd1837eUL} }, 1644 + { &fnv_test_str[100], (Fnv64_t) {0x64b2f99aUL, 0x23d3767eUL} }, 1645 + { &fnv_test_str[101], (Fnv64_t) {0x028f6754UL, 0x7691fd7eUL} }, 1646 + { &fnv_test_str[102], (Fnv64_t) {0x41204318UL, 0x34ad3b10UL} }, 1647 + { &fnv_test_str[103], (Fnv64_t) {0xa9d201c8UL, 0xa29e749eUL} }, 1648 + { &fnv_test_str[104], (Fnv64_t) {0x4120431bUL, 0x34ad3b10UL} }, 1649 + { &fnv_test_str[105], (Fnv64_t) {0xa9d206e1UL, 0xa29e779eUL} }, 1650 + { &fnv_test_str[106], (Fnv64_t) {0x4120431aUL, 0x34ad3b10UL} }, 1651 + { &fnv_test_str[107], (Fnv64_t) {0xa9d2052eUL, 0xa29e769eUL} }, 1652 + { &fnv_test_str[108], (Fnv64_t) {0xa4aa3497UL, 0x02a17ebcUL} }, 1653 + { &fnv_test_str[109], (Fnv64_t) {0xcd375c95UL, 0x229ef18bUL} }, 1654 + { &fnv_test_str[110], (Fnv64_t) {0xa4aa32c8UL, 0x02a17dbcUL} }, 1655 + { &fnv_test_str[111], (Fnv64_t) {0xcd3449d8UL, 0x229b6f8bUL} }, 1656 + { &fnv_test_str[112], (Fnv64_t) {0xa4aa3ed5UL, 0x02a184bcUL} }, 1657 + { &fnv_test_str[113], (Fnv64_t) {0xcd48c3efUL, 0x22b3618bUL} }, 1658 + { &fnv_test_str[114], (Fnv64_t) {0x06186f36UL, 0x5c2c3467UL} }, 1659 + { &fnv_test_str[115], (Fnv64_t) {0x5b84f8c2UL, 0xb78c410fUL} }, 1660 + { &fnv_test_str[116], (Fnv64_t) {0x2b267395UL, 0xed947821UL} }, 1661 + { &fnv_test_str[117], (Fnv64_t) {0x5256662fUL, 0xd9bbb55cUL} }, 1662 + { &fnv_test_str[118], (Fnv64_t) {0x3249438aUL, 0x8c54f020UL} }, 1663 + { &fnv_test_str[119], (Fnv64_t) {0x727dc37eUL, 0xbd9790b5UL} }, 1664 + { &fnv_test_str[120], (Fnv64_t) {0xc9e2b0e3UL, 0xa64e5f36UL} }, 1665 + { &fnv_test_str[121], (Fnv64_t) {0xa3088a04UL, 0x8fd0680dUL} }, 1666 + { &fnv_test_str[122], (Fnv64_t) {0x078284ccUL, 0x67aad32cUL} }, 1667 + { &fnv_test_str[123], (Fnv64_t) {0x1c57b331UL, 0xb37d55d8UL} }, 1668 + { &fnv_test_str[124], (Fnv64_t) {0x29057c43UL, 0x55ac0f38UL} }, 1669 + { &fnv_test_str[125], (Fnv64_t) {0xe1b6cc20UL, 0xcb27f4b8UL} }, 1670 + { &fnv_test_str[126], (Fnv64_t) {0xcbef2d19UL, 0x26caf88bUL} }, 1671 + { &fnv_test_str[127], (Fnv64_t) {0x97e61b8fUL, 0x8e6e063bUL} }, 1672 + { &fnv_test_str[128], (Fnv64_t) {0xf3b7c37eUL, 0xb42750f7UL} }, 1673 + { &fnv_test_str[129], (Fnv64_t) {0xcf7ca99bUL, 0xf3c6ba64UL} }, 1674 + { &fnv_test_str[130], (Fnv64_t) {0x27ea80feUL, 0xebfb69b4UL} }, 1675 + { &fnv_test_str[131], (Fnv64_t) {0xd970f46cUL, 0x39b50c3eUL} }, 1676 + { &fnv_test_str[132], (Fnv64_t) {0xa3eb3e8aUL, 0x5b9b177aUL} }, 1677 + { &fnv_test_str[133], (Fnv64_t) {0xcf4ec903UL, 0x6510063eUL} }, 1678 + { &fnv_test_str[134], (Fnv64_t) {0x00797c7aUL, 0x2b3bbd2cUL} }, 1679 + { &fnv_test_str[135], (Fnv64_t) {0xf5cb4aa7UL, 0xf1d6204fUL} }, 1680 + { &fnv_test_str[136], (Fnv64_t) {0xcf099f38UL, 0x4836e27cUL} }, 1681 + { &fnv_test_str[137], (Fnv64_t) {0xd073b44dUL, 0x82efbb0dUL} }, 1682 + { &fnv_test_str[138], (Fnv64_t) {0xffd7d4c6UL, 0x4a80c282UL} }, 1683 + { &fnv_test_str[139], (Fnv64_t) {0x9ee43bdfUL, 0x305d1a9cUL} }, 1684 + { &fnv_test_str[140], (Fnv64_t) {0x8ffc6997UL, 0x15c36694UL} }, 1685 + { &fnv_test_str[141], (Fnv64_t) {0x18916e7bUL, 0x80153ae2UL} }, 1686 + { &fnv_test_str[142], (Fnv64_t) {0xf9e2a9e1UL, 0xfa23e2bdUL} }, 1687 + { &fnv_test_str[143], (Fnv64_t) {0x2333c6deUL, 0xd47e8d8aUL} }, 1688 + { &fnv_test_str[144], (Fnv64_t) {0xf688b056UL, 0x7e128095UL} }, 1689 + { &fnv_test_str[145], (Fnv64_t) {0x0efcedabUL, 0x2f535689UL} }, 1690 + { &fnv_test_str[146], (Fnv64_t) {0x014f55c5UL, 0x95c2b383UL} }, 1691 + { &fnv_test_str[147], (Fnv64_t) {0x9ce6070fUL, 0x4727a533UL} }, 1692 + { &fnv_test_str[148], (Fnv64_t) {0x575108e9UL, 0xb0555ecdUL} }, 1693 + { &fnv_test_str[149], (Fnv64_t) {0x0bb4af37UL, 0x48d78577UL} }, 1694 + { &fnv_test_str[150], (Fnv64_t) {0x12af02b1UL, 0x09d4701cUL} }, 1695 + { &fnv_test_str[151], (Fnv64_t) {0x8f3cf62eUL, 0x79f031e7UL} }, 1696 + { &fnv_test_str[152], (Fnv64_t) {0xdb1b5a94UL, 0x52a1ee85UL} }, 1697 + { &fnv_test_str[153], (Fnv64_t) {0xb37fa6b8UL, 0x6bd95b2eUL} }, 1698 + { &fnv_test_str[154], (Fnv64_t) {0x77aef85dUL, 0x74971b70UL} }, 1699 + { &fnv_test_str[155], (Fnv64_t) {0xffcc1aadUL, 0xb4e4fae2UL} }, 1700 + { &fnv_test_str[156], (Fnv64_t) {0x98b8f63aUL, 0x2bd48bd8UL} }, 1701 + { &fnv_test_str[157], (Fnv64_t) {0x556257f6UL, 0xe9966ac1UL} }, 1702 + { &fnv_test_str[158], (Fnv64_t) {0x078ba293UL, 0x92a3d1cdUL} }, 1703 + { &fnv_test_str[159], (Fnv64_t) {0x82e20ab8UL, 0xf81175a4UL} }, 1704 + { &fnv_test_str[160], (Fnv64_t) {0x22e73048UL, 0x5bbb3de7UL} }, 1705 + { &fnv_test_str[161], (Fnv64_t) {0x92b9f2beUL, 0x6b4f3634UL} }, 1706 + { &fnv_test_str[162], (Fnv64_t) {0x73d59875UL, 0xc2d559dfUL} }, 1707 + { &fnv_test_str[163], (Fnv64_t) {0x4bc7a8c2UL, 0xf75f6228UL} }, 1708 + { &fnv_test_str[164], (Fnv64_t) {0x16a9f1ccUL, 0xda8dd8e1UL} }, 1709 + { &fnv_test_str[165], (Fnv64_t) {0x76057885UL, 0xbdc1e6abUL} }, 1710 + { &fnv_test_str[166], (Fnv64_t) {0x8a1224a0UL, 0xfec6a423UL} }, 1711 + { &fnv_test_str[167], (Fnv64_t) {0x223e290eUL, 0xc03f40f3UL} }, 1712 + { &fnv_test_str[168], (Fnv64_t) {0x466ffda9UL, 0x1ed21673UL} }, 1713 + { &fnv_test_str[169], (Fnv64_t) {0xbb0dd2afUL, 0xdf70f906UL} }, 1714 + { &fnv_test_str[170], (Fnv64_t) {0x9f2af666UL, 0xf3dcda36UL} }, 1715 + { &fnv_test_str[171], (Fnv64_t) {0x3cdcebdeUL, 0x9ebb1157UL} }, 1716 + { &fnv_test_str[172], (Fnv64_t) {0x77fedca0UL, 0x81c72d90UL} }, 1717 + { &fnv_test_str[173], (Fnv64_t) {0x1be5fb15UL, 0x0ec074a3UL} }, 1718 + { &fnv_test_str[174], (Fnv64_t) {0xb6c48f20UL, 0x2a8b3280UL} }, 1719 + { &fnv_test_str[175], (Fnv64_t) {0x13309344UL, 0xfd317775UL} }, 1720 + { &fnv_test_str[176], (Fnv64_t) {0x6ad006b6UL, 0x194534a8UL} }, 1721 + { &fnv_test_str[177], (Fnv64_t) {0x6e0cfe12UL, 0x3be6fdf4UL} }, 1722 + { &fnv_test_str[178], (Fnv64_t) {0xa07eb057UL, 0x017cc137UL} }, 1723 + { &fnv_test_str[179], (Fnv64_t) {0x7d26b54dUL, 0x9428fc6eUL} }, 1724 + { &fnv_test_str[180], (Fnv64_t) {0x03ef8ad7UL, 0x9aaa2e36UL} }, 1725 + { &fnv_test_str[181], (Fnv64_t) {0xa0ccdf7dUL, 0x82c6d3f3UL} }, 1726 + { &fnv_test_str[182], (Fnv64_t) {0x0cf09b65UL, 0xc86eeea0UL} }, 1727 + { &fnv_test_str[183], (Fnv64_t) {0xdbb58299UL, 0x705f8189UL} }, 1728 + { &fnv_test_str[184], (Fnv64_t) {0x4391ca69UL, 0x415a7f55UL} }, 1729 + { &fnv_test_str[185], (Fnv64_t) {0xa2bdc555UL, 0xcfe3d49fUL} }, 1730 + { &fnv_test_str[186], (Fnv64_t) {0x39b25191UL, 0xf0f9c560UL} }, 1731 + { &fnv_test_str[187], (Fnv64_t) {0xbd1d32d9UL, 0x7075cb6aUL} }, 1732 + { &fnv_test_str[188], (Fnv64_t) {0x8b277509UL, 0x43c94e2cUL} }, 1733 + { &fnv_test_str[189], (Fnv64_t) {0xea670359UL, 0x3cbfd4e4UL} }, 1734 + { &fnv_test_str[190], (Fnv64_t) {0x0f4d019dUL, 0xc0588781UL} }, 1735 + { &fnv_test_str[191], (Fnv64_t) {0x3ac22dc5UL, 0x14468ff9UL} }, 1736 + { &fnv_test_str[192], (Fnv64_t) {0x89d99c05UL, 0xebed6995UL} }, 1737 + { &fnv_test_str[193], (Fnv64_t) {0x321ca5d5UL, 0x6d99f6dfUL} }, 1738 + { &fnv_test_str[194], (Fnv64_t) {0x8c36d625UL, 0x0cd410d0UL} }, 1739 + { &fnv_test_str[195], (Fnv64_t) {0x86831d35UL, 0xef1b2a2cUL} }, 1740 + { &fnv_test_str[196], (Fnv64_t) {0x69ee5f05UL, 0x3b349c4dUL} }, 1741 + { &fnv_test_str[197], (Fnv64_t) {0x8f45f035UL, 0x55248ce8UL} }, 1742 + { &fnv_test_str[198], (Fnv64_t) {0x18a4c885UL, 0xaa69ca6aUL} }, 1743 + { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} }, 1744 + { &fnv_test_str[200], (Fnv64_t) {0xa8df69d9UL, 0x0289a488UL} }, 1745 + { &fnv_test_str[201], (Fnv64_t) {0x13df98b5UL, 0x15e96e16UL} }, 1746 + { &fnv_test_str[202], (Fnv64_t) {0x5ad89b99UL, 0xe6be5737UL} }, 1747 + { NULL, (Fnv64_t) {0,0} } 1748 + }; 1749 + #endif /* HAVE_64BIT_LONG_LONG */ 1750 + 1751 + /* FNV-1a 64 bit test vectors */ 1752 + #if defined(HAVE_64BIT_LONG_LONG) 1753 + struct fnv1a_64_test_vector fnv1a_64_vector[] = { 1754 + { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL }, 1755 + { &fnv_test_str[1], (Fnv64_t) 0xaf63dc4c8601ec8cULL }, 1756 + { &fnv_test_str[2], (Fnv64_t) 0xaf63df4c8601f1a5ULL }, 1757 + { &fnv_test_str[3], (Fnv64_t) 0xaf63de4c8601eff2ULL }, 1758 + { &fnv_test_str[4], (Fnv64_t) 0xaf63d94c8601e773ULL }, 1759 + { &fnv_test_str[5], (Fnv64_t) 0xaf63d84c8601e5c0ULL }, 1760 + { &fnv_test_str[6], (Fnv64_t) 0xaf63db4c8601ead9ULL }, 1761 + { &fnv_test_str[7], (Fnv64_t) 0x08985907b541d342ULL }, 1762 + { &fnv_test_str[8], (Fnv64_t) 0xdcb27518fed9d577ULL }, 1763 + { &fnv_test_str[9], (Fnv64_t) 0xdd120e790c2512afULL }, 1764 + { &fnv_test_str[10], (Fnv64_t) 0xcac165afa2fef40aULL }, 1765 + { &fnv_test_str[11], (Fnv64_t) 0x85944171f73967e8ULL }, 1766 + { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, 1767 + { &fnv_test_str[13], (Fnv64_t) 0x089be207b544f1e4ULL }, 1768 + { &fnv_test_str[14], (Fnv64_t) 0x08a61407b54d9b5fULL }, 1769 + { &fnv_test_str[15], (Fnv64_t) 0x08a2ae07b54ab836ULL }, 1770 + { &fnv_test_str[16], (Fnv64_t) 0x0891b007b53c4869ULL }, 1771 + { &fnv_test_str[17], (Fnv64_t) 0x088e4a07b5396540ULL }, 1772 + { &fnv_test_str[18], (Fnv64_t) 0x08987c07b5420ebbULL }, 1773 + { &fnv_test_str[19], (Fnv64_t) 0xdcb28a18fed9f926ULL }, 1774 + { &fnv_test_str[20], (Fnv64_t) 0xdd1270790c25b935ULL }, 1775 + { &fnv_test_str[21], (Fnv64_t) 0xcac146afa2febf5dULL }, 1776 + { &fnv_test_str[22], (Fnv64_t) 0x8593d371f738acfeULL }, 1777 + { &fnv_test_str[23], (Fnv64_t) 0x34531ca7168b8f38ULL }, 1778 + { &fnv_test_str[24], (Fnv64_t) 0x08a25607b54a22aeULL }, 1779 + { &fnv_test_str[25], (Fnv64_t) 0xf5faf0190cf90df3ULL }, 1780 + { &fnv_test_str[26], (Fnv64_t) 0xf27397910b3221c7ULL }, 1781 + { &fnv_test_str[27], (Fnv64_t) 0x2c8c2b76062f22e0ULL }, 1782 + { &fnv_test_str[28], (Fnv64_t) 0xe150688c8217b8fdULL }, 1783 + { &fnv_test_str[29], (Fnv64_t) 0xf35a83c10e4f1f87ULL }, 1784 + { &fnv_test_str[30], (Fnv64_t) 0xd1edd10b507344d0ULL }, 1785 + { &fnv_test_str[31], (Fnv64_t) 0x2a5ee739b3ddb8c3ULL }, 1786 + { &fnv_test_str[32], (Fnv64_t) 0xdcfb970ca1c0d310ULL }, 1787 + { &fnv_test_str[33], (Fnv64_t) 0x4054da76daa6da90ULL }, 1788 + { &fnv_test_str[34], (Fnv64_t) 0xf70a2ff589861368ULL }, 1789 + { &fnv_test_str[35], (Fnv64_t) 0x4c628b38aed25f17ULL }, 1790 + { &fnv_test_str[36], (Fnv64_t) 0x9dd1f6510f78189fULL }, 1791 + { &fnv_test_str[37], (Fnv64_t) 0xa3de85bd491270ceULL }, 1792 + { &fnv_test_str[38], (Fnv64_t) 0x858e2fa32a55e61dULL }, 1793 + { &fnv_test_str[39], (Fnv64_t) 0x46810940eff5f915ULL }, 1794 + { &fnv_test_str[40], (Fnv64_t) 0xf5fadd190cf8edaaULL }, 1795 + { &fnv_test_str[41], (Fnv64_t) 0xf273ed910b32b3e9ULL }, 1796 + { &fnv_test_str[42], (Fnv64_t) 0x2c8c5276062f6525ULL }, 1797 + { &fnv_test_str[43], (Fnv64_t) 0xe150b98c821842a0ULL }, 1798 + { &fnv_test_str[44], (Fnv64_t) 0xf35aa3c10e4f55e7ULL }, 1799 + { &fnv_test_str[45], (Fnv64_t) 0xd1ed680b50729265ULL }, 1800 + { &fnv_test_str[46], (Fnv64_t) 0x2a5f0639b3dded70ULL }, 1801 + { &fnv_test_str[47], (Fnv64_t) 0xdcfbaa0ca1c0f359ULL }, 1802 + { &fnv_test_str[48], (Fnv64_t) 0x4054ba76daa6a430ULL }, 1803 + { &fnv_test_str[49], (Fnv64_t) 0xf709c7f5898562b0ULL }, 1804 + { &fnv_test_str[50], (Fnv64_t) 0x4c62e638aed2f9b8ULL }, 1805 + { &fnv_test_str[51], (Fnv64_t) 0x9dd1a8510f779415ULL }, 1806 + { &fnv_test_str[52], (Fnv64_t) 0xa3de2abd4911d62dULL }, 1807 + { &fnv_test_str[53], (Fnv64_t) 0x858e0ea32a55ae0aULL }, 1808 + { &fnv_test_str[54], (Fnv64_t) 0x46810f40eff60347ULL }, 1809 + { &fnv_test_str[55], (Fnv64_t) 0xc33bce57bef63eafULL }, 1810 + { &fnv_test_str[56], (Fnv64_t) 0x08a24307b54a0265ULL }, 1811 + { &fnv_test_str[57], (Fnv64_t) 0xf5b9fd190cc18d15ULL }, 1812 + { &fnv_test_str[58], (Fnv64_t) 0x4c968290ace35703ULL }, 1813 + { &fnv_test_str[59], (Fnv64_t) 0x07174bd5c64d9350ULL }, 1814 + { &fnv_test_str[60], (Fnv64_t) 0x5a294c3ff5d18750ULL }, 1815 + { &fnv_test_str[61], (Fnv64_t) 0x05b3c1aeb308b843ULL }, 1816 + { &fnv_test_str[62], (Fnv64_t) 0xb92a48da37d0f477ULL }, 1817 + { &fnv_test_str[63], (Fnv64_t) 0x73cdddccd80ebc49ULL }, 1818 + { &fnv_test_str[64], (Fnv64_t) 0xd58c4c13210a266bULL }, 1819 + { &fnv_test_str[65], (Fnv64_t) 0xe78b6081243ec194ULL }, 1820 + { &fnv_test_str[66], (Fnv64_t) 0xb096f77096a39f34ULL }, 1821 + { &fnv_test_str[67], (Fnv64_t) 0xb425c54ff807b6a3ULL }, 1822 + { &fnv_test_str[68], (Fnv64_t) 0x23e520e2751bb46eULL }, 1823 + { &fnv_test_str[69], (Fnv64_t) 0x1a0b44ccfe1385ecULL }, 1824 + { &fnv_test_str[70], (Fnv64_t) 0xf5ba4b190cc2119fULL }, 1825 + { &fnv_test_str[71], (Fnv64_t) 0x4c962690ace2baafULL }, 1826 + { &fnv_test_str[72], (Fnv64_t) 0x0716ded5c64cda19ULL }, 1827 + { &fnv_test_str[73], (Fnv64_t) 0x5a292c3ff5d150f0ULL }, 1828 + { &fnv_test_str[74], (Fnv64_t) 0x05b3e0aeb308ecf0ULL }, 1829 + { &fnv_test_str[75], (Fnv64_t) 0xb92a5eda37d119d9ULL }, 1830 + { &fnv_test_str[76], (Fnv64_t) 0x73ce41ccd80f6635ULL }, 1831 + { &fnv_test_str[77], (Fnv64_t) 0xd58c2c132109f00bULL }, 1832 + { &fnv_test_str[78], (Fnv64_t) 0xe78baf81243f47d1ULL }, 1833 + { &fnv_test_str[79], (Fnv64_t) 0xb0968f7096a2ee7cULL }, 1834 + { &fnv_test_str[80], (Fnv64_t) 0xb425a84ff807855cULL }, 1835 + { &fnv_test_str[81], (Fnv64_t) 0x23e4e9e2751b56f9ULL }, 1836 + { &fnv_test_str[82], (Fnv64_t) 0x1a0b4eccfe1396eaULL }, 1837 + { &fnv_test_str[83], (Fnv64_t) 0x54abd453bb2c9004ULL }, 1838 + { &fnv_test_str[84], (Fnv64_t) 0x08ba5f07b55ec3daULL }, 1839 + { &fnv_test_str[85], (Fnv64_t) 0x337354193006cb6eULL }, 1840 + { &fnv_test_str[86], (Fnv64_t) 0xa430d84680aabd0bULL }, 1841 + { &fnv_test_str[87], (Fnv64_t) 0xa9bc8acca21f39b1ULL }, 1842 + { &fnv_test_str[88], (Fnv64_t) 0x6961196491cc682dULL }, 1843 + { &fnv_test_str[89], (Fnv64_t) 0xad2bb1774799dfe9ULL }, 1844 + { &fnv_test_str[90], (Fnv64_t) 0x6961166491cc6314ULL }, 1845 + { &fnv_test_str[91], (Fnv64_t) 0x8d1bb3904a3b1236ULL }, 1846 + { &fnv_test_str[92], (Fnv64_t) 0x6961176491cc64c7ULL }, 1847 + { &fnv_test_str[93], (Fnv64_t) 0xed205d87f40434c7ULL }, 1848 + { &fnv_test_str[94], (Fnv64_t) 0x6961146491cc5faeULL }, 1849 + { &fnv_test_str[95], (Fnv64_t) 0xcd3baf5e44f8ad9cULL }, 1850 + { &fnv_test_str[96], (Fnv64_t) 0xe3b36596127cd6d8ULL }, 1851 + { &fnv_test_str[97], (Fnv64_t) 0xf77f1072c8e8a646ULL }, 1852 + { &fnv_test_str[98], (Fnv64_t) 0xe3b36396127cd372ULL }, 1853 + { &fnv_test_str[99], (Fnv64_t) 0x6067dce9932ad458ULL }, 1854 + { &fnv_test_str[100], (Fnv64_t) 0xe3b37596127cf208ULL }, 1855 + { &fnv_test_str[101], (Fnv64_t) 0x4b7b10fa9fe83936ULL }, 1856 + { &fnv_test_str[102], (Fnv64_t) 0xaabafe7104d914beULL }, 1857 + { &fnv_test_str[103], (Fnv64_t) 0xf4d3180b3cde3edaULL }, 1858 + { &fnv_test_str[104], (Fnv64_t) 0xaabafd7104d9130bULL }, 1859 + { &fnv_test_str[105], (Fnv64_t) 0xf4cfb20b3cdb5bb1ULL }, 1860 + { &fnv_test_str[106], (Fnv64_t) 0xaabafc7104d91158ULL }, 1861 + { &fnv_test_str[107], (Fnv64_t) 0xf4cc4c0b3cd87888ULL }, 1862 + { &fnv_test_str[108], (Fnv64_t) 0xe729bac5d2a8d3a7ULL }, 1863 + { &fnv_test_str[109], (Fnv64_t) 0x74bc0524f4dfa4c5ULL }, 1864 + { &fnv_test_str[110], (Fnv64_t) 0xe72630c5d2a5b352ULL }, 1865 + { &fnv_test_str[111], (Fnv64_t) 0x6b983224ef8fb456ULL }, 1866 + { &fnv_test_str[112], (Fnv64_t) 0xe73042c5d2ae266dULL }, 1867 + { &fnv_test_str[113], (Fnv64_t) 0x8527e324fdeb4b37ULL }, 1868 + { &fnv_test_str[114], (Fnv64_t) 0x0a83c86fee952abcULL }, 1869 + { &fnv_test_str[115], (Fnv64_t) 0x7318523267779d74ULL }, 1870 + { &fnv_test_str[116], (Fnv64_t) 0x3e66d3d56b8caca1ULL }, 1871 + { &fnv_test_str[117], (Fnv64_t) 0x956694a5c0095593ULL }, 1872 + { &fnv_test_str[118], (Fnv64_t) 0xcac54572bb1a6fc8ULL }, 1873 + { &fnv_test_str[119], (Fnv64_t) 0xa7a4c9f3edebf0d8ULL }, 1874 + { &fnv_test_str[120], (Fnv64_t) 0x7829851fac17b143ULL }, 1875 + { &fnv_test_str[121], (Fnv64_t) 0x2c8f4c9af81bcf06ULL }, 1876 + { &fnv_test_str[122], (Fnv64_t) 0xd34e31539740c732ULL }, 1877 + { &fnv_test_str[123], (Fnv64_t) 0x3605a2ac253d2db1ULL }, 1878 + { &fnv_test_str[124], (Fnv64_t) 0x08c11b8346f4a3c3ULL }, 1879 + { &fnv_test_str[125], (Fnv64_t) 0x6be396289ce8a6daULL }, 1880 + { &fnv_test_str[126], (Fnv64_t) 0xd9b957fb7fe794c5ULL }, 1881 + { &fnv_test_str[127], (Fnv64_t) 0x05be33da04560a93ULL }, 1882 + { &fnv_test_str[128], (Fnv64_t) 0x0957f1577ba9747cULL }, 1883 + { &fnv_test_str[129], (Fnv64_t) 0xda2cc3acc24fba57ULL }, 1884 + { &fnv_test_str[130], (Fnv64_t) 0x74136f185b29e7f0ULL }, 1885 + { &fnv_test_str[131], (Fnv64_t) 0xb2f2b4590edb93b2ULL }, 1886 + { &fnv_test_str[132], (Fnv64_t) 0xb3608fce8b86ae04ULL }, 1887 + { &fnv_test_str[133], (Fnv64_t) 0x4a3a865079359063ULL }, 1888 + { &fnv_test_str[134], (Fnv64_t) 0x5b3a7ef496880a50ULL }, 1889 + { &fnv_test_str[135], (Fnv64_t) 0x48fae3163854c23bULL }, 1890 + { &fnv_test_str[136], (Fnv64_t) 0x07aaa640476e0b9aULL }, 1891 + { &fnv_test_str[137], (Fnv64_t) 0x2f653656383a687dULL }, 1892 + { &fnv_test_str[138], (Fnv64_t) 0xa1031f8e7599d79cULL }, 1893 + { &fnv_test_str[139], (Fnv64_t) 0xa31908178ff92477ULL }, 1894 + { &fnv_test_str[140], (Fnv64_t) 0x097edf3c14c3fb83ULL }, 1895 + { &fnv_test_str[141], (Fnv64_t) 0xb51ca83feaa0971bULL }, 1896 + { &fnv_test_str[142], (Fnv64_t) 0xdd3c0d96d784f2e9ULL }, 1897 + { &fnv_test_str[143], (Fnv64_t) 0x86cd26a9ea767d78ULL }, 1898 + { &fnv_test_str[144], (Fnv64_t) 0xe6b215ff54a30c18ULL }, 1899 + { &fnv_test_str[145], (Fnv64_t) 0xec5b06a1c5531093ULL }, 1900 + { &fnv_test_str[146], (Fnv64_t) 0x45665a929f9ec5e5ULL }, 1901 + { &fnv_test_str[147], (Fnv64_t) 0x8c7609b4a9f10907ULL }, 1902 + { &fnv_test_str[148], (Fnv64_t) 0x89aac3a491f0d729ULL }, 1903 + { &fnv_test_str[149], (Fnv64_t) 0x32ce6b26e0f4a403ULL }, 1904 + { &fnv_test_str[150], (Fnv64_t) 0x614ab44e02b53e01ULL }, 1905 + { &fnv_test_str[151], (Fnv64_t) 0xfa6472eb6eef3290ULL }, 1906 + { &fnv_test_str[152], (Fnv64_t) 0x9e5d75eb1948eb6aULL }, 1907 + { &fnv_test_str[153], (Fnv64_t) 0xb6d12ad4a8671852ULL }, 1908 + { &fnv_test_str[154], (Fnv64_t) 0x88826f56eba07af1ULL }, 1909 + { &fnv_test_str[155], (Fnv64_t) 0x44535bf2645bc0fdULL }, 1910 + { &fnv_test_str[156], (Fnv64_t) 0x169388ffc21e3728ULL }, 1911 + { &fnv_test_str[157], (Fnv64_t) 0xf68aac9e396d8224ULL }, 1912 + { &fnv_test_str[158], (Fnv64_t) 0x8e87d7e7472b3883ULL }, 1913 + { &fnv_test_str[159], (Fnv64_t) 0x295c26caa8b423deULL }, 1914 + { &fnv_test_str[160], (Fnv64_t) 0x322c814292e72176ULL }, 1915 + { &fnv_test_str[161], (Fnv64_t) 0x8a06550eb8af7268ULL }, 1916 + { &fnv_test_str[162], (Fnv64_t) 0xef86d60e661bcf71ULL }, 1917 + { &fnv_test_str[163], (Fnv64_t) 0x9e5426c87f30ee54ULL }, 1918 + { &fnv_test_str[164], (Fnv64_t) 0xf1ea8aa826fd047eULL }, 1919 + { &fnv_test_str[165], (Fnv64_t) 0x0babaf9a642cb769ULL }, 1920 + { &fnv_test_str[166], (Fnv64_t) 0x4b3341d4068d012eULL }, 1921 + { &fnv_test_str[167], (Fnv64_t) 0xd15605cbc30a335cULL }, 1922 + { &fnv_test_str[168], (Fnv64_t) 0x5b21060aed8412e5ULL }, 1923 + { &fnv_test_str[169], (Fnv64_t) 0x45e2cda1ce6f4227ULL }, 1924 + { &fnv_test_str[170], (Fnv64_t) 0x50ae3745033ad7d4ULL }, 1925 + { &fnv_test_str[171], (Fnv64_t) 0xaa4588ced46bf414ULL }, 1926 + { &fnv_test_str[172], (Fnv64_t) 0xc1b0056c4a95467eULL }, 1927 + { &fnv_test_str[173], (Fnv64_t) 0x56576a71de8b4089ULL }, 1928 + { &fnv_test_str[174], (Fnv64_t) 0xbf20965fa6dc927eULL }, 1929 + { &fnv_test_str[175], (Fnv64_t) 0x569f8383c2040882ULL }, 1930 + { &fnv_test_str[176], (Fnv64_t) 0xe1e772fba08feca0ULL }, 1931 + { &fnv_test_str[177], (Fnv64_t) 0x4ced94af97138ac4ULL }, 1932 + { &fnv_test_str[178], (Fnv64_t) 0xc4112ffb337a82fbULL }, 1933 + { &fnv_test_str[179], (Fnv64_t) 0xd64a4fd41de38b7dULL }, 1934 + { &fnv_test_str[180], (Fnv64_t) 0x4cfc32329edebcbbULL }, 1935 + { &fnv_test_str[181], (Fnv64_t) 0x0803564445050395ULL }, 1936 + { &fnv_test_str[182], (Fnv64_t) 0xaa1574ecf4642ffdULL }, 1937 + { &fnv_test_str[183], (Fnv64_t) 0x694bc4e54cc315f9ULL }, 1938 + { &fnv_test_str[184], (Fnv64_t) 0xa3d7cb273b011721ULL }, 1939 + { &fnv_test_str[185], (Fnv64_t) 0x577c2f8b6115bfa5ULL }, 1940 + { &fnv_test_str[186], (Fnv64_t) 0xb7ec8c1a769fb4c1ULL }, 1941 + { &fnv_test_str[187], (Fnv64_t) 0x5d5cfce63359ab19ULL }, 1942 + { &fnv_test_str[188], (Fnv64_t) 0x33b96c3cd65b5f71ULL }, 1943 + { &fnv_test_str[189], (Fnv64_t) 0xd845097780602bb9ULL }, 1944 + { &fnv_test_str[190], (Fnv64_t) 0x84d47645d02da3d5ULL }, 1945 + { &fnv_test_str[191], (Fnv64_t) 0x83544f33b58773a5ULL }, 1946 + { &fnv_test_str[192], (Fnv64_t) 0x9175cbb2160836c5ULL }, 1947 + { &fnv_test_str[193], (Fnv64_t) 0xc71b3bc175e72bc5ULL }, 1948 + { &fnv_test_str[194], (Fnv64_t) 0x636806ac222ec985ULL }, 1949 + { &fnv_test_str[195], (Fnv64_t) 0xb6ef0e6950f52ed5ULL }, 1950 + { &fnv_test_str[196], (Fnv64_t) 0xead3d8a0f3dfdaa5ULL }, 1951 + { &fnv_test_str[197], (Fnv64_t) 0x922908fe9a861ba5ULL }, 1952 + { &fnv_test_str[198], (Fnv64_t) 0x6d4821de275fd5c5ULL }, 1953 + { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL }, 1954 + { &fnv_test_str[200], (Fnv64_t) 0xc23e9fccd6f70591ULL }, 1955 + { &fnv_test_str[201], (Fnv64_t) 0xc1af12bdfe16b5b5ULL }, 1956 + { &fnv_test_str[202], (Fnv64_t) 0x39e9f18f2f85e221ULL }, 1957 + { NULL, (Fnv64_t) 0 } 1958 + }; 1959 + #else /* HAVE_64BIT_LONG_LONG */ 1960 + struct fnv1a_64_test_vector fnv1a_64_vector[] = { 1961 + { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, 1962 + { &fnv_test_str[1], (Fnv64_t) {0x8601ec8cUL, 0xaf63dc4cUL} }, 1963 + { &fnv_test_str[2], (Fnv64_t) {0x8601f1a5UL, 0xaf63df4cUL} }, 1964 + { &fnv_test_str[3], (Fnv64_t) {0x8601eff2UL, 0xaf63de4cUL} }, 1965 + { &fnv_test_str[4], (Fnv64_t) {0x8601e773UL, 0xaf63d94cUL} }, 1966 + { &fnv_test_str[5], (Fnv64_t) {0x8601e5c0UL, 0xaf63d84cUL} }, 1967 + { &fnv_test_str[6], (Fnv64_t) {0x8601ead9UL, 0xaf63db4cUL} }, 1968 + { &fnv_test_str[7], (Fnv64_t) {0xb541d342UL, 0x08985907UL} }, 1969 + { &fnv_test_str[8], (Fnv64_t) {0xfed9d577UL, 0xdcb27518UL} }, 1970 + { &fnv_test_str[9], (Fnv64_t) {0x0c2512afUL, 0xdd120e79UL} }, 1971 + { &fnv_test_str[10], (Fnv64_t) {0xa2fef40aUL, 0xcac165afUL} }, 1972 + { &fnv_test_str[11], (Fnv64_t) {0xf73967e8UL, 0x85944171UL} }, 1973 + { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, 1974 + { &fnv_test_str[13], (Fnv64_t) {0xb544f1e4UL, 0x089be207UL} }, 1975 + { &fnv_test_str[14], (Fnv64_t) {0xb54d9b5fUL, 0x08a61407UL} }, 1976 + { &fnv_test_str[15], (Fnv64_t) {0xb54ab836UL, 0x08a2ae07UL} }, 1977 + { &fnv_test_str[16], (Fnv64_t) {0xb53c4869UL, 0x0891b007UL} }, 1978 + { &fnv_test_str[17], (Fnv64_t) {0xb5396540UL, 0x088e4a07UL} }, 1979 + { &fnv_test_str[18], (Fnv64_t) {0xb5420ebbUL, 0x08987c07UL} }, 1980 + { &fnv_test_str[19], (Fnv64_t) {0xfed9f926UL, 0xdcb28a18UL} }, 1981 + { &fnv_test_str[20], (Fnv64_t) {0x0c25b935UL, 0xdd127079UL} }, 1982 + { &fnv_test_str[21], (Fnv64_t) {0xa2febf5dUL, 0xcac146afUL} }, 1983 + { &fnv_test_str[22], (Fnv64_t) {0xf738acfeUL, 0x8593d371UL} }, 1984 + { &fnv_test_str[23], (Fnv64_t) {0x168b8f38UL, 0x34531ca7UL} }, 1985 + { &fnv_test_str[24], (Fnv64_t) {0xb54a22aeUL, 0x08a25607UL} }, 1986 + { &fnv_test_str[25], (Fnv64_t) {0x0cf90df3UL, 0xf5faf019UL} }, 1987 + { &fnv_test_str[26], (Fnv64_t) {0x0b3221c7UL, 0xf2739791UL} }, 1988 + { &fnv_test_str[27], (Fnv64_t) {0x062f22e0UL, 0x2c8c2b76UL} }, 1989 + { &fnv_test_str[28], (Fnv64_t) {0x8217b8fdUL, 0xe150688cUL} }, 1990 + { &fnv_test_str[29], (Fnv64_t) {0x0e4f1f87UL, 0xf35a83c1UL} }, 1991 + { &fnv_test_str[30], (Fnv64_t) {0x507344d0UL, 0xd1edd10bUL} }, 1992 + { &fnv_test_str[31], (Fnv64_t) {0xb3ddb8c3UL, 0x2a5ee739UL} }, 1993 + { &fnv_test_str[32], (Fnv64_t) {0xa1c0d310UL, 0xdcfb970cUL} }, 1994 + { &fnv_test_str[33], (Fnv64_t) {0xdaa6da90UL, 0x4054da76UL} }, 1995 + { &fnv_test_str[34], (Fnv64_t) {0x89861368UL, 0xf70a2ff5UL} }, 1996 + { &fnv_test_str[35], (Fnv64_t) {0xaed25f17UL, 0x4c628b38UL} }, 1997 + { &fnv_test_str[36], (Fnv64_t) {0x0f78189fUL, 0x9dd1f651UL} }, 1998 + { &fnv_test_str[37], (Fnv64_t) {0x491270ceUL, 0xa3de85bdUL} }, 1999 + { &fnv_test_str[38], (Fnv64_t) {0x2a55e61dUL, 0x858e2fa3UL} }, 2000 + { &fnv_test_str[39], (Fnv64_t) {0xeff5f915UL, 0x46810940UL} }, 2001 + { &fnv_test_str[40], (Fnv64_t) {0x0cf8edaaUL, 0xf5fadd19UL} }, 2002 + { &fnv_test_str[41], (Fnv64_t) {0x0b32b3e9UL, 0xf273ed91UL} }, 2003 + { &fnv_test_str[42], (Fnv64_t) {0x062f6525UL, 0x2c8c5276UL} }, 2004 + { &fnv_test_str[43], (Fnv64_t) {0x821842a0UL, 0xe150b98cUL} }, 2005 + { &fnv_test_str[44], (Fnv64_t) {0x0e4f55e7UL, 0xf35aa3c1UL} }, 2006 + { &fnv_test_str[45], (Fnv64_t) {0x50729265UL, 0xd1ed680bUL} }, 2007 + { &fnv_test_str[46], (Fnv64_t) {0xb3dded70UL, 0x2a5f0639UL} }, 2008 + { &fnv_test_str[47], (Fnv64_t) {0xa1c0f359UL, 0xdcfbaa0cUL} }, 2009 + { &fnv_test_str[48], (Fnv64_t) {0xdaa6a430UL, 0x4054ba76UL} }, 2010 + { &fnv_test_str[49], (Fnv64_t) {0x898562b0UL, 0xf709c7f5UL} }, 2011 + { &fnv_test_str[50], (Fnv64_t) {0xaed2f9b8UL, 0x4c62e638UL} }, 2012 + { &fnv_test_str[51], (Fnv64_t) {0x0f779415UL, 0x9dd1a851UL} }, 2013 + { &fnv_test_str[52], (Fnv64_t) {0x4911d62dUL, 0xa3de2abdUL} }, 2014 + { &fnv_test_str[53], (Fnv64_t) {0x2a55ae0aUL, 0x858e0ea3UL} }, 2015 + { &fnv_test_str[54], (Fnv64_t) {0xeff60347UL, 0x46810f40UL} }, 2016 + { &fnv_test_str[55], (Fnv64_t) {0xbef63eafUL, 0xc33bce57UL} }, 2017 + { &fnv_test_str[56], (Fnv64_t) {0xb54a0265UL, 0x08a24307UL} }, 2018 + { &fnv_test_str[57], (Fnv64_t) {0x0cc18d15UL, 0xf5b9fd19UL} }, 2019 + { &fnv_test_str[58], (Fnv64_t) {0xace35703UL, 0x4c968290UL} }, 2020 + { &fnv_test_str[59], (Fnv64_t) {0xc64d9350UL, 0x07174bd5UL} }, 2021 + { &fnv_test_str[60], (Fnv64_t) {0xf5d18750UL, 0x5a294c3fUL} }, 2022 + { &fnv_test_str[61], (Fnv64_t) {0xb308b843UL, 0x05b3c1aeUL} }, 2023 + { &fnv_test_str[62], (Fnv64_t) {0x37d0f477UL, 0xb92a48daUL} }, 2024 + { &fnv_test_str[63], (Fnv64_t) {0xd80ebc49UL, 0x73cdddccUL} }, 2025 + { &fnv_test_str[64], (Fnv64_t) {0x210a266bUL, 0xd58c4c13UL} }, 2026 + { &fnv_test_str[65], (Fnv64_t) {0x243ec194UL, 0xe78b6081UL} }, 2027 + { &fnv_test_str[66], (Fnv64_t) {0x96a39f34UL, 0xb096f770UL} }, 2028 + { &fnv_test_str[67], (Fnv64_t) {0xf807b6a3UL, 0xb425c54fUL} }, 2029 + { &fnv_test_str[68], (Fnv64_t) {0x751bb46eUL, 0x23e520e2UL} }, 2030 + { &fnv_test_str[69], (Fnv64_t) {0xfe1385ecUL, 0x1a0b44ccUL} }, 2031 + { &fnv_test_str[70], (Fnv64_t) {0x0cc2119fUL, 0xf5ba4b19UL} }, 2032 + { &fnv_test_str[71], (Fnv64_t) {0xace2baafUL, 0x4c962690UL} }, 2033 + { &fnv_test_str[72], (Fnv64_t) {0xc64cda19UL, 0x0716ded5UL} }, 2034 + { &fnv_test_str[73], (Fnv64_t) {0xf5d150f0UL, 0x5a292c3fUL} }, 2035 + { &fnv_test_str[74], (Fnv64_t) {0xb308ecf0UL, 0x05b3e0aeUL} }, 2036 + { &fnv_test_str[75], (Fnv64_t) {0x37d119d9UL, 0xb92a5edaUL} }, 2037 + { &fnv_test_str[76], (Fnv64_t) {0xd80f6635UL, 0x73ce41ccUL} }, 2038 + { &fnv_test_str[77], (Fnv64_t) {0x2109f00bUL, 0xd58c2c13UL} }, 2039 + { &fnv_test_str[78], (Fnv64_t) {0x243f47d1UL, 0xe78baf81UL} }, 2040 + { &fnv_test_str[79], (Fnv64_t) {0x96a2ee7cUL, 0xb0968f70UL} }, 2041 + { &fnv_test_str[80], (Fnv64_t) {0xf807855cUL, 0xb425a84fUL} }, 2042 + { &fnv_test_str[81], (Fnv64_t) {0x751b56f9UL, 0x23e4e9e2UL} }, 2043 + { &fnv_test_str[82], (Fnv64_t) {0xfe1396eaUL, 0x1a0b4eccUL} }, 2044 + { &fnv_test_str[83], (Fnv64_t) {0xbb2c9004UL, 0x54abd453UL} }, 2045 + { &fnv_test_str[84], (Fnv64_t) {0xb55ec3daUL, 0x08ba5f07UL} }, 2046 + { &fnv_test_str[85], (Fnv64_t) {0x3006cb6eUL, 0x33735419UL} }, 2047 + { &fnv_test_str[86], (Fnv64_t) {0x80aabd0bUL, 0xa430d846UL} }, 2048 + { &fnv_test_str[87], (Fnv64_t) {0xa21f39b1UL, 0xa9bc8accUL} }, 2049 + { &fnv_test_str[88], (Fnv64_t) {0x91cc682dUL, 0x69611964UL} }, 2050 + { &fnv_test_str[89], (Fnv64_t) {0x4799dfe9UL, 0xad2bb177UL} }, 2051 + { &fnv_test_str[90], (Fnv64_t) {0x91cc6314UL, 0x69611664UL} }, 2052 + { &fnv_test_str[91], (Fnv64_t) {0x4a3b1236UL, 0x8d1bb390UL} }, 2053 + { &fnv_test_str[92], (Fnv64_t) {0x91cc64c7UL, 0x69611764UL} }, 2054 + { &fnv_test_str[93], (Fnv64_t) {0xf40434c7UL, 0xed205d87UL} }, 2055 + { &fnv_test_str[94], (Fnv64_t) {0x91cc5faeUL, 0x69611464UL} }, 2056 + { &fnv_test_str[95], (Fnv64_t) {0x44f8ad9cUL, 0xcd3baf5eUL} }, 2057 + { &fnv_test_str[96], (Fnv64_t) {0x127cd6d8UL, 0xe3b36596UL} }, 2058 + { &fnv_test_str[97], (Fnv64_t) {0xc8e8a646UL, 0xf77f1072UL} }, 2059 + { &fnv_test_str[98], (Fnv64_t) {0x127cd372UL, 0xe3b36396UL} }, 2060 + { &fnv_test_str[99], (Fnv64_t) {0x932ad458UL, 0x6067dce9UL} }, 2061 + { &fnv_test_str[100], (Fnv64_t) {0x127cf208UL, 0xe3b37596UL} }, 2062 + { &fnv_test_str[101], (Fnv64_t) {0x9fe83936UL, 0x4b7b10faUL} }, 2063 + { &fnv_test_str[102], (Fnv64_t) {0x04d914beUL, 0xaabafe71UL} }, 2064 + { &fnv_test_str[103], (Fnv64_t) {0x3cde3edaUL, 0xf4d3180bUL} }, 2065 + { &fnv_test_str[104], (Fnv64_t) {0x04d9130bUL, 0xaabafd71UL} }, 2066 + { &fnv_test_str[105], (Fnv64_t) {0x3cdb5bb1UL, 0xf4cfb20bUL} }, 2067 + { &fnv_test_str[106], (Fnv64_t) {0x04d91158UL, 0xaabafc71UL} }, 2068 + { &fnv_test_str[107], (Fnv64_t) {0x3cd87888UL, 0xf4cc4c0bUL} }, 2069 + { &fnv_test_str[108], (Fnv64_t) {0xd2a8d3a7UL, 0xe729bac5UL} }, 2070 + { &fnv_test_str[109], (Fnv64_t) {0xf4dfa4c5UL, 0x74bc0524UL} }, 2071 + { &fnv_test_str[110], (Fnv64_t) {0xd2a5b352UL, 0xe72630c5UL} }, 2072 + { &fnv_test_str[111], (Fnv64_t) {0xef8fb456UL, 0x6b983224UL} }, 2073 + { &fnv_test_str[112], (Fnv64_t) {0xd2ae266dUL, 0xe73042c5UL} }, 2074 + { &fnv_test_str[113], (Fnv64_t) {0xfdeb4b37UL, 0x8527e324UL} }, 2075 + { &fnv_test_str[114], (Fnv64_t) {0xee952abcUL, 0x0a83c86fUL} }, 2076 + { &fnv_test_str[115], (Fnv64_t) {0x67779d74UL, 0x73185232UL} }, 2077 + { &fnv_test_str[116], (Fnv64_t) {0x6b8caca1UL, 0x3e66d3d5UL} }, 2078 + { &fnv_test_str[117], (Fnv64_t) {0xc0095593UL, 0x956694a5UL} }, 2079 + { &fnv_test_str[118], (Fnv64_t) {0xbb1a6fc8UL, 0xcac54572UL} }, 2080 + { &fnv_test_str[119], (Fnv64_t) {0xedebf0d8UL, 0xa7a4c9f3UL} }, 2081 + { &fnv_test_str[120], (Fnv64_t) {0xac17b143UL, 0x7829851fUL} }, 2082 + { &fnv_test_str[121], (Fnv64_t) {0xf81bcf06UL, 0x2c8f4c9aUL} }, 2083 + { &fnv_test_str[122], (Fnv64_t) {0x9740c732UL, 0xd34e3153UL} }, 2084 + { &fnv_test_str[123], (Fnv64_t) {0x253d2db1UL, 0x3605a2acUL} }, 2085 + { &fnv_test_str[124], (Fnv64_t) {0x46f4a3c3UL, 0x08c11b83UL} }, 2086 + { &fnv_test_str[125], (Fnv64_t) {0x9ce8a6daUL, 0x6be39628UL} }, 2087 + { &fnv_test_str[126], (Fnv64_t) {0x7fe794c5UL, 0xd9b957fbUL} }, 2088 + { &fnv_test_str[127], (Fnv64_t) {0x04560a93UL, 0x05be33daUL} }, 2089 + { &fnv_test_str[128], (Fnv64_t) {0x7ba9747cUL, 0x0957f157UL} }, 2090 + { &fnv_test_str[129], (Fnv64_t) {0xc24fba57UL, 0xda2cc3acUL} }, 2091 + { &fnv_test_str[130], (Fnv64_t) {0x5b29e7f0UL, 0x74136f18UL} }, 2092 + { &fnv_test_str[131], (Fnv64_t) {0x0edb93b2UL, 0xb2f2b459UL} }, 2093 + { &fnv_test_str[132], (Fnv64_t) {0x8b86ae04UL, 0xb3608fceUL} }, 2094 + { &fnv_test_str[133], (Fnv64_t) {0x79359063UL, 0x4a3a8650UL} }, 2095 + { &fnv_test_str[134], (Fnv64_t) {0x96880a50UL, 0x5b3a7ef4UL} }, 2096 + { &fnv_test_str[135], (Fnv64_t) {0x3854c23bUL, 0x48fae316UL} }, 2097 + { &fnv_test_str[136], (Fnv64_t) {0x476e0b9aUL, 0x07aaa640UL} }, 2098 + { &fnv_test_str[137], (Fnv64_t) {0x383a687dUL, 0x2f653656UL} }, 2099 + { &fnv_test_str[138], (Fnv64_t) {0x7599d79cUL, 0xa1031f8eUL} }, 2100 + { &fnv_test_str[139], (Fnv64_t) {0x8ff92477UL, 0xa3190817UL} }, 2101 + { &fnv_test_str[140], (Fnv64_t) {0x14c3fb83UL, 0x097edf3cUL} }, 2102 + { &fnv_test_str[141], (Fnv64_t) {0xeaa0971bUL, 0xb51ca83fUL} }, 2103 + { &fnv_test_str[142], (Fnv64_t) {0xd784f2e9UL, 0xdd3c0d96UL} }, 2104 + { &fnv_test_str[143], (Fnv64_t) {0xea767d78UL, 0x86cd26a9UL} }, 2105 + { &fnv_test_str[144], (Fnv64_t) {0x54a30c18UL, 0xe6b215ffUL} }, 2106 + { &fnv_test_str[145], (Fnv64_t) {0xc5531093UL, 0xec5b06a1UL} }, 2107 + { &fnv_test_str[146], (Fnv64_t) {0x9f9ec5e5UL, 0x45665a92UL} }, 2108 + { &fnv_test_str[147], (Fnv64_t) {0xa9f10907UL, 0x8c7609b4UL} }, 2109 + { &fnv_test_str[148], (Fnv64_t) {0x91f0d729UL, 0x89aac3a4UL} }, 2110 + { &fnv_test_str[149], (Fnv64_t) {0xe0f4a403UL, 0x32ce6b26UL} }, 2111 + { &fnv_test_str[150], (Fnv64_t) {0x02b53e01UL, 0x614ab44eUL} }, 2112 + { &fnv_test_str[151], (Fnv64_t) {0x6eef3290UL, 0xfa6472ebUL} }, 2113 + { &fnv_test_str[152], (Fnv64_t) {0x1948eb6aUL, 0x9e5d75ebUL} }, 2114 + { &fnv_test_str[153], (Fnv64_t) {0xa8671852UL, 0xb6d12ad4UL} }, 2115 + { &fnv_test_str[154], (Fnv64_t) {0xeba07af1UL, 0x88826f56UL} }, 2116 + { &fnv_test_str[155], (Fnv64_t) {0x645bc0fdUL, 0x44535bf2UL} }, 2117 + { &fnv_test_str[156], (Fnv64_t) {0xc21e3728UL, 0x169388ffUL} }, 2118 + { &fnv_test_str[157], (Fnv64_t) {0x396d8224UL, 0xf68aac9eUL} }, 2119 + { &fnv_test_str[158], (Fnv64_t) {0x472b3883UL, 0x8e87d7e7UL} }, 2120 + { &fnv_test_str[159], (Fnv64_t) {0xa8b423deUL, 0x295c26caUL} }, 2121 + { &fnv_test_str[160], (Fnv64_t) {0x92e72176UL, 0x322c8142UL} }, 2122 + { &fnv_test_str[161], (Fnv64_t) {0xb8af7268UL, 0x8a06550eUL} }, 2123 + { &fnv_test_str[162], (Fnv64_t) {0x661bcf71UL, 0xef86d60eUL} }, 2124 + { &fnv_test_str[163], (Fnv64_t) {0x7f30ee54UL, 0x9e5426c8UL} }, 2125 + { &fnv_test_str[164], (Fnv64_t) {0x26fd047eUL, 0xf1ea8aa8UL} }, 2126 + { &fnv_test_str[165], (Fnv64_t) {0x642cb769UL, 0x0babaf9aUL} }, 2127 + { &fnv_test_str[166], (Fnv64_t) {0x068d012eUL, 0x4b3341d4UL} }, 2128 + { &fnv_test_str[167], (Fnv64_t) {0xc30a335cUL, 0xd15605cbUL} }, 2129 + { &fnv_test_str[168], (Fnv64_t) {0xed8412e5UL, 0x5b21060aUL} }, 2130 + { &fnv_test_str[169], (Fnv64_t) {0xce6f4227UL, 0x45e2cda1UL} }, 2131 + { &fnv_test_str[170], (Fnv64_t) {0x033ad7d4UL, 0x50ae3745UL} }, 2132 + { &fnv_test_str[171], (Fnv64_t) {0xd46bf414UL, 0xaa4588ceUL} }, 2133 + { &fnv_test_str[172], (Fnv64_t) {0x4a95467eUL, 0xc1b0056cUL} }, 2134 + { &fnv_test_str[173], (Fnv64_t) {0xde8b4089UL, 0x56576a71UL} }, 2135 + { &fnv_test_str[174], (Fnv64_t) {0xa6dc927eUL, 0xbf20965fUL} }, 2136 + { &fnv_test_str[175], (Fnv64_t) {0xc2040882UL, 0x569f8383UL} }, 2137 + { &fnv_test_str[176], (Fnv64_t) {0xa08feca0UL, 0xe1e772fbUL} }, 2138 + { &fnv_test_str[177], (Fnv64_t) {0x97138ac4UL, 0x4ced94afUL} }, 2139 + { &fnv_test_str[178], (Fnv64_t) {0x337a82fbUL, 0xc4112ffbUL} }, 2140 + { &fnv_test_str[179], (Fnv64_t) {0x1de38b7dUL, 0xd64a4fd4UL} }, 2141 + { &fnv_test_str[180], (Fnv64_t) {0x9edebcbbUL, 0x4cfc3232UL} }, 2142 + { &fnv_test_str[181], (Fnv64_t) {0x45050395UL, 0x08035644UL} }, 2143 + { &fnv_test_str[182], (Fnv64_t) {0xf4642ffdUL, 0xaa1574ecUL} }, 2144 + { &fnv_test_str[183], (Fnv64_t) {0x4cc315f9UL, 0x694bc4e5UL} }, 2145 + { &fnv_test_str[184], (Fnv64_t) {0x3b011721UL, 0xa3d7cb27UL} }, 2146 + { &fnv_test_str[185], (Fnv64_t) {0x6115bfa5UL, 0x577c2f8bUL} }, 2147 + { &fnv_test_str[186], (Fnv64_t) {0x769fb4c1UL, 0xb7ec8c1aUL} }, 2148 + { &fnv_test_str[187], (Fnv64_t) {0x3359ab19UL, 0x5d5cfce6UL} }, 2149 + { &fnv_test_str[188], (Fnv64_t) {0xd65b5f71UL, 0x33b96c3cUL} }, 2150 + { &fnv_test_str[189], (Fnv64_t) {0x80602bb9UL, 0xd8450977UL} }, 2151 + { &fnv_test_str[190], (Fnv64_t) {0xd02da3d5UL, 0x84d47645UL} }, 2152 + { &fnv_test_str[191], (Fnv64_t) {0xb58773a5UL, 0x83544f33UL} }, 2153 + { &fnv_test_str[192], (Fnv64_t) {0x160836c5UL, 0x9175cbb2UL} }, 2154 + { &fnv_test_str[193], (Fnv64_t) {0x75e72bc5UL, 0xc71b3bc1UL} }, 2155 + { &fnv_test_str[194], (Fnv64_t) {0x222ec985UL, 0x636806acUL} }, 2156 + { &fnv_test_str[195], (Fnv64_t) {0x50f52ed5UL, 0xb6ef0e69UL} }, 2157 + { &fnv_test_str[196], (Fnv64_t) {0xf3dfdaa5UL, 0xead3d8a0UL} }, 2158 + { &fnv_test_str[197], (Fnv64_t) {0x9a861ba5UL, 0x922908feUL} }, 2159 + { &fnv_test_str[198], (Fnv64_t) {0x275fd5c5UL, 0x6d4821deUL} }, 2160 + { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} }, 2161 + { &fnv_test_str[200], (Fnv64_t) {0xd6f70591UL, 0xc23e9fccUL} }, 2162 + { &fnv_test_str[201], (Fnv64_t) {0xfe16b5b5UL, 0xc1af12bdUL} }, 2163 + { &fnv_test_str[202], (Fnv64_t) {0x2f85e221UL, 0x39e9f18fUL} }, 2164 + { NULL, (Fnv64_t) {0,0} } 2165 + }; 2166 + #endif /* HAVE_64BIT_LONG_LONG */ 2167 + 2168 + /* end of output generated by make vector.c */ 2169 + /* 2170 + * insert the contents of vector.c above 2171 + */ 2172 + 2173 + 2174 + /* 2175 + * unknown_hash_type - report an unknown hash type error 2176 + * 2177 + * NOTE: Does not return. 2178 + */ 2179 + void 2180 + unknown_hash_type(char *prog, enum fnv_type type, int code) 2181 + { 2182 + fprintf(stderr, "%s: unknown or unexpexted hash type: %d\n", prog, type); 2183 + exit(code); 2184 + } 2185 + 2186 + 2187 + /* 2188 + * print_fnv32 - print an FNV hash 2189 + * 2190 + * given: 2191 + * hval the hash value to print 2192 + * mask lower bit mask 2193 + * verbose 1 => print arg with hash 2194 + * arg string or filename arg 2195 + */ 2196 + void 2197 + print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg) 2198 + { 2199 + if (verbose) { 2200 + printf("0x%08lx %s\n", hval & mask, arg); 2201 + } else { 2202 + printf("0x%08lx\n", hval & mask); 2203 + } 2204 + } 2205 + 2206 + 2207 + /* 2208 + * print_fnv64 - print an FNV hash 2209 + * 2210 + * given: 2211 + * hval the hash value to print 2212 + * mask lower bit mask 2213 + * verbose 1 => print arg with hash 2214 + * arg string or filename arg 2215 + */ 2216 + void 2217 + print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg) 2218 + { 2219 + #if defined(HAVE_64BIT_LONG_LONG) 2220 + if (verbose) { 2221 + printf("0x%016llx %s\n", hval & mask, arg); 2222 + } else { 2223 + printf("0x%016llx\n", hval & mask); 2224 + } 2225 + #else 2226 + if (verbose) { 2227 + printf("0x%08lx%08lx %s\n", 2228 + hval.w32[1] & mask.w32[1], 2229 + hval.w32[0] & mask.w32[0], 2230 + arg); 2231 + } else { 2232 + printf("0x%08lx%08lx\n", 2233 + hval.w32[1] & mask.w32[1], 2234 + hval.w32[0] & mask.w32[0]); 2235 + } 2236 + #endif 2237 + }
+154
quantum/wear_leveling/tests/backing_mocks.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include "gtest/gtest.h" 4 + #include "gmock/gmock.h" 5 + #include "backing_mocks.hpp" 6 + 7 + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 8 + // Backing Store Mock implementation 9 + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 10 + 11 + void MockBackingStore::reset_instance() { 12 + for (auto&& e : backing_storage) 13 + e.reset(); 14 + 15 + locked = true; 16 + 17 + backing_erasure_count = 0; 18 + backing_max_write_count = 0; 19 + backing_total_write_count = 0; 20 + 21 + backing_init_invoke_count = 0; 22 + backing_unlock_invoke_count = 0; 23 + backing_erase_invoke_count = 0; 24 + backing_write_invoke_count = 0; 25 + backing_lock_invoke_count = 0; 26 + 27 + init_success_callback = [](std::uint64_t) { return true; }; 28 + erase_success_callback = [](std::uint64_t) { return true; }; 29 + unlock_success_callback = [](std::uint64_t) { return true; }; 30 + write_success_callback = [](std::uint64_t, std::uint32_t) { return true; }; 31 + lock_success_callback = [](std::uint64_t) { return true; }; 32 + 33 + write_log.clear(); 34 + } 35 + 36 + bool MockBackingStore::init(void) { 37 + ++backing_init_invoke_count; 38 + 39 + if (init_success_callback) { 40 + return init_success_callback(backing_init_invoke_count); 41 + } 42 + return true; 43 + } 44 + 45 + bool MockBackingStore::unlock(void) { 46 + ++backing_unlock_invoke_count; 47 + 48 + EXPECT_TRUE(is_locked()) << "Attempted to unlock but was not locked"; 49 + locked = false; 50 + 51 + if (unlock_success_callback) { 52 + return unlock_success_callback(backing_unlock_invoke_count); 53 + } 54 + return true; 55 + } 56 + 57 + bool MockBackingStore::erase(void) { 58 + ++backing_erase_invoke_count; 59 + 60 + // Erase each slot 61 + for (std::size_t i = 0; i < backing_storage.size(); ++i) { 62 + // Drop out of erase early with failure if we need to 63 + if (erase_success_callback && !erase_success_callback(backing_erase_invoke_count)) { 64 + append_log(true); 65 + return false; 66 + } 67 + 68 + backing_storage[i].erase(); 69 + } 70 + 71 + // Keep track of the erase in the write log so that we can verify during tests 72 + append_log(true); 73 + 74 + ++backing_erasure_count; 75 + return true; 76 + } 77 + 78 + bool MockBackingStore::write(uint32_t address, backing_store_int_t value) { 79 + ++backing_write_invoke_count; 80 + 81 + // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE 82 + EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size"; 83 + EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access"; 84 + EXPECT_FALSE(is_locked()) << "Write was attempted without being unlocked first"; 85 + 86 + // Drop out of write early with failure if we need to 87 + if (write_success_callback && !write_success_callback(backing_write_invoke_count, address)) { 88 + return false; 89 + } 90 + 91 + // Write the complement as we're simulating flash memory -- 0xFF means 0x00 92 + std::size_t index = address / BACKING_STORE_WRITE_SIZE; 93 + backing_storage[index].set(~value); 94 + 95 + // Keep track of the write log so that we can verify during tests 96 + append_log(address, value); 97 + 98 + // Keep track of the total number of writes into the backing store 99 + ++backing_total_write_count; 100 + 101 + return true; 102 + } 103 + 104 + bool MockBackingStore::lock(void) { 105 + ++backing_lock_invoke_count; 106 + 107 + EXPECT_FALSE(is_locked()) << "Attempted to lock but was not unlocked"; 108 + locked = true; 109 + 110 + if (lock_success_callback) { 111 + return lock_success_callback(backing_lock_invoke_count); 112 + } 113 + return true; 114 + } 115 + 116 + bool MockBackingStore::read(uint32_t address, backing_store_int_t& value) const { 117 + // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE 118 + EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size"; 119 + EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access"; 120 + 121 + // Read and take the complement as we're simulating flash memory -- 0xFF means 0x00 122 + std::size_t index = address / BACKING_STORE_WRITE_SIZE; 123 + value = ~backing_storage[index].get(); 124 + 125 + return true; 126 + } 127 + 128 + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 129 + // Backing Implementation 130 + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 131 + 132 + extern "C" bool backing_store_init(void) { 133 + return MockBackingStore::Instance().init(); 134 + } 135 + 136 + extern "C" bool backing_store_unlock(void) { 137 + return MockBackingStore::Instance().unlock(); 138 + } 139 + 140 + extern "C" bool backing_store_erase(void) { 141 + return MockBackingStore::Instance().erase(); 142 + } 143 + 144 + extern "C" bool backing_store_write(uint32_t address, backing_store_int_t value) { 145 + return MockBackingStore::Instance().write(address, value); 146 + } 147 + 148 + extern "C" bool backing_store_lock(void) { 149 + return MockBackingStore::Instance().lock(); 150 + } 151 + 152 + extern "C" bool backing_store_read(uint32_t address, backing_store_int_t* value) { 153 + return MockBackingStore::Instance().read(address, *value); 154 + }
+210
quantum/wear_leveling/tests/backing_mocks.hpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #pragma once 4 + #include <algorithm> 5 + #include <array> 6 + #include <cstdint> 7 + #include <cstdlib> 8 + #include <functional> 9 + #include <type_traits> 10 + #include <vector> 11 + 12 + extern "C" { 13 + #include "fnv.h" 14 + #include "wear_leveling.h" 15 + #include "wear_leveling_internal.h" 16 + }; 17 + 18 + // Maximum number of mock write log entries to keep 19 + using MOCK_WRITE_LOG_MAX_ENTRIES = std::integral_constant<std::size_t, 1024>; 20 + // Complement to the backing store integral, for emulating flash erases of all bytes=0xFF 21 + using BACKING_STORE_INTEGRAL_COMPLEMENT = std::integral_constant<backing_store_int_t, ((backing_store_int_t)(~(backing_store_int_t)0))>; 22 + // Total number of elements stored in the backing arrays 23 + using BACKING_STORE_ELEMENT_COUNT = std::integral_constant<std::size_t, (WEAR_LEVELING_BACKING_SIZE / sizeof(backing_store_int_t))>; 24 + 25 + class MockBackingStoreElement { 26 + private: 27 + backing_store_int_t value; 28 + std::size_t writes; 29 + std::size_t erases; 30 + 31 + public: 32 + MockBackingStoreElement() : value(BACKING_STORE_INTEGRAL_COMPLEMENT::value), writes(0), erases(0) {} 33 + void reset() { 34 + erase(); 35 + writes = 0; 36 + erases = 0; 37 + } 38 + void erase() { 39 + if (!is_erased()) { 40 + ++erases; 41 + } 42 + value = BACKING_STORE_INTEGRAL_COMPLEMENT::value; 43 + } 44 + backing_store_int_t get() const { 45 + return value; 46 + } 47 + void set(const backing_store_int_t& v) { 48 + EXPECT_TRUE(is_erased()) << "Attempted write at index which isn't empty."; 49 + value = v; 50 + ++writes; 51 + } 52 + std::size_t num_writes() const { 53 + return writes; 54 + } 55 + std::size_t num_erases() const { 56 + return erases; 57 + } 58 + bool is_erased() const { 59 + return value == BACKING_STORE_INTEGRAL_COMPLEMENT::value; 60 + } 61 + }; 62 + 63 + struct MockBackingStoreLogEntry { 64 + MockBackingStoreLogEntry(uint32_t address, backing_store_int_t value) : address(address), value(value), erased(false) {} 65 + MockBackingStoreLogEntry(bool erased) : address(0), value(0), erased(erased) {} 66 + uint32_t address = 0; // The address of the operation 67 + backing_store_int_t value = 0; // The value of the operation 68 + bool erased = false; // Whether the entire backing store was erased 69 + }; 70 + 71 + class MockBackingStore { 72 + private: 73 + MockBackingStore() { 74 + reset_instance(); 75 + } 76 + 77 + // Type containing each of the entries and the write counts 78 + using storage_t = std::array<MockBackingStoreElement, BACKING_STORE_ELEMENT_COUNT::value>; 79 + 80 + // Whether the backing store is locked 81 + bool locked; 82 + // The actual data stored in the emulated flash 83 + storage_t backing_storage; 84 + // The number of erase cycles that have occurred 85 + std::uint64_t backing_erasure_count; 86 + // The max number of writes to an element of the backing store 87 + std::uint64_t backing_max_write_count; 88 + // The total number of writes to all elements of the backing store 89 + std::uint64_t backing_total_write_count; 90 + // The write log for the backing store 91 + std::vector<MockBackingStoreLogEntry> write_log; 92 + 93 + // The number of times each API was invoked 94 + std::uint64_t backing_init_invoke_count; 95 + std::uint64_t backing_unlock_invoke_count; 96 + std::uint64_t backing_erase_invoke_count; 97 + std::uint64_t backing_write_invoke_count; 98 + std::uint64_t backing_lock_invoke_count; 99 + 100 + // Whether init should succeed 101 + std::function<bool(std::uint64_t)> init_success_callback; 102 + // Whether erase should succeed 103 + std::function<bool(std::uint64_t)> erase_success_callback; 104 + // Whether unlocks should succeed 105 + std::function<bool(std::uint64_t)> unlock_success_callback; 106 + // Whether writes should succeed 107 + std::function<bool(std::uint64_t, std::uint32_t)> write_success_callback; 108 + // Whether locks should succeed 109 + std::function<bool(std::uint64_t)> lock_success_callback; 110 + 111 + template <typename... Args> 112 + void append_log(Args&&... args) { 113 + if (write_log.size() < MOCK_WRITE_LOG_MAX_ENTRIES::value) { 114 + write_log.emplace_back(std::forward<Args>(args)...); 115 + } 116 + } 117 + 118 + public: 119 + static MockBackingStore& Instance() { 120 + static MockBackingStore instance; 121 + return instance; 122 + } 123 + 124 + std::uint64_t erasure_count() const { 125 + return backing_erasure_count; 126 + } 127 + std::uint64_t max_write_count() const { 128 + return backing_max_write_count; 129 + } 130 + std::uint64_t total_write_count() const { 131 + return backing_total_write_count; 132 + } 133 + 134 + // The number of times each API was invoked 135 + std::uint64_t init_invoke_count() const { 136 + return backing_init_invoke_count; 137 + } 138 + std::uint64_t unlock_invoke_count() const { 139 + return backing_unlock_invoke_count; 140 + } 141 + std::uint64_t erase_invoke_count() const { 142 + return backing_erase_invoke_count; 143 + } 144 + std::uint64_t write_invoke_count() const { 145 + return backing_write_invoke_count; 146 + } 147 + std::uint64_t lock_invoke_count() const { 148 + return backing_lock_invoke_count; 149 + } 150 + 151 + // Clear out the internal data for the next run 152 + void reset_instance(); 153 + 154 + bool is_locked() const { 155 + return locked; 156 + } 157 + 158 + // APIs for the backing store 159 + bool init(); 160 + bool unlock(); 161 + bool erase(); 162 + bool write(std::uint32_t address, backing_store_int_t value); 163 + bool lock(); 164 + bool read(std::uint32_t address, backing_store_int_t& value) const; 165 + 166 + // Control over when init/writes/erases should succeed 167 + void set_init_callback(std::function<bool(std::uint64_t)> callback) { 168 + init_success_callback = callback; 169 + } 170 + void set_erase_callback(std::function<bool(std::uint64_t)> callback) { 171 + erase_success_callback = callback; 172 + } 173 + void set_unlock_callback(std::function<bool(std::uint64_t)> callback) { 174 + unlock_success_callback = callback; 175 + } 176 + void set_write_callback(std::function<bool(std::uint64_t, std::uint32_t)> callback) { 177 + write_success_callback = callback; 178 + } 179 + void set_lock_callback(std::function<bool(std::uint64_t)> callback) { 180 + lock_success_callback = callback; 181 + } 182 + 183 + auto storage_begin() const -> decltype(backing_storage.begin()) { 184 + return backing_storage.begin(); 185 + } 186 + auto storage_end() const -> decltype(backing_storage.end()) { 187 + return backing_storage.end(); 188 + } 189 + 190 + auto storage_begin() -> decltype(backing_storage.begin()) { 191 + return backing_storage.begin(); 192 + } 193 + auto storage_end() -> decltype(backing_storage.end()) { 194 + return backing_storage.end(); 195 + } 196 + 197 + auto log_begin() -> decltype(write_log.begin()) { 198 + return write_log.begin(); 199 + } 200 + auto log_end() -> decltype(write_log.end()) { 201 + return write_log.end(); 202 + } 203 + 204 + auto log_begin() const -> decltype(write_log.begin()) { 205 + return write_log.begin(); 206 + } 207 + auto log_end() const -> decltype(write_log.end()) { 208 + return write_log.end(); 209 + } 210 + };
+66
quantum/wear_leveling/tests/rules.mk
··· 1 + wear_leveling_common_DEFS := \ 2 + -DWEAR_LEVELING_TESTS 3 + wear_leveling_common_SRC := \ 4 + $(LIB_PATH)/fnv/qmk_fnv_type_validation.c \ 5 + $(LIB_PATH)/fnv/hash_32a.c \ 6 + $(LIB_PATH)/fnv/hash_64a.c \ 7 + $(QUANTUM_PATH)/wear_leveling/wear_leveling.c \ 8 + $(QUANTUM_PATH)/wear_leveling/tests/backing_mocks.cpp 9 + wear_leveling_common_INC := \ 10 + $(LIB_PATH)/fnv \ 11 + $(QUANTUM_PATH)/wear_leveling 12 + 13 + wear_leveling_general_DEFS := \ 14 + $(wear_leveling_common_DEFS) \ 15 + -DBACKING_STORE_WRITE_SIZE=2 \ 16 + -DWEAR_LEVELING_BACKING_SIZE=48 \ 17 + -DWEAR_LEVELING_LOGICAL_SIZE=16 18 + wear_leveling_general_SRC := \ 19 + $(wear_leveling_common_SRC) \ 20 + $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_general.cpp 21 + wear_leveling_general_INC := \ 22 + $(wear_leveling_common_INC) 23 + 24 + wear_leveling_2byte_optimized_writes_DEFS := \ 25 + $(wear_leveling_common_DEFS) \ 26 + -DBACKING_STORE_WRITE_SIZE=2 \ 27 + -DWEAR_LEVELING_BACKING_SIZE=65536 \ 28 + -DWEAR_LEVELING_LOGICAL_SIZE=32768 29 + wear_leveling_2byte_optimized_writes_SRC := \ 30 + $(wear_leveling_common_SRC) \ 31 + $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp 32 + wear_leveling_2byte_optimized_writes_INC := \ 33 + $(wear_leveling_common_INC) 34 + 35 + wear_leveling_2byte_DEFS := \ 36 + $(wear_leveling_common_DEFS) \ 37 + -DBACKING_STORE_WRITE_SIZE=2 \ 38 + -DWEAR_LEVELING_BACKING_SIZE=48 \ 39 + -DWEAR_LEVELING_LOGICAL_SIZE=16 40 + wear_leveling_2byte_SRC := \ 41 + $(wear_leveling_common_SRC) \ 42 + $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte.cpp 43 + wear_leveling_2byte_INC := \ 44 + $(wear_leveling_common_INC) 45 + 46 + wear_leveling_4byte_DEFS := \ 47 + $(wear_leveling_common_DEFS) \ 48 + -DBACKING_STORE_WRITE_SIZE=4 \ 49 + -DWEAR_LEVELING_BACKING_SIZE=48 \ 50 + -DWEAR_LEVELING_LOGICAL_SIZE=16 51 + wear_leveling_4byte_SRC := \ 52 + $(wear_leveling_common_SRC) \ 53 + $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_4byte.cpp 54 + wear_leveling_4byte_INC := \ 55 + $(wear_leveling_common_INC) 56 + 57 + wear_leveling_8byte_DEFS := \ 58 + $(wear_leveling_common_DEFS) \ 59 + -DBACKING_STORE_WRITE_SIZE=8 \ 60 + -DWEAR_LEVELING_BACKING_SIZE=48 \ 61 + -DWEAR_LEVELING_LOGICAL_SIZE=16 62 + wear_leveling_8byte_SRC := \ 63 + $(wear_leveling_common_SRC) \ 64 + $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_8byte.cpp 65 + wear_leveling_8byte_INC := \ 66 + $(wear_leveling_common_INC)
+6
quantum/wear_leveling/tests/testlist.mk
··· 1 + TEST_LIST += \ 2 + wear_leveling_general \ 3 + wear_leveling_2byte_optimized_writes \ 4 + wear_leveling_2byte \ 5 + wear_leveling_4byte \ 6 + wear_leveling_8byte
+228
quantum/wear_leveling/tests/wear_leveling_2byte.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <numeric> 4 + #include "gtest/gtest.h" 5 + #include "gmock/gmock.h" 6 + #include "backing_mocks.hpp" 7 + 8 + class WearLeveling2Byte : public ::testing::Test { 9 + protected: 10 + void SetUp() override { 11 + MockBackingStore::Instance().reset_instance(); 12 + wear_leveling_init(); 13 + } 14 + }; 15 + 16 + static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data; 17 + 18 + static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { 19 + memcpy(&verify_data[address], value, length); 20 + return wear_leveling_write(address, value, length); 21 + } 22 + 23 + /** 24 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. 25 + */ 26 + TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash) { 27 + auto& inst = MockBackingStore::Instance(); 28 + uint8_t test_value = 0x15; 29 + test_write(0x02, &test_value, sizeof(test_value)); 30 + EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 31 + } 32 + 33 + /** 34 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. 35 + */ 36 + TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash_AfterErase) { 37 + auto& inst = MockBackingStore::Instance(); 38 + uint8_t test_value = 0x15; 39 + wear_leveling_erase(); 40 + test_write(0x02, &test_value, sizeof(test_value)); 41 + EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 42 + } 43 + 44 + /** 45 + * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the 46 + * base logical area. 47 + */ 48 + TEST_F(WearLeveling2Byte, ConsolidationOverflow) { 49 + auto& inst = MockBackingStore::Instance(); 50 + 51 + // Generate a test block of data which forces OPTIMIZED_64 writes 52 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue; 53 + 54 + // Write the data 55 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 56 + EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; 57 + uint8_t dummy = 0x40; 58 + EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; 59 + 60 + // All writes are at address<64, so each logical byte written will generate 1 write log entry, thus 1 backing store write. 61 + // Expected log: 62 + // [0..11]: optimised64, backing address 0x18, logical address 0x00 63 + // [12]: erase 64 + // [13..20]: consolidated data, backing address 0x00, logical address 0x00 65 + // [21..24]: FNV1a_64 result, backing address 0x10 66 + // [25]: optimised64, backing address 0x18, logical address 0x04 67 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 26); 68 + 69 + // Verify the backing store writes for the write log 70 + std::size_t index; 71 + write_log_entry_t e; 72 + for (index = 0; index < 12; ++index) { 73 + auto write_iter = inst.log_begin() + index; 74 + EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; 75 + e.raw16[0] = write_iter->value; 76 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; 77 + } 78 + 79 + // Verify the backing store erase 80 + { 81 + index = 12; 82 + auto write_iter = inst.log_begin() + index; 83 + e.raw16[0] = write_iter->value; 84 + EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; 85 + } 86 + 87 + // Verify the backing store writes for consolidation 88 + for (index = 13; index < 21; ++index) { 89 + auto write_iter = inst.log_begin() + index; 90 + EXPECT_EQ(write_iter->address, (index - 13) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; 91 + } 92 + 93 + // Verify the FNV1a_64 write 94 + { 95 + EXPECT_EQ((inst.log_begin() + 21)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; 96 + e.raw16[0] = (inst.log_begin() + 21)->value; 97 + e.raw16[1] = (inst.log_begin() + 22)->value; 98 + e.raw16[2] = (inst.log_begin() + 23)->value; 99 + e.raw16[3] = (inst.log_begin() + 24)->value; 100 + EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current 101 + } 102 + 103 + // Verify the final write 104 + EXPECT_EQ((inst.log_begin() + 25)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; 105 + 106 + // Verify the data is what we expected 107 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback; 108 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 109 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 110 + 111 + // Re-init and re-read, verifying the reload capability 112 + EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; 113 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 114 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 115 + } 116 + 117 + /** 118 + * This test verifies multibyte readback gets canceled with an out-of-bounds address. 119 + */ 120 + TEST_F(WearLeveling2Byte, PlaybackReadbackMultibyte_OOB) { 121 + auto& inst = MockBackingStore::Instance(); 122 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 123 + 124 + // Invalid FNV1a_64 hash 125 + (logstart + 0)->set(0); 126 + (logstart + 1)->set(0); 127 + (logstart + 2)->set(0); 128 + (logstart + 3)->set(0); 129 + 130 + // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 131 + auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 132 + entry0.raw8[3] = 0x11; 133 + entry0.raw8[4] = 0x12; 134 + (logstart + 4)->set(~entry0.raw16[0]); 135 + (logstart + 5)->set(~entry0.raw16[1]); 136 + (logstart + 6)->set(~entry0.raw16[2]); 137 + 138 + // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) 139 + auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); 140 + entry1.raw8[3] = 0x13; 141 + entry1.raw8[4] = 0x14; 142 + (logstart + 7)->set(~entry1.raw16[0]); 143 + (logstart + 8)->set(~entry1.raw16[1]); 144 + (logstart + 9)->set(~entry1.raw16[2]); 145 + 146 + // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x01 147 + auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 148 + entry2.raw8[3] = 0x15; 149 + entry2.raw8[4] = 0x16; 150 + (logstart + 10)->set(~entry2.raw16[0]); 151 + (logstart + 11)->set(~entry2.raw16[1]); 152 + (logstart + 12)->set(~entry2.raw16[2]); 153 + 154 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 155 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; 156 + EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; 157 + 158 + uint8_t buf[2]; 159 + wear_leveling_read(0x01, buf, sizeof(buf)); 160 + EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; 161 + EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; 162 + } 163 + 164 + /** 165 + * This test verifies optimized 64 readback gets canceled with an out-of-bounds address. 166 + */ 167 + TEST_F(WearLeveling2Byte, PlaybackReadbackOptimized64_OOB) { 168 + auto& inst = MockBackingStore::Instance(); 169 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 170 + 171 + // Invalid FNV1a_64 hash 172 + (logstart + 0)->set(0); 173 + (logstart + 1)->set(0); 174 + (logstart + 2)->set(0); 175 + (logstart + 3)->set(0); 176 + 177 + // Set up a 1-byte logical write of 0x11 at logical offset 0x01 178 + auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); 179 + (logstart + 4)->set(~entry0.raw16[0]); 180 + 181 + // Set up a 1-byte logical write of 0x11 at logical offset 0x30 (out of bounds) 182 + auto entry1 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x30, 0x11); 183 + (logstart + 5)->set(~entry1.raw16[0]); 184 + 185 + // Set up a 1-byte logical write of 0x12 at logical offset 0x01 186 + auto entry2 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x12); 187 + (logstart + 6)->set(~entry2.raw16[0]); 188 + 189 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 190 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; 191 + EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; 192 + uint8_t tmp; 193 + wear_leveling_read(0x01, &tmp, sizeof(tmp)); 194 + EXPECT_EQ(tmp, 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; 195 + } 196 + 197 + /** 198 + * This test verifies word 0/1 readback gets canceled with an out-of-bounds address. 199 + */ 200 + TEST_F(WearLeveling2Byte, PlaybackReadbackWord01_OOB) { 201 + auto& inst = MockBackingStore::Instance(); 202 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 203 + 204 + // Invalid FNV1a_64 hash 205 + (logstart + 0)->set(0); 206 + (logstart + 1)->set(0); 207 + (logstart + 2)->set(0); 208 + (logstart + 3)->set(0); 209 + 210 + // Set up a 1-byte logical write of 1 at logical offset 0x02 211 + auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1); 212 + (logstart + 4)->set(~entry0.raw16[0]); 213 + 214 + // Set up a 1-byte logical write of 1 at logical offset 0x1000 (out of bounds) 215 + auto entry1 = LOG_ENTRY_MAKE_WORD_01(0x1000, 1); 216 + (logstart + 5)->set(~entry1.raw16[0]); 217 + 218 + // Set up a 1-byte logical write of 0 at logical offset 0x02 219 + auto entry2 = LOG_ENTRY_MAKE_WORD_01(0x02, 0); 220 + (logstart + 6)->set(~entry2.raw16[0]); 221 + 222 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 223 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; 224 + EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; 225 + uint8_t tmp; 226 + wear_leveling_read(0x02, &tmp, sizeof(tmp)); 227 + EXPECT_EQ(tmp, 1) << "Readback should have maintained the previous pre-failure value from the write log"; 228 + }
+295
quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <numeric> 4 + #include "gtest/gtest.h" 5 + #include "gmock/gmock.h" 6 + #include "backing_mocks.hpp" 7 + 8 + class WearLeveling2ByteOptimizedWrites : public ::testing::Test { 9 + protected: 10 + void SetUp() override { 11 + MockBackingStore::Instance().reset_instance(); 12 + wear_leveling_init(); 13 + } 14 + }; 15 + 16 + static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data; 17 + 18 + static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { 19 + memcpy(&verify_data[address], value, length); 20 + return wear_leveling_write(address, value, length); 21 + } 22 + 23 + /** 24 + * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. 25 + */ 26 + TEST_F(WearLeveling2ByteOptimizedWrites, MultibyteBackingStoreWriteCounts) { 27 + auto& inst = MockBackingStore::Instance(); 28 + 29 + for (std::size_t length = 1; length <= 5; ++length) { 30 + // Clear things out 31 + std::fill(verify_data.begin(), verify_data.end(), 0); 32 + inst.reset_instance(); 33 + wear_leveling_init(); 34 + 35 + // Generate a test block of data 36 + std::vector<std::uint8_t> testvalue(length); 37 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 38 + 39 + // Write the data 40 + EXPECT_EQ(test_write(2000, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 41 + 42 + std::size_t expected; 43 + if (length > 3) { 44 + expected = 4; 45 + } else if (length > 1) { 46 + expected = 3; 47 + } else { 48 + expected = 2; 49 + } 50 + 51 + // Check that we got the expected number of write log entries 52 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected); 53 + } 54 + } 55 + 56 + /** 57 + * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to even addresses only. 58 + * - Addresses <16384 will result in a single optimised backing write 59 + * - Higher addresses will result in a multibyte write of 3 backing writes 60 + */ 61 + TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToEvenAddresses) { 62 + auto& inst = MockBackingStore::Instance(); 63 + 64 + // Only attempt writes for each address up to a limit that would NOT force a consolidated data write. 65 + std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1 66 + std::size_t final_address; 67 + for (uint32_t address = 0; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) { 68 + // Clear things out 69 + std::fill(verify_data.begin(), verify_data.end(), 0); 70 + inst.reset_instance(); 71 + wear_leveling_init(); 72 + 73 + // Loop through all the addresses in this range 74 + std::size_t expected = 0; 75 + for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) { 76 + // If we're about to exceed the limit of the logical store, skip the writes 77 + if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) { 78 + break; 79 + } 80 + 81 + // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs. 82 + uint16_t val = 1; 83 + EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 84 + val = 0; 85 + EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 86 + 87 + std::size_t backing_store_writes_expected = 0; 88 + if (address + offset < 16384) { 89 + // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes 90 + backing_store_writes_expected = 2; 91 + } else { 92 + // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data 93 + backing_store_writes_expected = 6; 94 + } 95 + 96 + // Keep track of the total number of expected writes to the backing store 97 + expected += backing_store_writes_expected; 98 + 99 + // Verify we're at the correct number of writes 100 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset); 101 + 102 + // Verify that the write log entries we expect are actually present 103 + std::size_t write_index = expected - backing_store_writes_expected; 104 + auto write_iter = inst.log_begin() + write_index; 105 + write_log_entry_t e; 106 + if (address + offset < 16384) { 107 + // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes 108 + for (std::size_t i = 0; i < 2; ++i) { 109 + e.raw16[0] = write_iter->value; 110 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_WORD_01) << "Invalid write log entry type at " << (address + offset); 111 + ++write_iter; 112 + } 113 + } else { 114 + // Multibyte write 115 + e.raw16[0] = write_iter->value; 116 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type at " << (address + offset); 117 + EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length at " << (address + offset); 118 + ++write_iter; 119 + } 120 + 121 + // Keep track of the final address written, so we can verify the entire logical range was handled 122 + final_address = address + offset; 123 + } 124 + 125 + // Verify the number of writes that occurred to the backing store 126 + size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end()); 127 + EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address; 128 + 129 + // Verify the data is what we expected 130 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback; 131 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 132 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; 133 + 134 + // Re-init and re-read, testing the reload capability 135 + EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; 136 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 137 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; 138 + } 139 + 140 + // Verify the full range of the logical area got written 141 + EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 2) << "Invalid final write address"; 142 + } 143 + 144 + /** 145 + * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to odd addresses only. 146 + * - Addresses <63 will result in 2 optimised backing writes 147 + * - Address 63 results in a single optimised backing write for the first logical byte, and a multibyte write of 2 backing writes for the second logical byte 148 + * - Higher addresses will result in a multibyte write of 3 backing writes 149 + */ 150 + TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToOddAddresses) { 151 + auto& inst = MockBackingStore::Instance(); 152 + 153 + // Only attempt writes for each address up to a limit that would NOT force a consolidated data write. 154 + std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1 155 + std::size_t final_address; 156 + for (uint32_t address = 1; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) { 157 + // Clear things out 158 + std::fill(verify_data.begin(), verify_data.end(), 0); 159 + inst.reset_instance(); 160 + wear_leveling_init(); 161 + 162 + // Loop through all the addresses in this range 163 + std::size_t expected = 0; 164 + for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) { 165 + // If we're about to exceed the limit of the logical store, skip the writes 166 + if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) { 167 + break; 168 + } 169 + 170 + // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs. 171 + uint16_t val = 1; 172 + EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 173 + val = 0; 174 + EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 175 + 176 + std::size_t backing_store_writes_expected = 0; 177 + if (address + offset < 63) { 178 + // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes 179 + backing_store_writes_expected = 4; 180 + } else if (address + offset == 63) { 181 + // If we're straddling the boundary for optimised bytes (addr==64), then the first logical byte is written using the optimised write (1 backing 182 + // store write), and the second logical byte uses a multibyte write (2 backing store writes) 183 + backing_store_writes_expected = 2 // First logical bytes written using optimised log entries 184 + + 4; // Second logical bytes written using multibyte log entries 185 + } else { 186 + // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data 187 + backing_store_writes_expected = 6; 188 + } 189 + 190 + // Keep track of the total number of expected writes to the backing store 191 + expected += backing_store_writes_expected; 192 + 193 + // Verify we're at the correct number of writes 194 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset); 195 + 196 + // Verify that the write log entries we expect are actually present 197 + std::size_t write_index = expected - backing_store_writes_expected; 198 + auto write_iter = inst.log_begin() + write_index; 199 + write_log_entry_t e; 200 + if (address + offset < 63) { 201 + // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes 202 + for (std::size_t i = 0; i < 4; ++i) { 203 + e.raw16[0] = write_iter->value; 204 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; 205 + ++write_iter; 206 + } 207 + } else if (address + offset == 63) { 208 + // First log entry is the 64-addr optimised one 209 + e.raw16[0] = write_iter->value; 210 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; 211 + ++write_iter; 212 + 213 + // Second log entry is the multibyte entry for the second logical byte 214 + e.raw16[0] = write_iter->value; 215 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; 216 + EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 1) << "Invalid write log entry length"; 217 + ++write_iter; 218 + } else { 219 + // Multibyte write 220 + e.raw16[0] = write_iter->value; 221 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; 222 + EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length"; 223 + ++write_iter; 224 + } 225 + 226 + // Keep track of the final address written, so we can verify the entire logical range was handled 227 + final_address = address + offset; 228 + } 229 + 230 + // Verify the number of writes that occurred to the backing store 231 + size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end()); 232 + EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address; 233 + 234 + // Verify the data is what we expected 235 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback; 236 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 237 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; 238 + 239 + // Re-init and re-read, testing the reload capability 240 + EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; 241 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 242 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; 243 + } 244 + 245 + // Verify the full range of the logical area got written 246 + EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 3) << "Invalid final write address"; 247 + } 248 + 249 + /** 250 + * This test verifies readback after playback of the write log, simulating power loss and reboot. 251 + */ 252 + TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackOptimized64_Success) { 253 + auto& inst = MockBackingStore::Instance(); 254 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 255 + 256 + // Invalid FNV1a_64 hash 257 + (logstart + 0)->set(0); 258 + (logstart + 1)->set(0); 259 + (logstart + 2)->set(0); 260 + (logstart + 3)->set(0); 261 + 262 + // Set up a 1-byte logical write of 0x11 at logical offset 0x01 263 + auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); 264 + (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result 265 + 266 + wear_leveling_init(); 267 + uint8_t tmp; 268 + 269 + wear_leveling_read(0x01, &tmp, sizeof(tmp)); 270 + EXPECT_EQ(tmp, 0x11) << "Failed to read back the seeded data"; 271 + } 272 + 273 + /** 274 + * This test verifies readback after playback of the write log, simulating power loss and reboot. 275 + */ 276 + TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackWord01_Success) { 277 + auto& inst = MockBackingStore::Instance(); 278 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 279 + 280 + // Invalid FNV1a_64 hash 281 + (logstart + 0)->set(0); 282 + (logstart + 1)->set(0); 283 + (logstart + 2)->set(0); 284 + (logstart + 3)->set(0); 285 + 286 + // Set up a 1-byte logical write of 1 at logical offset 0x02 287 + auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1); 288 + (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result 289 + 290 + wear_leveling_init(); 291 + uint8_t tmp; 292 + 293 + wear_leveling_read(0x02, &tmp, sizeof(tmp)); 294 + EXPECT_EQ(tmp, 1) << "Failed to read back the seeded data"; 295 + }
+193
quantum/wear_leveling/tests/wear_leveling_4byte.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <numeric> 4 + #include "gtest/gtest.h" 5 + #include "gmock/gmock.h" 6 + #include "backing_mocks.hpp" 7 + 8 + class WearLeveling4Byte : public ::testing::Test { 9 + protected: 10 + void SetUp() override { 11 + MockBackingStore::Instance().reset_instance(); 12 + wear_leveling_init(); 13 + } 14 + }; 15 + 16 + static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data; 17 + 18 + static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { 19 + memcpy(&verify_data[address], value, length); 20 + return wear_leveling_write(address, value, length); 21 + } 22 + 23 + /** 24 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. 25 + */ 26 + TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash) { 27 + auto& inst = MockBackingStore::Instance(); 28 + uint8_t test_value = 0x15; 29 + test_write(0x02, &test_value, sizeof(test_value)); 30 + EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 31 + } 32 + 33 + /** 34 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. 35 + */ 36 + TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash_AfterErase) { 37 + auto& inst = MockBackingStore::Instance(); 38 + uint8_t test_value = 0x15; 39 + wear_leveling_erase(); 40 + test_write(0x02, &test_value, sizeof(test_value)); 41 + EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 42 + } 43 + 44 + /** 45 + * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. 46 + */ 47 + TEST_F(WearLeveling4Byte, MultibyteBackingStoreWriteCounts) { 48 + auto& inst = MockBackingStore::Instance(); 49 + 50 + for (std::size_t length = 1; length <= 5; ++length) { 51 + // Clear things out 52 + std::fill(verify_data.begin(), verify_data.end(), 0); 53 + inst.reset_instance(); 54 + wear_leveling_init(); 55 + 56 + // Generate a test block of data 57 + std::vector<std::uint8_t> testvalue(length); 58 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 59 + 60 + // Write the data 61 + EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 62 + 63 + std::size_t expected; 64 + if (length > 1) { 65 + expected = 2; 66 + } else { 67 + expected = 1; 68 + } 69 + 70 + // Check that we got the expected number of write log entries 71 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected); 72 + } 73 + } 74 + 75 + /** 76 + * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the 77 + * base logical area. 78 + */ 79 + TEST_F(WearLeveling4Byte, ConsolidationOverflow) { 80 + auto& inst = MockBackingStore::Instance(); 81 + 82 + // Generate a test block of data 83 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue; 84 + 85 + // Write the data 86 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 87 + EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; 88 + uint8_t dummy = 0x40; 89 + EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; 90 + 91 + // Expected log: 92 + // [0,1]: multibyte, 5 bytes, backing address 0x18, logical address 0x00 93 + // [2,3]: multibyte, 5 bytes, backing address 0x20, logical address 0x05 94 + // [4,5]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation 95 + // [6]: erase 96 + // [7,8]: consolidated data, backing address 0x00, logical address 0x00 97 + // [9,10]: consolidated data, backing address 0x08, logical address 0x08 98 + // [11,12]: FNV1a_64 result, backing address 0x10 99 + // [13]: multibyte, 1 byte, backing address 0x18, logical address 0x04 100 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 14); 101 + 102 + // Verify the backing store writes for the write log 103 + std::size_t index; 104 + write_log_entry_t e; 105 + for (index = 0; index < 6; ++index) { 106 + auto write_iter = inst.log_begin() + index; 107 + EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; 108 + 109 + // If this is the backing store write that contains the metadata, verify it 110 + if (index % 2 == 0) { 111 + write_log_entry_t e; 112 + e.raw64 = write_iter->value; 113 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; 114 + } 115 + } 116 + 117 + // Verify the backing store erase 118 + { 119 + index = 6; 120 + auto write_iter = inst.log_begin() + index; 121 + e.raw64 = write_iter->value; 122 + EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; 123 + } 124 + 125 + // Verify the backing store writes for consolidation 126 + for (index = 7; index < 11; ++index) { 127 + auto write_iter = inst.log_begin() + index; 128 + EXPECT_EQ(write_iter->address, (index - 7) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; 129 + } 130 + 131 + // Verify the FNV1a_64 write 132 + { 133 + EXPECT_EQ((inst.log_begin() + 11)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; 134 + e.raw32[0] = (inst.log_begin() + 11)->value; 135 + e.raw32[1] = (inst.log_begin() + 12)->value; 136 + EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current 137 + } 138 + 139 + // Verify the final write 140 + EXPECT_EQ((inst.log_begin() + 13)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; 141 + 142 + // Verify the data is what we expected 143 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback; 144 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 145 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 146 + 147 + // Re-init and re-read, verifying the reload capability 148 + EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; 149 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 150 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 151 + } 152 + 153 + /** 154 + * This test verifies multibyte readback gets canceled with an out-of-bounds address. 155 + */ 156 + TEST_F(WearLeveling4Byte, PlaybackReadbackMultibyte_OOB) { 157 + auto& inst = MockBackingStore::Instance(); 158 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 159 + 160 + // Invalid FNV1a_64 hash 161 + (logstart + 0)->set(0); 162 + (logstart + 1)->set(0); 163 + 164 + // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 165 + auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 166 + entry0.raw8[3] = 0x11; 167 + entry0.raw8[4] = 0x12; 168 + (logstart + 2)->set(~entry0.raw32[0]); 169 + (logstart + 3)->set(~entry0.raw32[1]); 170 + 171 + // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) 172 + auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); 173 + entry1.raw8[3] = 0x13; 174 + entry1.raw8[4] = 0x14; 175 + (logstart + 4)->set(~entry1.raw32[0]); 176 + (logstart + 5)->set(~entry1.raw32[1]); 177 + 178 + // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10 179 + auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 180 + entry2.raw8[3] = 0x15; 181 + entry2.raw8[4] = 0x16; 182 + (logstart + 6)->set(~entry2.raw32[0]); 183 + (logstart + 7)->set(~entry2.raw32[1]); 184 + 185 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 186 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; 187 + EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; 188 + 189 + uint8_t buf[2]; 190 + wear_leveling_read(0x01, buf, sizeof(buf)); 191 + EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; 192 + EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; 193 + }
+178
quantum/wear_leveling/tests/wear_leveling_8byte.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <numeric> 4 + #include "gtest/gtest.h" 5 + #include "gmock/gmock.h" 6 + #include "backing_mocks.hpp" 7 + 8 + class WearLeveling8Byte : public ::testing::Test { 9 + protected: 10 + void SetUp() override { 11 + MockBackingStore::Instance().reset_instance(); 12 + wear_leveling_init(); 13 + } 14 + }; 15 + 16 + static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data; 17 + 18 + static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { 19 + memcpy(&verify_data[address], value, length); 20 + return wear_leveling_write(address, value, length); 21 + } 22 + 23 + /** 24 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. 25 + */ 26 + TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash) { 27 + auto& inst = MockBackingStore::Instance(); 28 + uint8_t test_value = 0x15; 29 + test_write(0x02, &test_value, sizeof(test_value)); 30 + EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 31 + } 32 + 33 + /** 34 + * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. 35 + */ 36 + TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash_AfterErase) { 37 + auto& inst = MockBackingStore::Instance(); 38 + uint8_t test_value = 0x15; 39 + wear_leveling_erase(); 40 + test_write(0x02, &test_value, sizeof(test_value)); 41 + EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; 42 + } 43 + 44 + /** 45 + * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. 46 + */ 47 + TEST_F(WearLeveling8Byte, MultibyteBackingStoreWriteCounts) { 48 + auto& inst = MockBackingStore::Instance(); 49 + 50 + for (std::size_t length = 1; length <= 5; ++length) { 51 + // Clear things out 52 + std::fill(verify_data.begin(), verify_data.end(), 0); 53 + inst.reset_instance(); 54 + wear_leveling_init(); 55 + 56 + // Generate a test block of data 57 + std::vector<std::uint8_t> testvalue(length); 58 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 59 + 60 + // Write the data 61 + EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; 62 + 63 + // Check that we got the expected number of write log entries 64 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 1); 65 + } 66 + } 67 + 68 + /** 69 + * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the 70 + * base logical area. 71 + */ 72 + TEST_F(WearLeveling8Byte, ConsolidationOverflow) { 73 + auto& inst = MockBackingStore::Instance(); 74 + 75 + // Generate a test block of data 76 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue; 77 + 78 + // Write the data 79 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 80 + EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; 81 + uint8_t dummy = 0x40; 82 + EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; 83 + 84 + // Expected log: 85 + // [0]: multibyte, 5 bytes, backing address 0x18, logical address 0x00 86 + // [1]: multibyte, 5 bytes, backing address 0x20, logical address 0x05 87 + // [2]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation 88 + // [3]: erase 89 + // [4]: consolidated data, backing address 0x00, logical address 0x00 90 + // [5]: consolidated data, backing address 0x08, logical address 0x08 91 + // [6]: FNV1a_64 result, backing address 0x10 92 + // [7]: multibyte, 1 byte, backing address 0x18, logical address 0x04 93 + EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 8); 94 + 95 + // Verify the backing store writes for the write log 96 + std::size_t index; 97 + write_log_entry_t e; 98 + for (index = 0; index < 3; ++index) { 99 + auto write_iter = inst.log_begin() + index; 100 + EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; 101 + 102 + write_log_entry_t e; 103 + e.raw64 = write_iter->value; 104 + EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; 105 + } 106 + 107 + // Verify the backing store erase 108 + { 109 + index = 3; 110 + auto write_iter = inst.log_begin() + index; 111 + e.raw64 = write_iter->value; 112 + EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; 113 + } 114 + 115 + // Verify the backing store writes for consolidation 116 + for (index = 4; index < 6; ++index) { 117 + auto write_iter = inst.log_begin() + index; 118 + EXPECT_EQ(write_iter->address, (index - 4) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; 119 + } 120 + 121 + // Verify the FNV1a_64 write 122 + { 123 + EXPECT_EQ((inst.log_begin() + 6)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; 124 + e.raw64 = (inst.log_begin() + 6)->value; 125 + EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current 126 + } 127 + 128 + // Verify the final write 129 + EXPECT_EQ((inst.log_begin() + 7)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; 130 + 131 + // Verify the data is what we expected 132 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback; 133 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 134 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 135 + 136 + // Re-init and re-read, verifying the reload capability 137 + EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; 138 + EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; 139 + EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; 140 + } 141 + 142 + /** 143 + * This test verifies multibyte readback gets canceled with an out-of-bounds address. 144 + */ 145 + TEST_F(WearLeveling8Byte, PlaybackReadbackMultibyte_OOB) { 146 + auto& inst = MockBackingStore::Instance(); 147 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 148 + 149 + // Invalid FNV1a_64 hash 150 + (logstart + 0)->set(0); 151 + 152 + // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 153 + auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 154 + entry0.raw8[3] = 0x11; 155 + entry0.raw8[4] = 0x12; 156 + (logstart + 1)->set(~entry0.raw64); 157 + 158 + // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) 159 + auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); 160 + entry1.raw8[3] = 0x13; 161 + entry1.raw8[4] = 0x14; 162 + (logstart + 2)->set(~entry1.raw64); 163 + 164 + // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10 165 + auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); 166 + entry2.raw8[3] = 0x15; 167 + entry2.raw8[4] = 0x16; 168 + (logstart + 3)->set(~entry2.raw64); 169 + 170 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 171 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; 172 + EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; 173 + 174 + uint8_t buf[2]; 175 + wear_leveling_read(0x01, buf, sizeof(buf)); 176 + EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; 177 + EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; 178 + }
+204
quantum/wear_leveling/tests/wear_leveling_general.cpp
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <numeric> 4 + #include "gtest/gtest.h" 5 + #include "gmock/gmock.h" 6 + #include "backing_mocks.hpp" 7 + 8 + class WearLevelingGeneral : public ::testing::Test { 9 + protected: 10 + void SetUp() override { 11 + MockBackingStore::Instance().reset_instance(); 12 + wear_leveling_init(); 13 + } 14 + }; 15 + 16 + /** 17 + * This test verifies that even if there is consolidated data present, if the checksum doesn't match then the cache is zero'd after reading the consolidated area, but before write log is played back. 18 + */ 19 + TEST_F(WearLevelingGeneral, InvalidChecksum_ConsolidatedDataIgnored) { 20 + auto& inst = MockBackingStore::Instance(); 21 + auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); 22 + 23 + // Generate a test block of data 24 + std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue; 25 + std::iota(testvalue.begin(), testvalue.end(), 0x20); 26 + 27 + // Write the data 28 + EXPECT_EQ(wear_leveling_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; 29 + 30 + // Invalidate the checksum 31 + (logstart + 0)->erase(); 32 + (logstart + 1)->erase(); 33 + (logstart + 2)->erase(); 34 + (logstart + 3)->erase(); 35 + 36 + // Set up a 1-byte logical write of [0x11] at logical offset 0x01 37 + auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); 38 + (logstart + 4)->set(~entry0.raw16[0]); 39 + 40 + // Re-init 41 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_SUCCESS) << "Init returned incorrect status"; 42 + EXPECT_EQ(wear_leveling_read(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Failed to read"; 43 + for (int i = 0; i < WEAR_LEVELING_LOGICAL_SIZE; ++i) { 44 + EXPECT_EQ(testvalue[i], i == 0x01 ? 0x11 : 0x00) << "Invalid readback"; 45 + } 46 + } 47 + 48 + /** 49 + * This test verifies that writing the same data multiple times does not result in subsequent writes to the backing store. 50 + */ 51 + TEST_F(WearLevelingGeneral, SameValue_SingleBackingWrite) { 52 + auto& inst = MockBackingStore::Instance(); 53 + 54 + uint8_t test_val = 0x14; 55 + EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "First overall write operation should have succeeded"; 56 + 57 + uint64_t invoke_count = inst.unlock_invoke_count(); 58 + uint64_t erase_count = inst.erase_invoke_count(); 59 + uint64_t write_count = inst.write_invoke_count(); 60 + uint64_t lock_count = inst.lock_invoke_count(); 61 + 62 + for (int i = 0; i < 10; ++i) { 63 + EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Subsequent overall write operation should have succeeded"; 64 + 65 + EXPECT_EQ(inst.unlock_invoke_count(), invoke_count) << "Unlock count should match"; 66 + EXPECT_EQ(inst.erase_invoke_count(), erase_count) << "Erase count should match"; 67 + EXPECT_EQ(inst.write_invoke_count(), write_count) << "Write count should match"; 68 + EXPECT_EQ(inst.lock_invoke_count(), lock_count) << "Lock count should match"; 69 + } 70 + } 71 + 72 + /** 73 + * This test verifies that no other invocations occur if `backing_store_init()` fails. 74 + */ 75 + TEST_F(WearLevelingGeneral, InitFailure) { 76 + auto& inst = MockBackingStore::Instance(); 77 + inst.reset_instance(); // make sure the counters are all zero 78 + inst.set_init_callback([](std::uint64_t count) { return false; }); 79 + 80 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; 81 + EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Init should have failed"; 82 + EXPECT_EQ(inst.erasure_count(), 0) << "Invalid final erase count"; 83 + 84 + EXPECT_EQ(inst.init_invoke_count(), 1) << "Init should have been invoked once"; 85 + EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; 86 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 87 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 88 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 89 + } 90 + 91 + /** 92 + * This test verifies that no invocations occur if the supplied address is out of range while writing. 93 + */ 94 + TEST_F(WearLevelingGeneral, WriteFailure_OOB) { 95 + auto& inst = MockBackingStore::Instance(); 96 + 97 + uint8_t test_val = 0x14; 98 + EXPECT_EQ(wear_leveling_write(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; 99 + 100 + EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; 101 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 102 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 103 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 104 + } 105 + 106 + /** 107 + * This test verifies that a single write occurs if the supplied address and data length hits the edge of the logical area. 108 + */ 109 + TEST_F(WearLevelingGeneral, WriteSuccess_BoundaryOK) { 110 + auto& inst = MockBackingStore::Instance(); 111 + 112 + uint16_t test_val = 0x14; 113 + EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val), &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Overall write operation should have succeeded"; 114 + 115 + EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; 116 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 117 + EXPECT_EQ(inst.write_invoke_count(), 2) << "Write should have been invoked twice"; 118 + EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once"; 119 + } 120 + 121 + /** 122 + * This test verifies that no invocations occur if the supplied address and length would generate writes outside the logical range. 123 + */ 124 + TEST_F(WearLevelingGeneral, WriteFailure_BoundaryOverflow) { 125 + auto& inst = MockBackingStore::Instance(); 126 + 127 + uint16_t test_val = 0x14; 128 + EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val) + 1, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; 129 + 130 + EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; 131 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 132 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 133 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 134 + } 135 + 136 + /** 137 + * This test verifies that no invocations occur if the supplied address is out of range while reading. 138 + */ 139 + TEST_F(WearLevelingGeneral, ReadFailure_OOB) { 140 + auto& inst = MockBackingStore::Instance(); 141 + 142 + uint8_t test_val = 0; 143 + EXPECT_EQ(wear_leveling_read(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall read operation should have failed"; 144 + 145 + EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; 146 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 147 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 148 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 149 + } 150 + 151 + /** 152 + * This test verifies that no write invocations occur if `backing_store_unlock()` fails. 153 + */ 154 + TEST_F(WearLevelingGeneral, UnlockFailure_NoWrite) { 155 + auto& inst = MockBackingStore::Instance(); 156 + inst.set_unlock_callback([](std::uint64_t count) { return false; }); 157 + 158 + uint8_t test_val = 0x14; 159 + EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; 160 + 161 + EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; 162 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 163 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 164 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 165 + 166 + test_val = 0; 167 + wear_leveling_read(0x04, &test_val, sizeof(test_val)); 168 + EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure"; 169 + } 170 + 171 + /** 172 + * This test verifies that no erase invocations occur if `backing_store_unlock()` fails. 173 + */ 174 + TEST_F(WearLevelingGeneral, UnlockFailure_NoErase) { 175 + auto& inst = MockBackingStore::Instance(); 176 + inst.set_unlock_callback([](std::uint64_t count) { return false; }); 177 + 178 + EXPECT_EQ(wear_leveling_erase(), WEAR_LEVELING_FAILED) << "Overall erase operation should have failed"; 179 + 180 + EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; 181 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 182 + EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; 183 + EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; 184 + } 185 + 186 + /** 187 + * This test verifies that only one write invocation occurs if `backing_store_write()` fails. 188 + */ 189 + TEST_F(WearLevelingGeneral, WriteFailure_NoSubsequentWrites) { 190 + auto& inst = MockBackingStore::Instance(); 191 + inst.set_write_callback([](std::uint64_t count, std::uint32_t address) { return false; }); 192 + 193 + uint8_t test_val = 0x14; 194 + EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; 195 + 196 + EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; 197 + EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; 198 + EXPECT_EQ(inst.write_invoke_count(), 1) << "Write should have been invoked once"; 199 + EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once"; 200 + 201 + test_val = 0; 202 + wear_leveling_read(0x04, &test_val, sizeof(test_val)); 203 + EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure"; 204 + }
+779
quantum/wear_leveling/wear_leveling.c
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #include <stdbool.h> 4 + #include "fnv.h" 5 + #include "wear_leveling.h" 6 + #include "wear_leveling_internal.h" 7 + 8 + /* 9 + This wear leveling algorithm is adapted from algorithms from previous 10 + implementations in QMK, namely: 11 + - Artur F. (http://engsta.com/stm32-flash-memory-eeprom-emulator/) 12 + - Yiancar -- QMK's base implementation for STM32F303 13 + - Ilya Zhuravlev -- initial wear leveling algorithm 14 + - Don Kjer -- increased flash density algorithm 15 + - Nick Brassel (@tzarc) -- decoupled for use on other peripherals 16 + 17 + At this layer, it is assumed that any reads/writes from the backing store 18 + have a "reset state" after erasure of zero. 19 + It is up to the backing store to perform translation of values, such as 20 + taking the complement in order to deal with flash memory's reset value. 21 + 22 + Terminology: 23 + 24 + - Backing store: this is the storage area used by the wear leveling 25 + algorithm. 26 + 27 + - Backing size: this is the amount of storage provided by the backing 28 + store for use by the wear leveling algorithm. 29 + 30 + - Backing write size: this is the minimum number of bytes the backing 31 + store can write in a single operation. 32 + 33 + - Logical data: this is the externally-visible "emulated EEPROM" that 34 + external subsystems "see" when performing reads/writes. 35 + 36 + - Logical size: this is the amount of storage available for use 37 + externally. Effectively, the "size of the EEPROM". 38 + 39 + - Write log: this is a section of the backing store used to keep track 40 + of modifications without overwriting existing data. This log is 41 + "played back" on startup such that any subsequent reads are capable 42 + of returning the latest data. 43 + 44 + - Consolidated data: this is a section of the backing store reserved for 45 + use for the latest copy of logical data. This is only ever written 46 + when the write log is full -- the latest values for the logical data 47 + are written here and the write log is cleared. 48 + 49 + Configurables: 50 + 51 + - BACKING_STORE_WRITE_SIZE: The number of bytes requires for a write 52 + operation. This is defined by the capabilities of the backing store. 53 + 54 + - WEAR_LEVELING_BACKING_SIZE: The number of bytes provided by the 55 + backing store for use by the wear leveling algorithm. This is 56 + defined by the capabilities of the backing store. This value must 57 + also be at least twice the size of the logical size, as well as a 58 + multiple of the logical size. 59 + 60 + - WEAR_LEVELING_LOGICAL_SIZE: The number of bytes externally visible 61 + to other subsystems performing reads/writes. This must be a multiple 62 + of the write size. 63 + 64 + General algorithm: 65 + 66 + During initialization: 67 + * The contents of the consolidated data section are read into cache. 68 + * The contents of the write log are "played back" and update the 69 + cache accordingly. 70 + 71 + During reads: 72 + * Logical data is served from the cache. 73 + 74 + During writes: 75 + * The cache is updated with the new data. 76 + * A new write log entry is appended to the log. 77 + * If the log's full, data is consolidated and the write log cleared. 78 + 79 + Write log structure: 80 + 81 + The first 8 bytes of the write log are a FNV1a_64 hash of the contents 82 + of the consolidated data area, in an attempt to detect and guard against 83 + any data corruption. 84 + 85 + The write log follows the hash: 86 + 87 + Given that the algorithm needs to cater for 2-, 4-, and 8-byte writes, 88 + a variable-length write log entry is used such that the minimal amount 89 + of storage is used based off the backing store write size. 90 + 91 + Firstly, an empty log entry is expected to be all zeros. If the backing 92 + store uses 0xFF for cleared bytes, it should return the complement, such 93 + that this wear-leveling algorithm "receives" zeros. 94 + 95 + For multi-byte writes, up to 8 bytes will be used for each log entry, 96 + depending on the size of backing store writes: 97 + 98 + ╔ Multi-byte Log Entry (2, 4-byte) ═╗ 99 + ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║ 100 + ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║ 101 + ║ LenAdd║ Address║ Address║Value[0]║ 102 + ╚════════╩════════╩════════╩════════╝ 103 + ╔ Multi-byte Log Entry (2-byte) ══════════════════════╗ 104 + ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║BBBBBBBB║CCCCCCCC║ 105 + ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║ 106 + ║ LenAdd║ Address║ Address║Value[0]║Value[1]║Value[2]║ 107 + ╚════════╩════════╩════════╩════════╩════════╩════════╝ 108 + ╔ Multi-byte Log Entry (2, 4, 8-byte) ══════════════════════════════════╗ 109 + ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║BBBBBBBB║CCCCCCCC║DDDDDDDD║EEEEEEEE║ 110 + ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║ 111 + ║ LenAdd║ Address║ Address║Value[0]║Value[1]║Value[2]║Value[3]║Value[4]║ 112 + ╚════════╩════════╩════════╩════════╩════════╩════════╩════════╩════════╝ 113 + 114 + 19 bits are used for the address, which allows for a max logical size of 115 + 512kB. Up to 5 bytes can be included in a single log entry. 116 + 117 + For 2-byte backing store writes, the last two bytes are optional 118 + depending on the length of data to be written. Accordingly, either 3 119 + or 4 backing store write operations will occur. 120 + For 4-byte backing store writes, either one or two write operations 121 + occur, depending on the length. 122 + For 8-byte backing store writes, one write operation occur. 123 + 124 + 2-byte backing store optimizations: 125 + 126 + For single byte writes, addresses between 0...63 are encoded in a single 127 + backing store write operation. 4- and 8-byte backing stores do not have 128 + this optimization as it does not minimize the number of bytes written. 129 + 130 + ╔ Byte-Entry ════╗ 131 + ║01XXXXXXYYYYYYYY║ 132 + ║ └─┬──┘└──┬───┘║ 133 + ║ Address Value ║ 134 + ╚════════════════╝ 135 + 0 <= Address < 0x40 (64) 136 + 137 + A second optimization takes into account uint16_t writes of 0 or 1, 138 + specifically catering for KC_NO and KC_TRANSPARENT in the dynamic keymap 139 + subsystem. This is valid only for the first 16kB of logical data -- 140 + addresses outside this range will use the multi-byte encoding above. 141 + 142 + ╔ U16-Encoded 0 ═╗ 143 + ║100XXXXXXXXXXXXX║ 144 + ║ │└─────┬─────┘║ 145 + ║ │Address >> 1 ║ 146 + ║ └── Value: 0 ║ 147 + ╚════════════════╝ 148 + 0 <= Address <= 0x3FFE (16382) 149 + 150 + ╔ U16-Encoded 1 ═╗ 151 + ║101XXXXXXXXXXXXX║ 152 + ║ │└─────┬─────┘║ 153 + ║ │Address >> 1 ║ 154 + ║ └── Value: 1 ║ 155 + ╚════════════════╝ 156 + 0 <= Address <= 0x3FFE (16382) */ 157 + 158 + /** 159 + * Storage area for the wear-leveling cache. 160 + */ 161 + static struct __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) { 162 + __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) uint8_t cache[(WEAR_LEVELING_LOGICAL_SIZE)]; 163 + uint32_t write_address; 164 + bool unlocked; 165 + } wear_leveling; 166 + 167 + /** 168 + * Locking helper: status 169 + */ 170 + typedef enum backing_store_lock_status_t { STATUS_FAILURE = 0, STATUS_SUCCESS, STATUS_UNCHANGED } backing_store_lock_status_t; 171 + 172 + /** 173 + * Locking helper: unlock 174 + */ 175 + static inline backing_store_lock_status_t wear_leveling_unlock(void) { 176 + if (wear_leveling.unlocked) { 177 + return STATUS_UNCHANGED; 178 + } 179 + if (!backing_store_unlock()) { 180 + return STATUS_FAILURE; 181 + } 182 + wear_leveling.unlocked = true; 183 + return STATUS_SUCCESS; 184 + } 185 + 186 + /** 187 + * Locking helper: lock 188 + */ 189 + static inline backing_store_lock_status_t wear_leveling_lock(void) { 190 + if (!wear_leveling.unlocked) { 191 + return STATUS_UNCHANGED; 192 + } 193 + if (!backing_store_lock()) { 194 + return STATUS_FAILURE; 195 + } 196 + wear_leveling.unlocked = false; 197 + return STATUS_SUCCESS; 198 + } 199 + 200 + /** 201 + * Resets the cache, ensuring the write address is correctly initialised. 202 + */ 203 + static void wear_leveling_clear_cache(void) { 204 + memset(wear_leveling.cache, 0, (WEAR_LEVELING_LOGICAL_SIZE)); 205 + wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 is due to the FNV1a_64 of the consolidated buffer 206 + } 207 + 208 + /** 209 + * Reads the consolidated data from the backing store into the cache. 210 + * Does not consider the write log. 211 + */ 212 + static wear_leveling_status_t wear_leveling_read_consolidated(void) { 213 + wl_dprintf("Reading consolidated data\n"); 214 + 215 + wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; 216 + for (int address = 0; address < (WEAR_LEVELING_LOGICAL_SIZE); address += (BACKING_STORE_WRITE_SIZE)) { 217 + backing_store_int_t *const loc = (backing_store_int_t *)&wear_leveling.cache[address]; 218 + backing_store_int_t temp; 219 + bool ok = backing_store_read(address, &temp); 220 + if (!ok) { 221 + wl_dprintf("Failed to read from backing store\n"); 222 + status = WEAR_LEVELING_FAILED; 223 + break; 224 + } 225 + *loc = temp; 226 + } 227 + 228 + // Verify the FNV1a_64 result 229 + if (status != WEAR_LEVELING_FAILED) { 230 + uint64_t expected = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT); 231 + write_log_entry_t entry; 232 + #if BACKING_STORE_WRITE_SIZE == 2 233 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 0, &entry.raw16[0]); 234 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 2, &entry.raw16[1]); 235 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 4, &entry.raw16[2]); 236 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 6, &entry.raw16[3]); 237 + #elif BACKING_STORE_WRITE_SIZE == 4 238 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 0, &entry.raw32[0]); 239 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 4, &entry.raw32[1]); 240 + #elif BACKING_STORE_WRITE_SIZE == 8 241 + backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 0, &entry.raw64); 242 + #endif 243 + // If we have a mismatch, clear the cache but do not flag a failure, 244 + // which will cater for the completely clean MCU case. 245 + if (entry.raw64 != expected) { 246 + wear_leveling_clear_cache(); 247 + } 248 + } 249 + 250 + // If we failed for any reason, then clear the cache 251 + if (status == WEAR_LEVELING_FAILED) { 252 + wear_leveling_clear_cache(); 253 + } 254 + 255 + return status; 256 + } 257 + 258 + /** 259 + * Writes the current cache to consolidated data at the beginning of the backing store. 260 + * Does not clear the write log. 261 + */ 262 + static wear_leveling_status_t wear_leveling_write_consolidated(void) { 263 + wl_dprintf("Writing consolidated data\n"); 264 + 265 + wear_leveling_status_t status = WEAR_LEVELING_CONSOLIDATED; 266 + backing_store_lock_status_t lock_status = wear_leveling_unlock(); 267 + for (int address = 0; address < (WEAR_LEVELING_LOGICAL_SIZE); address += (BACKING_STORE_WRITE_SIZE)) { 268 + const backing_store_int_t value = *(backing_store_int_t *)&wear_leveling.cache[address]; 269 + backing_store_int_t temp; 270 + bool ok = backing_store_read(address, &temp); 271 + if (!ok) { 272 + wl_dprintf("Failed to read from backing store\n"); 273 + status = WEAR_LEVELING_FAILED; 274 + break; 275 + } 276 + if (temp != value) { 277 + ok = backing_store_write(address, value); 278 + if (!ok) { 279 + wl_dprintf("Failed to write to backing store\n"); 280 + status = WEAR_LEVELING_FAILED; 281 + break; 282 + } 283 + } 284 + } 285 + 286 + if (status != WEAR_LEVELING_FAILED) { 287 + // Write out the FNV1a_64 result of the consolidated data 288 + write_log_entry_t entry; 289 + entry.raw64 = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT); 290 + do { 291 + #if BACKING_STORE_WRITE_SIZE == 2 292 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 0, entry.raw16[0])) { 293 + status = WEAR_LEVELING_FAILED; 294 + break; 295 + } 296 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 2, entry.raw16[1])) { 297 + status = WEAR_LEVELING_FAILED; 298 + break; 299 + } 300 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 4, entry.raw16[2])) { 301 + status = WEAR_LEVELING_FAILED; 302 + break; 303 + } 304 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 6, entry.raw16[3])) { 305 + status = WEAR_LEVELING_FAILED; 306 + break; 307 + } 308 + #elif BACKING_STORE_WRITE_SIZE == 4 309 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 0, entry.raw32[0])) { 310 + status = WEAR_LEVELING_FAILED; 311 + break; 312 + } 313 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 4, entry.raw32[1])) { 314 + status = WEAR_LEVELING_FAILED; 315 + break; 316 + } 317 + #elif BACKING_STORE_WRITE_SIZE == 8 318 + if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE) + 0, entry.raw64)) { 319 + status = WEAR_LEVELING_FAILED; 320 + break; 321 + } 322 + #endif 323 + } while (0); 324 + } 325 + 326 + if (lock_status == STATUS_SUCCESS) { 327 + wear_leveling_lock(); 328 + } 329 + return status; 330 + } 331 + 332 + /** 333 + * Forces a write of the current cache. 334 + * Erases the backing store, including the write log. 335 + * During this operation, there is the potential for data loss if a power loss occurs. 336 + */ 337 + static wear_leveling_status_t wear_leveling_consolidate_force(void) { 338 + wl_dprintf("Erasing backing store\n"); 339 + 340 + // Erase the backing store. Expectation is that any un-written values that are read back after this call come back as zero. 341 + bool ok = backing_store_erase(); 342 + if (!ok) { 343 + wl_dprintf("Failed to erase backing store\n"); 344 + return WEAR_LEVELING_FAILED; 345 + } 346 + 347 + // Write the cache to the first section of the backing store. 348 + wear_leveling_status_t status = wear_leveling_write_consolidated(); 349 + if (status == WEAR_LEVELING_FAILED) { 350 + wl_dprintf("Failed to write consolidated data\n"); 351 + } 352 + 353 + // Next write of the log occurs after the consolidated values at the start of the backing store. 354 + wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area 355 + 356 + return status; 357 + } 358 + 359 + /** 360 + * Potential write of the current cache to the backing store. 361 + * Skipped if the current write log position is not at the end of the backing store. 362 + * During this operation, there is the potential for data loss if a power loss occurs. 363 + * 364 + * @return true if consolidation occurred 365 + */ 366 + static wear_leveling_status_t wear_leveling_consolidate_if_needed(void) { 367 + if (wear_leveling.write_address >= (WEAR_LEVELING_BACKING_SIZE)) { 368 + return wear_leveling_consolidate_force(); 369 + } 370 + 371 + return WEAR_LEVELING_SUCCESS; 372 + } 373 + 374 + /** 375 + * Appends the supplied fixed-width entry to the write log, optionally consolidating if the log is full. 376 + * 377 + * @return true if consolidation occurred 378 + */ 379 + static wear_leveling_status_t wear_leveling_append_raw(backing_store_int_t value) { 380 + bool ok = backing_store_write(wear_leveling.write_address, value); 381 + if (!ok) { 382 + wl_dprintf("Failed to write to backing store\n"); 383 + return WEAR_LEVELING_FAILED; 384 + } 385 + wear_leveling.write_address += (BACKING_STORE_WRITE_SIZE); 386 + return wear_leveling_consolidate_if_needed(); 387 + } 388 + 389 + /** 390 + * Handles writing multi_byte-encoded data to the backing store. 391 + * 392 + * @return true if consolidation occurred 393 + */ 394 + static wear_leveling_status_t wear_leveling_write_raw_multibyte(uint32_t address, const void *value, size_t length) { 395 + const uint8_t * p = value; 396 + write_log_entry_t log = LOG_ENTRY_MAKE_MULTIBYTE(address, length); 397 + for (size_t i = 0; i < length; ++i) { 398 + log.raw8[3 + i] = p[i]; 399 + } 400 + 401 + // Write to the backing store. See the multi-byte log format in the documentation header at the top of the file. 402 + wear_leveling_status_t status; 403 + #if BACKING_STORE_WRITE_SIZE == 2 404 + status = wear_leveling_append_raw(log.raw16[0]); 405 + if (status != WEAR_LEVELING_SUCCESS) { 406 + return status; 407 + } 408 + 409 + status = wear_leveling_append_raw(log.raw16[1]); 410 + if (status != WEAR_LEVELING_SUCCESS) { 411 + return status; 412 + } 413 + 414 + if (length > 1) { 415 + status = wear_leveling_append_raw(log.raw16[2]); 416 + if (status != WEAR_LEVELING_SUCCESS) { 417 + return status; 418 + } 419 + } 420 + 421 + if (length > 3) { 422 + status = wear_leveling_append_raw(log.raw16[3]); 423 + if (status != WEAR_LEVELING_SUCCESS) { 424 + return status; 425 + } 426 + } 427 + #elif BACKING_STORE_WRITE_SIZE == 4 428 + status = wear_leveling_append_raw(log.raw32[0]); 429 + if (status != WEAR_LEVELING_SUCCESS) { 430 + return status; 431 + } 432 + 433 + if (length > 1) { 434 + status = wear_leveling_append_raw(log.raw32[1]); 435 + if (status != WEAR_LEVELING_SUCCESS) { 436 + return status; 437 + } 438 + } 439 + #elif BACKING_STORE_WRITE_SIZE == 8 440 + status = wear_leveling_append_raw(log.raw64); 441 + if (status != WEAR_LEVELING_SUCCESS) { 442 + return status; 443 + } 444 + #endif 445 + return status; 446 + } 447 + 448 + /** 449 + * Handles the actual writing of logical data into the write log section of the backing store. 450 + */ 451 + static wear_leveling_status_t wear_leveling_write_raw(uint32_t address, const void *value, size_t length) { 452 + const uint8_t * p = value; 453 + size_t remaining = length; 454 + wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; 455 + while (remaining > 0) { 456 + #if BACKING_STORE_WRITE_SIZE == 2 457 + // Small-write optimizations - uint16_t, 0 or 1, address is even, address <16384: 458 + if (remaining >= 2 && address % 2 == 0 && address < 16384) { 459 + const uint16_t v = *(const uint16_t *)p; 460 + if (v == 0 || v == 1) { 461 + const write_log_entry_t log = LOG_ENTRY_MAKE_WORD_01(address, v); 462 + status = wear_leveling_append_raw(log.raw16[0]); 463 + if (status != WEAR_LEVELING_SUCCESS) { 464 + // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. 465 + // If a failure occurred, pass it on. 466 + return status; 467 + } 468 + 469 + remaining -= 2; 470 + address += 2; 471 + p += 2; 472 + continue; 473 + } 474 + } 475 + 476 + // Small-write optimizations - address<64: 477 + if (address < 64) { 478 + const write_log_entry_t log = LOG_ENTRY_MAKE_OPTIMIZED_64(address, *p); 479 + status = wear_leveling_append_raw(log.raw16[0]); 480 + if (status != WEAR_LEVELING_SUCCESS) { 481 + // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. 482 + // If a failure occurred, pass it on. 483 + return status; 484 + } 485 + 486 + remaining--; 487 + address++; 488 + p++; 489 + continue; 490 + } 491 + #endif // BACKING_STORE_WRITE_SIZE == 2 492 + const size_t this_length = remaining >= LOG_ENTRY_MULTIBYTE_MAX_BYTES ? LOG_ENTRY_MULTIBYTE_MAX_BYTES : remaining; 493 + status = wear_leveling_write_raw_multibyte(address, p, this_length); 494 + if (status != WEAR_LEVELING_SUCCESS) { 495 + // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. 496 + // If a failure occurred, pass it on. 497 + return status; 498 + } 499 + remaining -= this_length; 500 + address += (uint32_t)this_length; 501 + p += this_length; 502 + } 503 + 504 + return status; 505 + } 506 + 507 + /** 508 + * "Replays" the write log from the backing store, updating the local cache with updated values. 509 + */ 510 + static wear_leveling_status_t wear_leveling_playback_log(void) { 511 + wl_dprintf("Playback write log\n"); 512 + 513 + wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; 514 + bool cancel_playback = false; 515 + uint32_t address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area 516 + while (!cancel_playback && address < (WEAR_LEVELING_BACKING_SIZE)) { 517 + backing_store_int_t value; 518 + bool ok = backing_store_read(address, &value); 519 + if (!ok) { 520 + wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); 521 + cancel_playback = true; 522 + status = WEAR_LEVELING_FAILED; 523 + break; 524 + } 525 + if (value == 0) { 526 + wl_dprintf("Found empty slot, no more log entries\n"); 527 + cancel_playback = true; 528 + break; 529 + } 530 + 531 + // If we got a nonzero value, then we need to increment the address to ensure next write occurs at next location 532 + address += (BACKING_STORE_WRITE_SIZE); 533 + 534 + // Read from the write log 535 + write_log_entry_t log; 536 + #if BACKING_STORE_WRITE_SIZE == 2 537 + log.raw16[0] = value; 538 + #elif BACKING_STORE_WRITE_SIZE == 4 539 + log.raw32[0] = value; 540 + #elif BACKING_STORE_WRITE_SIZE == 8 541 + log.raw64 = value; 542 + #endif 543 + 544 + switch (LOG_ENTRY_GET_TYPE(log)) { 545 + case LOG_ENTRY_TYPE_MULTIBYTE: { 546 + #if BACKING_STORE_WRITE_SIZE == 2 547 + ok = backing_store_read(address, &log.raw16[1]); 548 + if (!ok) { 549 + wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); 550 + cancel_playback = true; 551 + status = WEAR_LEVELING_FAILED; 552 + break; 553 + } 554 + address += (BACKING_STORE_WRITE_SIZE); 555 + #endif // BACKING_STORE_WRITE_SIZE == 2 556 + const uint32_t a = LOG_ENTRY_MULTIBYTE_GET_ADDRESS(log); 557 + const uint8_t l = LOG_ENTRY_MULTIBYTE_GET_LENGTH(log); 558 + 559 + if (a + l > (WEAR_LEVELING_LOGICAL_SIZE)) { 560 + cancel_playback = true; 561 + status = WEAR_LEVELING_FAILED; 562 + break; 563 + } 564 + 565 + #if BACKING_STORE_WRITE_SIZE == 2 566 + if (l > 1) { 567 + ok = backing_store_read(address, &log.raw16[2]); 568 + if (!ok) { 569 + wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); 570 + cancel_playback = true; 571 + status = WEAR_LEVELING_FAILED; 572 + break; 573 + } 574 + address += (BACKING_STORE_WRITE_SIZE); 575 + } 576 + if (l > 3) { 577 + ok = backing_store_read(address, &log.raw16[3]); 578 + if (!ok) { 579 + wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); 580 + cancel_playback = true; 581 + status = WEAR_LEVELING_FAILED; 582 + break; 583 + } 584 + address += (BACKING_STORE_WRITE_SIZE); 585 + } 586 + #elif BACKING_STORE_WRITE_SIZE == 4 587 + if (l > 1) { 588 + ok = backing_store_read(address, &log.raw32[1]); 589 + if (!ok) { 590 + wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); 591 + cancel_playback = true; 592 + status = WEAR_LEVELING_FAILED; 593 + break; 594 + } 595 + address += (BACKING_STORE_WRITE_SIZE); 596 + } 597 + #endif 598 + 599 + memcpy(&wear_leveling.cache[a], &log.raw8[3], l); 600 + } break; 601 + #if BACKING_STORE_WRITE_SIZE == 2 602 + case LOG_ENTRY_TYPE_OPTIMIZED_64: { 603 + const uint32_t a = LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(log); 604 + const uint8_t v = LOG_ENTRY_OPTIMIZED_64_GET_VALUE(log); 605 + 606 + if (a >= (WEAR_LEVELING_LOGICAL_SIZE)) { 607 + cancel_playback = true; 608 + status = WEAR_LEVELING_FAILED; 609 + break; 610 + } 611 + 612 + wear_leveling.cache[a] = v; 613 + } break; 614 + case LOG_ENTRY_TYPE_WORD_01: { 615 + const uint32_t a = LOG_ENTRY_WORD_01_GET_ADDRESS(log); 616 + const uint8_t v = LOG_ENTRY_WORD_01_GET_VALUE(log); 617 + 618 + if (a + 1 >= (WEAR_LEVELING_LOGICAL_SIZE)) { 619 + cancel_playback = true; 620 + status = WEAR_LEVELING_FAILED; 621 + break; 622 + } 623 + 624 + wear_leveling.cache[a + 0] = v; 625 + wear_leveling.cache[a + 1] = 0; 626 + } break; 627 + #endif // BACKING_STORE_WRITE_SIZE == 2 628 + default: { 629 + cancel_playback = true; 630 + status = WEAR_LEVELING_FAILED; 631 + } break; 632 + } 633 + } 634 + 635 + // We've reached the end of the log, so we're at the new write location 636 + wear_leveling.write_address = address; 637 + 638 + if (status == WEAR_LEVELING_FAILED) { 639 + // If we had a failure during readback, assume we're corrupted -- force a consolidation with the data we already have 640 + status = wear_leveling_consolidate_force(); 641 + } else { 642 + // Consolidate the cache + write log if required 643 + status = wear_leveling_consolidate_if_needed(); 644 + } 645 + 646 + return status; 647 + } 648 + 649 + /** 650 + * Wear-leveling initialization 651 + */ 652 + wear_leveling_status_t wear_leveling_init(void) { 653 + wl_dprintf("Init\n"); 654 + 655 + // Reset the cache 656 + wear_leveling_clear_cache(); 657 + 658 + // Initialise the backing store 659 + if (!backing_store_init()) { 660 + // If it failed, clear the cache and return with failure 661 + wear_leveling_clear_cache(); 662 + return WEAR_LEVELING_FAILED; 663 + } 664 + 665 + // Read the previous consolidated values, then replay the existing write log so that the cache has the "live" values 666 + wear_leveling_status_t status = wear_leveling_read_consolidated(); 667 + if (status == WEAR_LEVELING_FAILED) { 668 + // If it failed, clear the cache and return with failure 669 + wear_leveling_clear_cache(); 670 + return status; 671 + } 672 + 673 + status = wear_leveling_playback_log(); 674 + if (status == WEAR_LEVELING_FAILED) { 675 + // If it failed, clear the cache and return with failure 676 + wear_leveling_clear_cache(); 677 + return status; 678 + } 679 + 680 + return status; 681 + } 682 + 683 + /** 684 + * Wear-leveling erase. 685 + * Post-condition: any reads from the backing store directly after an erase operation must come back as zero. 686 + */ 687 + wear_leveling_status_t wear_leveling_erase(void) { 688 + wl_dprintf("Erase\n"); 689 + 690 + // Unlock the backing store 691 + backing_store_lock_status_t lock_status = wear_leveling_unlock(); 692 + if (lock_status == STATUS_FAILURE) { 693 + wear_leveling_lock(); 694 + return WEAR_LEVELING_FAILED; 695 + } 696 + 697 + // Perform the erase 698 + bool ret = backing_store_erase(); 699 + wear_leveling_clear_cache(); 700 + 701 + // Lock the backing store if we acquired the lock successfully 702 + if (lock_status == STATUS_SUCCESS) { 703 + ret &= (wear_leveling_lock() != STATUS_FAILURE); 704 + } 705 + 706 + return ret ? WEAR_LEVELING_SUCCESS : WEAR_LEVELING_FAILED; 707 + } 708 + 709 + /** 710 + * Writes logical data into the backing store. Skips writes if there are no changes to values. 711 + */ 712 + wear_leveling_status_t wear_leveling_write(const uint32_t address, const void *value, size_t length) { 713 + wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE)); 714 + if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) { 715 + return WEAR_LEVELING_FAILED; 716 + } 717 + 718 + wl_dprintf("Write "); 719 + wl_dump(address, value, length); 720 + 721 + // Skip write if there's no change compared to the current cached value 722 + if (memcmp(value, &wear_leveling.cache[address], length) == 0) { 723 + return true; 724 + } 725 + 726 + // Update the cache before writing to the backing store -- if we hit the end of the backing store during writes to the log then we'll force a consolidation in-line 727 + memcpy(&wear_leveling.cache[address], value, length); 728 + 729 + // Unlock the backing store 730 + backing_store_lock_status_t lock_status = wear_leveling_unlock(); 731 + if (lock_status == STATUS_FAILURE) { 732 + wear_leveling_lock(); 733 + return WEAR_LEVELING_FAILED; 734 + } 735 + 736 + // Perform the actual write 737 + wear_leveling_status_t status = wear_leveling_write_raw(address, value, length); 738 + switch (status) { 739 + case WEAR_LEVELING_CONSOLIDATED: 740 + case WEAR_LEVELING_FAILED: 741 + // If the write triggered consolidation, or the write failed, then nothing else needs to occur. 742 + break; 743 + 744 + case WEAR_LEVELING_SUCCESS: 745 + // Consolidate the cache + write log if required 746 + status = wear_leveling_consolidate_if_needed(); 747 + break; 748 + 749 + default: 750 + // Unsure how we'd get here... 751 + status = WEAR_LEVELING_FAILED; 752 + break; 753 + } 754 + 755 + if (lock_status == STATUS_SUCCESS) { 756 + if (wear_leveling_lock() == STATUS_FAILURE) { 757 + status = WEAR_LEVELING_FAILED; 758 + } 759 + } 760 + 761 + return status; 762 + } 763 + 764 + /** 765 + * Reads logical data from the cache. 766 + */ 767 + wear_leveling_status_t wear_leveling_read(const uint32_t address, void *value, size_t length) { 768 + wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE)); 769 + if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) { 770 + return WEAR_LEVELING_FAILED; 771 + } 772 + 773 + // Only need to copy from the cache 774 + memcpy(value, &wear_leveling.cache[address], length); 775 + 776 + wl_dprintf("Read "); 777 + wl_dump(address, value, length); 778 + return WEAR_LEVELING_SUCCESS; 779 + }
+54
quantum/wear_leveling/wear_leveling.h
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #pragma once 4 + #include <stdint.h> 5 + #include <stdlib.h> 6 + 7 + /** 8 + * @typedef Status returned from any wear-leveling API. 9 + */ 10 + typedef enum wear_leveling_status_t { 11 + WEAR_LEVELING_FAILED, //< Invocation failed 12 + WEAR_LEVELING_SUCCESS, //< Invocation succeeded 13 + WEAR_LEVELING_CONSOLIDATED //< Invocation succeeded, consolidation occurred 14 + } wear_leveling_status_t; 15 + 16 + /** 17 + * Wear-leveling initialization 18 + * 19 + * @return Status of the request 20 + */ 21 + wear_leveling_status_t wear_leveling_init(void); 22 + 23 + /** 24 + * Wear-leveling erasure. 25 + * 26 + * Clears the wear-leveling area, with the definition that the "reset state" of all data is zero. 27 + * 28 + * @return Status of the request 29 + */ 30 + wear_leveling_status_t wear_leveling_erase(void); 31 + 32 + /** 33 + * Writes logical data into the backing store. 34 + * 35 + * Skips writes if there are no changes to written values. The entire written block is considered when attempting to 36 + * determine if an overwrite should occur -- if there is any data mismatch the entire block will be written to the log, 37 + * not just the changed bytes. 38 + * 39 + * @param address[in] the logical address to write data 40 + * @param value[in] pointer to the source buffer 41 + * @param length[in] length of the data 42 + * @return Status of the request 43 + */ 44 + wear_leveling_status_t wear_leveling_write(uint32_t address, const void* value, size_t length); 45 + 46 + /** 47 + * Reads logical data from the cache. 48 + * 49 + * @param address[in] the logical address to read data 50 + * @param value[out] pointer to the destination buffer 51 + * @param length[in] length of the data 52 + * @return Status of the request 53 + */ 54 + wear_leveling_status_t wear_leveling_read(uint32_t address, void* value, size_t length);
+145
quantum/wear_leveling/wear_leveling_internal.h
··· 1 + // Copyright 2022 Nick Brassel (@tzarc) 2 + // SPDX-License-Identifier: GPL-2.0-or-later 3 + #pragma once 4 + 5 + #ifdef __cplusplus 6 + # define _Static_assert static_assert 7 + #endif 8 + 9 + #include <stdint.h> 10 + #include <string.h> 11 + 12 + #if BACKING_STORE_WRITE_SIZE == 2 13 + typedef uint16_t backing_store_int_t; 14 + #elif BACKING_STORE_WRITE_SIZE == 4 15 + typedef uint32_t backing_store_int_t; 16 + #elif BACKING_STORE_WRITE_SIZE == 8 17 + typedef uint64_t backing_store_int_t; 18 + #else 19 + # error Invalid BACKING_STORE_WRITE_SIZE, needs to be 2/4/8. 20 + #endif 21 + 22 + #ifndef WEAR_LEVELING_BACKING_SIZE 23 + # error WEAR_LEVELING_BACKING_SIZE was not set. 24 + #endif 25 + 26 + #ifndef WEAR_LEVELING_LOGICAL_SIZE 27 + # error WEAR_LEVELING_LOGICAL_SIZE was not set. 28 + #endif 29 + 30 + #ifdef WEAR_LEVELING_DEBUG_OUTPUT 31 + # include <stdio.h> 32 + # define wl_dprintf(...) printf("Wear leveling: " __VA_ARGS__) 33 + # define wl_dump(address, value, length) \ 34 + do { \ 35 + printf("[0x%04X]: ", (int)(address)); \ 36 + const uint8_t* p = (const uint8_t*)(value); \ 37 + for (int i = 0; i < (length); ++i) { \ 38 + printf(" %02X", (int)p[i]); \ 39 + } \ 40 + printf("\n"); \ 41 + } while (0) 42 + #else 43 + # define wl_dprintf(...) \ 44 + do { \ 45 + } while (0) 46 + # define wl_dump(...) \ 47 + do { \ 48 + } while (0) 49 + #endif // WEAR_LEVELING_DEBUG_OUTPUT 50 + 51 + #ifdef WEAR_LEVELING_ASSERTS 52 + # include <assert.h> 53 + # define wl_assert(...) assert(__VA_ARGS__) 54 + #else 55 + # define wl_assert(...) \ 56 + do { \ 57 + } while (0) 58 + #endif // WEAR_LEVELING_ASSERTS 59 + 60 + // Compile-time validation of configurable options 61 + _Static_assert(WEAR_LEVELING_BACKING_SIZE >= (WEAR_LEVELING_LOGICAL_SIZE * 2), "Total backing size must be at least twice the size of the logical size"); 62 + _Static_assert(WEAR_LEVELING_LOGICAL_SIZE % BACKING_STORE_WRITE_SIZE == 0, "Logical size must be a multiple of write size"); 63 + _Static_assert(WEAR_LEVELING_BACKING_SIZE % WEAR_LEVELING_LOGICAL_SIZE == 0, "Backing size must be a multiple of logical size"); 64 + 65 + // Backing Store API, to be implemented elsewhere by flash driver etc. 66 + bool backing_store_init(void); 67 + bool backing_store_unlock(void); 68 + bool backing_store_erase(void); 69 + bool backing_store_write(uint32_t address, backing_store_int_t value); 70 + bool backing_store_lock(void); 71 + bool backing_store_read(uint32_t address, backing_store_int_t* value); 72 + 73 + /** 74 + * Helper type used to contain a write log entry. 75 + */ 76 + typedef union write_log_entry_t { 77 + uint64_t raw64; 78 + uint32_t raw32[2]; 79 + uint16_t raw16[4]; 80 + uint8_t raw8[8]; 81 + } write_log_entry_t; 82 + 83 + _Static_assert(sizeof(write_log_entry_t) == 8, "Wear leveling write log entry size was not 8"); 84 + 85 + /** 86 + * Log entry type discriminator. 87 + */ 88 + enum { 89 + // 0x00 -- Multi-byte storage type 90 + LOG_ENTRY_TYPE_MULTIBYTE, 91 + 92 + // 0x01 -- 2-byte backing store write optimization: address < 64 93 + LOG_ENTRY_TYPE_OPTIMIZED_64, 94 + 95 + // 0x02 -- 2-byte backing store write optimization: word-encoded 0/1 values 96 + LOG_ENTRY_TYPE_WORD_01, 97 + 98 + LOG_ENTRY_TYPES 99 + }; 100 + 101 + _Static_assert(LOG_ENTRY_TYPES <= (1 << 2), "Too many log entry types to fit into 2 bits of storage"); 102 + 103 + #define BITMASK_FOR_BITCOUNT(n) ((1 << (n)) - 1) 104 + 105 + #define LOG_ENTRY_GET_TYPE(entry) (((entry).raw8[0] >> 6) & BITMASK_FOR_BITCOUNT(2)) 106 + 107 + #define LOG_ENTRY_MULTIBYTE_MAX_BYTES 5 108 + #define LOG_ENTRY_MULTIBYTE_GET_ADDRESS(entry) (((((uint32_t)((entry).raw8[0])) & BITMASK_FOR_BITCOUNT(3)) << 16) | (((uint32_t)((entry).raw8[1])) << 8) | (entry).raw8[2]) 109 + #define LOG_ENTRY_MULTIBYTE_GET_LENGTH(entry) ((uint8_t)(((entry).raw8[0] >> 3) & BITMASK_FOR_BITCOUNT(3))) 110 + #define LOG_ENTRY_MAKE_MULTIBYTE(address, length) \ 111 + (write_log_entry_t) { \ 112 + .raw8 = { \ 113 + [0] = (((((uint8_t)LOG_ENTRY_TYPE_MULTIBYTE) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ 114 + | ((((uint8_t)(length)) & BITMASK_FOR_BITCOUNT(3)) << 3) /* length */ \ 115 + | ((((uint8_t)((address) >> 16))) & BITMASK_FOR_BITCOUNT(3)) /* address */ \ 116 + ), \ 117 + [1] = (((uint8_t)((address) >> 8)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \ 118 + [2] = (((uint8_t)(address)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \ 119 + } \ 120 + } 121 + 122 + #define LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(entry) ((uint32_t)((entry).raw8[0] & BITMASK_FOR_BITCOUNT(6))) 123 + #define LOG_ENTRY_OPTIMIZED_64_GET_VALUE(entry) ((entry).raw8[1]) 124 + #define LOG_ENTRY_MAKE_OPTIMIZED_64(address, value) \ 125 + (write_log_entry_t) { \ 126 + .raw8 = { \ 127 + [0] = (((((uint8_t)LOG_ENTRY_TYPE_OPTIMIZED_64) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ 128 + | ((((uint8_t)(address))) & BITMASK_FOR_BITCOUNT(6)) /* address */ \ 129 + ), \ 130 + [1] = ((uint8_t)(value)), /* value */ \ 131 + } \ 132 + } 133 + 134 + #define LOG_ENTRY_WORD_01_GET_ADDRESS(entry) ((((uint32_t)(((entry).raw8[0]) & BITMASK_FOR_BITCOUNT(5))) << 9) | (((uint32_t)((entry).raw8[1])) << 1)) 135 + #define LOG_ENTRY_WORD_01_GET_VALUE(entry) ((uint8_t)((entry).raw8[0] >> 5) & BITMASK_FOR_BITCOUNT(1)) 136 + #define LOG_ENTRY_MAKE_WORD_01(address, value) \ 137 + (write_log_entry_t) { \ 138 + .raw8 = { \ 139 + [0] = (((((uint8_t)LOG_ENTRY_TYPE_WORD_01) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ 140 + | (((((uint8_t)((value) ? 1 : 0))) & BITMASK_FOR_BITCOUNT(1)) << 5) /* value */ \ 141 + | ((((uint8_t)((address) >> 9))) & BITMASK_FOR_BITCOUNT(5)) /* address */ \ 142 + ), \ 143 + [1] = (uint8_t)((address) >> 1), /* address */ \ 144 + } \ 145 + }