commit ec50ab1afed5844652706126cb54c076bcca478a
parent e6630f0e973a9a27b01a0eee63da22187737154d
Author: Robby Findler <robby@racket-lang.org>
Date: Wed, 15 Apr 2015 05:44:57 -0500
make blueboxes library work properly when the blueboxes.rktd files content changes
Diffstat:
1 file changed, 69 insertions(+), 43 deletions(-)
diff --git a/scribble-lib/scribble/blueboxes.rkt b/scribble-lib/scribble/blueboxes.rkt
@@ -15,7 +15,14 @@
[fetch-blueboxes-method-tags (->* (symbol?) (#:blueboxes-cache blueboxes-cache?)
(listof method-tag?))]))
+
+;; offset : (or/c exact-nonnegative-integer? #f)
+;; tag-ht : (or/c valid-blueboxes-info? #f)
+;; mod-time : (or/c exact-nonnegative-integer? #f)
+(struct bluebox-info (blueboxes.rktd [offset #:mutable] [tag-ht #:mutable] [mod-time #:mutable]))
+
(struct blueboxes-cache (info-or-paths method->tags) #:mutable)
+
(define (make-blueboxes-cache
populate?
#:blueboxes-dirs
@@ -45,25 +52,26 @@
(define (fetch-strs-for-single-tag tag cache)
(populate-cache! cache)
(for/or ([ent (in-list (blueboxes-cache-info-or-paths cache))])
- (define offset+lens (hash-ref (list-ref ent 2) tag #f))
- (cond
- [offset+lens
- (define lines
- (apply
- append
- (for/list ([offset+len (in-list offset+lens)])
- (define fn (list-ref ent 0))
- (define offset (list-ref ent 1))
- (call-with-input-file fn
- (λ (port)
- (port-count-lines! port)
- (file-position port (+ (car offset+len) offset))
- (for/list ([i (in-range (cdr offset+len))])
- (read-line port)))))))
+ (check-and-update-bluebox-info! ent)
+ (match ent
+ [(bluebox-info blueboxes.rktd offset tag-ht _)
+ (define offset+lens (hash-ref tag-ht tag #f))
(cond
- [(ormap eof-object? lines) #f]
- [else lines])]
- [else #f])))
+ [offset+lens
+ (define lines
+ (apply
+ append
+ (for/list ([offset+len (in-list offset+lens)])
+ (call-with-input-file blueboxes.rktd
+ (λ (port)
+ (port-count-lines! port)
+ (file-position port (+ (car offset+len) offset))
+ (for/list ([i (in-range (cdr offset+len))])
+ (read-line port)))))))
+ (cond
+ [(ormap eof-object? lines) #f]
+ [else lines])]
+ [else #f])])))
(define (fetch-blueboxes-method-tags sym #:blueboxes-cache [cache (make-blueboxes-cache #f)])
(populate-cache! cache)
@@ -78,9 +86,9 @@
(define (compute-methods-table lst)
(define meth-ht (make-hash))
- (for ([three-tuple (in-list lst)])
- (match three-tuple
- [`(,file-path ,i ,tag-ht)
+ (for ([a-bluebox-info (in-list lst)])
+ (match a-bluebox-info
+ [(bluebox-info blueboxes.rktd offset tag-ht mod-time)
(for ([(tag val) (in-hash tag-ht)])
(when (method-tag? tag)
(define-values (class/intf meth) (get-class/interface-and-method tag))
@@ -93,29 +101,47 @@
values
(for*/list ([doc-dir-name (in-list blueboxes-dirs)])
(define blueboxes.rktd (build-path doc-dir-name "blueboxes.rktd"))
- (and (file-exists? blueboxes.rktd)
- (call-with-input-file blueboxes.rktd
- (λ (port)
- (port-count-lines! port)
- (define first-line (read-line port))
- (define pos (file-position port))
- (define desed
- (with-handlers ([exn:fail? (λ (x)
- (log-warning "Failed to deserialize ~a: ~a"
- x
- (exn-message x))
- #f)])
- (define candidate (deserialize (read port)))
- (unless (valid-blueboxes-info? candidate)
- (error 'build-blueboxes-cache
- "blueboxes info didn't have the right shape: ~s"
- candidate))
- candidate))
- (and desed
- (list blueboxes.rktd
- (+ (string->number first-line) pos)
- desed))))))))
+ (define a-bluebox-info (bluebox-info blueboxes.rktd #f #f #f))
+ (populate-bluebox-info! a-bluebox-info)
+ a-bluebox-info)))
+(define (check-and-update-bluebox-info! a-bluebox-info)
+ (match a-bluebox-info
+ [(bluebox-info blueboxes.rktd offset tag-ht mod-time)
+ (when (or (not mod-time)
+ (and (file-exists? blueboxes.rktd)
+ (not (mod-time . = . (file-or-directory-modify-seconds blueboxes.rktd)))))
+ (populate-bluebox-info! a-bluebox-info))]))
+
+(define (populate-bluebox-info! a-bluebox-info)
+ (define blueboxes.rktd (bluebox-info-blueboxes.rktd a-bluebox-info))
+ (cond
+ [(file-exists? blueboxes.rktd)
+ (call-with-input-file blueboxes.rktd
+ (λ (port)
+ (port-count-lines! port)
+ (define first-line (read-line port))
+ (define pos (file-position port))
+ (define desed
+ (with-handlers ([exn:fail? (λ (x)
+ (log-warning "Failed to deserialize ~a: ~a"
+ x
+ (exn-message x))
+ #f)])
+ (define candidate (deserialize (read port)))
+ (unless (valid-blueboxes-info? candidate)
+ (error 'build-blueboxes-cache
+ "blueboxes info didn't have the right shape: ~s"
+ candidate))
+ candidate))
+ (set-bluebox-info-offset! a-bluebox-info (and desed (+ (string->number first-line) pos)))
+ (set-bluebox-info-tag-ht! a-bluebox-info desed)
+ (set-bluebox-info-mod-time! a-bluebox-info
+ (file-or-directory-modify-seconds blueboxes.rktd))))]
+ [else
+ (set-bluebox-info-offset! a-bluebox-info #f)
+ (set-bluebox-info-tag-ht! a-bluebox-info #f)
+ (set-bluebox-info-mod-time! a-bluebox-info #f)]))
(define valid-blueboxes-info?
(hash/c