(module hashed-set mzscheme (require "../private/require.ss") (require-contracts) (require-lists) (require-compare) (require-etc) (require-class) (require "../private/contracts.ss" "../private/method.ss" "set-interface.ss" "abstract-set.ss" "../iterator/iterator-interface.ss" "unordered-set.ss" "../table/ordered-table.ss") (provide/contract [hashed-set% (implementation?/c set<%>)] [make-hashed-set (([hash hash-fn/c] [equ? equality/c] [elems (listof any/c)]) . ->r . set/c)]) (define (make-hashed-set hash equ? elems) (foldl (lambda (elem set) (send set insert elem)) (new hashed-set% [hash hash] [equ? equ?] [groups (make-ordered-table number-compare null null)]) elems)) (define-syntax (define/set stx) (syntax-case stx () [(_ . REST) #'(define/export override set- . REST)])) (define hashed-set% (class* abstract-set% (set<%>) (super-new) (init-field hash equ? groups) (define/private (copy/groups new-groups) (new hashed-set% [hash hash] [equ? equ?] [groups new-groups])) (define/private (copy/group key group) (if (send group empty?) (copy/groups (send groups remove key)) (copy/groups (send groups insert key group)))) (define/private (get-group key) (send groups lookup key (lambda () (make-unordered-set equ? null)))) (define/set (clear) (copy/groups (send groups clear))) (define/set (elements) (apply append (map (lambda (group) (send group elements)) (map second (send groups sexp))))) (define/set (insert elem) (let* ([key (hash elem)]) (copy/group key (send (get-group key) insert elem)))) (define/set lookup (opt-lambda (elem [failure (constant #f)] [success identity]) (send (get-group (hash elem)) lookup elem failure success))) (define/set (iterator) (new hashed-iterator% [group-iter (send groups iterator)])) (define/set (remove elem) (let* ([key (hash elem)]) (copy/group key (send (get-group key) remove elem)))) (define/set (empty?) (send groups empty?)) (define/set (size) (send groups fold/value (lambda (group total) (+ (send group size) total)) 0)) (define/set (select) (send (send groups select/value) select)) )) (define hashed-iterator% (class* object% (iterator<%>) (super-new) (init-field group-iter) (define/private (copy/group-iter new-iter) (new hashed-iterator% [group-iter new-iter])) (define/public (end?) (send group-iter end?)) (define/public (element) (send (send (send group-iter element) iterator) element)) (define/public (next) (new append-iterator% [first (send (send (send group-iter element) iterator) next)] [second (copy/group-iter (send group-iter next))])) )) (define append-iterator% (class* object% (iterator<%>) (super-new) (init-field first second) (define/private (copy/first new-first) (new append-iterator% [first new-first] [second second])) (define/public (end?) (and (send first end?) (send second end?))) (define/public (element) (if (send first end?) (send second element) (send first element))) (define/public (next) (if (send first end?) (send second next) (copy/first (send first next)))) )) )