{ $values
{ "n" integer } { "seq" sequence }
{ "x" integer } }
-{ $description "Iterates over a sequence, computes a hashcode with " { $link hashcode* } " for each element, and combines them." } ;
+{ $description "Iterates over a sequence, computes a hashcode with " { $link hashcode* } " for each element, and combines them using " { $link sequence-hashcode-step } "." } ;
+
+HELP: sequence-hashcode-step
+{ $values
+ { "oldhash" integer } { "newpart" integer }
+ { "newhash" integer } }
+{ $description "An implementation word that computes a running hashcode of a sequence using some bit-twiddling. The resulting hashcode is always a fixnum." } ;
HELP: short
{ $values
: assert-sequence= ( a b -- )
2dup sequence= [ 2drop ] [ assert-sequence ] if ;
-: sequence-hashcode ( depth seq -- hash )
- [
- [ drop 1000003 HEX: 345678 ] dip length
- [ dup fixnum+fast 82520 fixnum+fast ] [ iota ] bi
- ] 2keep [
- swapd nth-unsafe hashcode* rot fixnum-bitxor
- pick fixnum*fast [ [ fixnum+fast ] keep ] dip swap
- ] 2curry each drop nip 97531 fixnum+fast ; inline
+<PRIVATE
+
+: sequence-hashcode-step ( oldhash newpart -- newhash )
+ >fixnum swap [
+ [ -2 fixnum-shift-fast ] [ 5 fixnum-shift-fast ] bi
+ fixnum+fast fixnum+fast
+ ] keep fixnum-bitxor ; inline
+
+PRIVATE>
+
+: sequence-hashcode ( n seq -- x )
+ [ 0 ] 2dip [ hashcode* sequence-hashcode-step ] with each ; inline
M: reversed equal? over reversed? [ sequence= ] [ 2drop f ] if ;
: reset-string-hashcode ( str -- )
f swap set-string-hashcode ; inline
-: string-hashcode-step ( oldhash newpart -- newhash )
- >fixnum swap [
- [ -2 fixnum-shift-fast ] [ 5 fixnum-shift-fast ] bi
- fixnum+fast fixnum+fast
- ] keep fixnum-bitxor ; inline
-
: rehash-string ( str -- )
- [ 0 [ string-hashcode-step ] reduce ] keep set-string-hashcode ; inline
+ 1 over sequence-hashcode swap set-string-hashcode ; inline
: (aux) ( n string -- byte-array m )
aux>> { byte-array } declare swap 1 fixnum-shift-fast ; inline