hash-sets: faster implementation based on hashtables.
parent
5908186301
commit
04af5f2ffb
|
@ -9,7 +9,7 @@ math.integers.private layouts math.order vectors hashtables
|
||||||
combinators effects generalizations sequences.generalizations
|
combinators effects generalizations sequences.generalizations
|
||||||
assocs sets combinators.short-circuit sequences.private locals
|
assocs sets combinators.short-circuit sequences.private locals
|
||||||
growable stack-checker namespaces compiler.tree.propagation.info
|
growable stack-checker namespaces compiler.tree.propagation.info
|
||||||
;
|
hash-sets ;
|
||||||
FROM: math => float ;
|
FROM: math => float ;
|
||||||
FROM: sets => set ;
|
FROM: sets => set ;
|
||||||
IN: compiler.tree.propagation.transforms
|
IN: compiler.tree.propagation.transforms
|
||||||
|
@ -157,7 +157,7 @@ IN: compiler.tree.propagation.transforms
|
||||||
in-d>> first value-info literal>> {
|
in-d>> first value-info literal>> {
|
||||||
{ V{ } [ [ drop { } 0 vector boa ] ] }
|
{ V{ } [ [ drop { } 0 vector boa ] ] }
|
||||||
{ H{ } [ [ drop 0 <hashtable> ] ] }
|
{ H{ } [ [ drop 0 <hashtable> ] ] }
|
||||||
{ HS{ } [ [ drop f fast-set ] ] }
|
{ HS{ } [ [ drop 0 <hash-set> ] ] }
|
||||||
[ drop f ]
|
[ drop f ]
|
||||||
} case
|
} case
|
||||||
] "custom-inlining" set-word-prop
|
] "custom-inlining" set-word-prop
|
||||||
|
|
|
@ -94,7 +94,12 @@ M: hashtable random
|
||||||
|
|
||||||
M: sets:set random members random ;
|
M: sets:set random members random ;
|
||||||
|
|
||||||
M: hash-set random table>> random first ;
|
M: hash-set random
|
||||||
|
dup cardinality [ drop f ] [
|
||||||
|
[ 0 ] [ array>> ] [ random ] tri* 1 + [
|
||||||
|
[ 2dup array-nth tombstone? [ 1 + ] 2dip ] loop
|
||||||
|
] times [ 1 - ] dip array-nth
|
||||||
|
] if-zero ;
|
||||||
|
|
||||||
: randomize-n-last ( seq n -- seq )
|
: randomize-n-last ( seq n -- seq )
|
||||||
[ dup length dup ] dip - 1 max '[ dup _ > ]
|
[ dup length dup ] dip - 1 max '[ dup _ > ]
|
||||||
|
|
|
@ -1,34 +1,149 @@
|
||||||
! Copyright (C) 2010 Daniel Ehrenberg
|
! Copyright (C) 2010 Daniel Ehrenberg
|
||||||
|
! Copyright (C) 2005, 2011 John Benediktsson, Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors assocs hashtables kernel sequences sets
|
USING: accessors arrays hash-sets hashtables.private kernel
|
||||||
sets.private ;
|
kernel.private math math.private sequences sequences.private
|
||||||
|
sets sets.private slots.private vectors ;
|
||||||
IN: hash-sets
|
IN: hash-sets
|
||||||
|
|
||||||
! In a better implementation, less memory would be used
|
TUPLE: hash-set
|
||||||
TUPLE: hash-set { table hashtable read-only } ;
|
{ count array-capacity }
|
||||||
|
{ deleted array-capacity }
|
||||||
|
{ array array } ;
|
||||||
|
|
||||||
: <hash-set> ( capacity -- hash-set )
|
<PRIVATE
|
||||||
<hashtable> hash-set boa ; inline
|
|
||||||
|
: hash@ ( key array -- i )
|
||||||
|
[ hashcode >fixnum ] dip wrap ; inline
|
||||||
|
|
||||||
|
: probe ( array i probe# -- array i probe# )
|
||||||
|
1 fixnum+fast [ fixnum+fast over wrap ] keep ; inline
|
||||||
|
|
||||||
|
: no-key ( key array -- array n ? ) nip f f ; inline
|
||||||
|
|
||||||
|
: (key@) ( key array i probe# -- array n ? )
|
||||||
|
[ 3dup swap array-nth ] dip over ((empty)) eq?
|
||||||
|
[ 4drop no-key ] [
|
||||||
|
[ = ] dip swap
|
||||||
|
[ drop rot drop t ]
|
||||||
|
[ probe (key@) ]
|
||||||
|
if
|
||||||
|
] if ; inline recursive
|
||||||
|
|
||||||
|
: key@ ( key hash -- array n ? )
|
||||||
|
array>> dup length>> 0 eq?
|
||||||
|
[ no-key ] [ 2dup hash@ 0 (key@) ] if ; inline
|
||||||
|
|
||||||
|
: <hash-array> ( n -- array )
|
||||||
|
1 + next-power-of-2 2 * ((empty)) <array> ; inline
|
||||||
|
|
||||||
|
: reset-hash ( n hash -- )
|
||||||
|
swap <hash-array> >>array init-hash ; inline
|
||||||
|
|
||||||
|
: (new-key@) ( key array i probe# j -- array i j empty? )
|
||||||
|
[ 2dup swap array-nth ] 2dip pick tombstone?
|
||||||
|
[
|
||||||
|
rot ((empty)) eq?
|
||||||
|
[ nip [ drop ] 3dip t ]
|
||||||
|
[ pick or [ probe ] dip (new-key@) ]
|
||||||
|
if
|
||||||
|
] [
|
||||||
|
[ [ pick ] dip = ] 2dip rot
|
||||||
|
[ nip [ drop ] 3dip f ]
|
||||||
|
[ [ probe ] dip (new-key@) ]
|
||||||
|
if
|
||||||
|
] if ; inline recursive
|
||||||
|
|
||||||
|
: new-key@ ( key hash -- array n )
|
||||||
|
[ array>> 2dup hash@ 0 f (new-key@) ] keep swap
|
||||||
|
[ over [ hash-deleted- ] [ hash-count+ ] if swap or ] [ 2drop ] if ; inline
|
||||||
|
|
||||||
|
: set-nth-item ( key seq n -- )
|
||||||
|
2 fixnum+fast set-slot ; inline
|
||||||
|
|
||||||
|
: (rehash) ( hash seq -- )
|
||||||
|
swap [ dupd new-key@ set-nth-item ] curry each ; inline
|
||||||
|
|
||||||
|
: hash-large? ( hash -- ? )
|
||||||
|
[ count>> 3 fixnum*fast 1 fixnum+fast ]
|
||||||
|
[ array>> length>> 1 fixnum-shift-fast ] bi fixnum> ; inline
|
||||||
|
|
||||||
|
: grow-hash ( hash -- )
|
||||||
|
{ hash-set } declare [
|
||||||
|
[ members { array } declare ]
|
||||||
|
[ cardinality 1 + ]
|
||||||
|
[ reset-hash ] tri
|
||||||
|
] keep swap (rehash) ;
|
||||||
|
|
||||||
|
: ?grow-hash ( hash -- )
|
||||||
|
dup hash-large? [ grow-hash ] [ drop ] if ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: <hash-set> ( n -- hash )
|
||||||
|
hash-set new [ reset-hash ] keep ; inline
|
||||||
|
|
||||||
|
M: hash-set in? ( key hash -- ? )
|
||||||
|
key@ 2nip ;
|
||||||
|
|
||||||
|
M: hash-set clear-set ( hash -- )
|
||||||
|
[ init-hash ] [ array>> [ drop ((empty)) ] map! drop ] bi ;
|
||||||
|
|
||||||
|
M: hash-set delete ( key hash -- )
|
||||||
|
[ nip ] [ key@ ] 2bi [
|
||||||
|
[ ((tombstone)) ] 2dip set-nth-item
|
||||||
|
hash-deleted+
|
||||||
|
] [
|
||||||
|
3drop
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
M: hash-set cardinality ( hash -- n )
|
||||||
|
[ count>> ] [ deleted>> ] bi - ; inline
|
||||||
|
|
||||||
|
M: hash-set adjoin ( key hash -- )
|
||||||
|
dup ?grow-hash dupd new-key@ set-nth-item ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: push-unsafe ( elt seq -- )
|
||||||
|
[ length ] keep
|
||||||
|
[ underlying>> set-array-nth ]
|
||||||
|
[ [ 1 fixnum+fast { array-capacity } declare ] dip length<< ]
|
||||||
|
2bi ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
M: hash-set members
|
||||||
|
[ array>> [ length ] keep ] [ cardinality <vector> ] bi [
|
||||||
|
[
|
||||||
|
[ array-nth ] dip over tombstone?
|
||||||
|
[ 2drop ] [ push-unsafe ] if
|
||||||
|
] 2curry each-integer
|
||||||
|
] keep { } like ;
|
||||||
|
|
||||||
|
M: hash-set clone
|
||||||
|
(clone) [ clone ] change-array ; inline
|
||||||
|
|
||||||
|
M: hash-set equal?
|
||||||
|
over hash-set? [ set= ] [ 2drop f ] if ;
|
||||||
|
|
||||||
: >hash-set ( members -- hash-set )
|
: >hash-set ( members -- hash-set )
|
||||||
unique hash-set boa ; inline
|
dup length <hash-set> [ [ adjoin ] curry each ] keep ;
|
||||||
|
|
||||||
|
M: hash-set set-like
|
||||||
|
drop dup hash-set? [ ?members >hash-set ] unless ; inline
|
||||||
|
|
||||||
INSTANCE: hash-set set
|
INSTANCE: hash-set set
|
||||||
M: hash-set in? table>> key? ; inline
|
|
||||||
M: hash-set adjoin table>> dupd set-at ; inline
|
|
||||||
M: hash-set delete table>> delete-at ; inline
|
|
||||||
M: hash-set members table>> keys ; inline
|
|
||||||
M: hash-set set-like drop dup hash-set? [ ?members >hash-set ] unless ;
|
|
||||||
M: hash-set clone table>> clone hash-set boa ;
|
|
||||||
M: hash-set null? table>> assoc-empty? ;
|
|
||||||
M: hash-set cardinality table>> assoc-size ;
|
|
||||||
M: hash-set intersect small/large sequence/tester filter >hash-set ;
|
M: hash-set intersect small/large sequence/tester filter >hash-set ;
|
||||||
|
|
||||||
M: hash-set union (union) >hash-set ;
|
M: hash-set union (union) >hash-set ;
|
||||||
|
|
||||||
M: hash-set diff sequence/tester [ not ] compose filter >hash-set ;
|
M: hash-set diff sequence/tester [ not ] compose filter >hash-set ;
|
||||||
M: hash-set clear-set table>> clear-assoc ;
|
|
||||||
|
M: f fast-set drop 0 <hash-set> ;
|
||||||
|
|
||||||
M: sequence fast-set >hash-set ;
|
M: sequence fast-set >hash-set ;
|
||||||
M: f fast-set drop H{ } clone hash-set boa ;
|
|
||||||
|
|
||||||
M: sequence duplicates
|
M: sequence duplicates
|
||||||
dup length <hash-set> [ ?adjoin not ] curry filter ;
|
dup length <hash-set> [ ?adjoin not ] curry filter ;
|
||||||
|
|
Loading…
Reference in New Issue