optimizations

main
Matthew Butterick 9 years ago
parent ad07636541
commit 5e8764afb5

@ -4,7 +4,7 @@
;; note to self: a require/typed function with proper typing
;; is faster than a generic function + type assertion at location of call
(require/typed racket/list
[flatten ((Listof QuadAttr) . -> . HashableList)])
[flatten ((Listof QuadAttr) . -> . QuadAttrs)])
(require/typed sugar/list [trimf (All (A) ((Listof A) (A . -> . Boolean) -> (Listof A)))]
[filter-split (All (A) ((Listof A) (A . -> . Boolean) -> (Listof (Listof A))))])
(require/typed racket/string [string-append* ((Listof String) . -> . String)])
@ -68,7 +68,10 @@
;; funky implementation
(define-type+predicate Quad (Pairof QuadName (Pairof QuadAttrs (Listof (U String Quad)))))
;; Quad-Recursive works around a bug in the optimizer
;; see https://github.com/racket/typed-racket/issues/60
(define-type Quad-Recursive (List* QuadName QuadAttrs (Listof (U String Quad-Recursive))))
(define-type+predicate Quad (List* QuadName QuadAttrs (Listof (U String Quad-Recursive))))
(define-predicate quad? Quad)
(define/typed (quad name attrs items)
(QuadName QuadAttrs QuadList . -> . Quad)
@ -82,7 +85,7 @@
(define/typed (quad-attrs q)
(Quad . -> . QuadAttrs)
(cadr q))
(car (cdr q)))
(define/typed (quad-attr-keys qas)
(QuadAttrs . -> . (Listof QuadAttrKey))
@ -92,17 +95,18 @@
(define/typed (quad-list q)
(Quad . -> . QuadList)
(cddr q))
(cdr (cdr q)))
(define/typed (quad-attr-ref q-or-qas key [default attr-missing])
(((U Quad QuadAttrs) QuadAttrKey) (QuadAttrValue) . ->* . QuadAttrValue)
(define qas (if (quad? q-or-qas) (quad-attrs q-or-qas) q-or-qas))
(define qa-result (memf (λ([qap : QuadAttr]) (equal? key (car qap))) qas))
(if qa-result
;; empty check shouldn't be necessary but the memf return type is lax: #f or (Listof A)
;; really it should be #f or (List* A (Listof A))
(if (and qa-result (not (empty? qa-result)))
;; car beacause result of memf is a list tail; cadr because second element in pair
(cadr (car qa-result))
(car (cdr (car qa-result)))
(if (not (equal? default attr-missing)) default (error 'key-not-found))))
@ -141,26 +145,27 @@
[else (string-append* ((inst map String QuadListItem) loop (quad-list x)))])))
(define/typed+provide (gather-common-attrs qs)
((Listof Quad) . -> . (Option HashableList))
((Listof Quad) . -> . QuadAttrs)
(: check-cap (Quad QuadAttr . -> . Boolean))
(define (check-cap q cap) ; cap = candidate-attr-pair
(equal? (quad-attr-ref q (car cap) attr-missing) (cdr cap)))
(and (not (null? qs))
(let loop
([qs qs]
;; start with the set of pairs in the first quad, then filter it down
[candidate-attr-pairs : (Listof QuadAttr) (let ([first-attrs (quad-attrs (car qs))])
(if first-attrs
(for/fold ([kvps : QuadAttrs null]) ([k (in-list (quad-attr-keys first-attrs))])
(if (member k cannot-be-common-attrs)
kvps
(cons (list k (quad-attr-ref first-attrs k)) kvps)))
null))])
(cond
[(null? candidate-attr-pairs) #f] ; ran out of possible pairs, so return #f
[(null? qs) (flatten candidate-attr-pairs)] ; ran out of quads, so return common-attr-pairs
;; todo: reconsider type interface between output of this function and input to quadattrs
[else (loop (cdr qs) (filter (λ([cap : QuadAttr]) (check-cap (car qs) cap)) candidate-attr-pairs))]))))
(if (null? qs)
qs
(let loop
([qs qs]
;; start with the set of pairs in the first quad, then filter it down
[candidate-attr-pairs : (Listof QuadAttr) (let ([first-attrs (quad-attrs (car qs))])
(if first-attrs
(for/fold ([kvps : QuadAttrs null]) ([k (in-list (quad-attr-keys first-attrs))])
(if (member k cannot-be-common-attrs)
kvps
(cons (list k (quad-attr-ref first-attrs k)) kvps)))
null))])
(cond
[(null? candidate-attr-pairs) null] ; ran out of possible pairs, so return #f
[(null? qs) (flatten candidate-attr-pairs)] ; ran out of quads, so return common-attr-pairs
;; todo: reconsider type interface between output of this function and input to quadattrs
[else (loop (cdr qs) (filter (λ([cap : QuadAttr]) (check-cap (car qs) cap)) candidate-attr-pairs))]))))
(define/typed (make-quadattrs xs)
;; no point typing the input as (U QuadAttrKey QuadAttrValue)
@ -191,15 +196,15 @@
((Listof Quad) . -> . Quad)
(apply id (gather-common-attrs qs) qs))
(define-type IdQuad (List 'id QuadAttrs QuadList))
(define-type IdQuad (List* 'id QuadAttrs (Listof (U String Quad))))
(define-predicate IdQuad? IdQuad)
(define id? IdQuad?)
(define/typed (id [attrs '()] #:zzz [zzz 0] . xs)
(() (QuadAttrs #:zzz Zero) #:rest QuadListItem . ->* . Quad)
(quad 'id (if (list? attrs)
(make-quadattrs attrs)
attrs) xs))))]))
(quad 'id (if (QuadAttrs? attrs)
attrs
(make-quadattrs attrs)) xs))))]))
(define/typed (whitespace? x [nbsp? #f])
((Any) (Boolean) . ->* . Boolean)
@ -256,7 +261,7 @@
(define-quad-type box)
#|
(define-quad-type spacer)
(define-quad-type kern)
(define-quad-type optical-kern)
@ -278,4 +283,4 @@
(define-break-type column)
(define-break-type block)
(define-break-type line)
|#

Loading…
Cancel
Save