benchmark-log.ss
(module benchmark-log mzscheme

  (require
   (lib "list.ss" "srfi" "1")
   (planet "science.ss" ("williams" "science.plt" 2))
   (planet "port.ss" ("schematics" "port.plt" 1)))

  (provide
   run-name
   run-times
   
   read-benchmark-log
   add-run
   find-most-recent-run)
  
  ;; A benchmark log is a (listof run)

  ;; A run is (vector name description seconds (vectorof time) mean std-dev)

  ;; name is a string, the name of the test-case the timing is for

  ;; description is a string, describing the changes implemented in this run
  
  ;; seconds is an integer, the value of current-seconds at
  ;; the time the data was first written

  ;; time is an integer, the runtime of the test

  ;; mean is a number, the mean of the times

  ;; std-dev is a number, the standard deviation of the times

  ;; run-name : run -> string
  (define (run-name run)
    (vector-ref run 0))

  ;; run-times : run -> (vectorof time)
  (define (run-times run)
    (vector-ref run 3))
  
  (define (read-benchmark-log file-name)
    (if (file-exists? file-name)
        (with-input-from-file file-name
          (lambda ()
            (read (current-input-port))))
        (begin
          (with-output-to-file file-name
            (lambda () (write null)))
          null)))

  ;; add-run : (U string path) (vectorof time) -> void
  (define (add-run file-name name times)
    (let ([data (read-benchmark-log file-name)])
      (with-output-to-file file-name
        (lambda ()
          (write
           (cons
            (vector name "" (current-seconds) times (mean times) (standard-deviation times))
            data)))
        'replace)))

  ;; find-most-recent-run : (U string path) string -> (U run #f)
  (define (find-most-recent-run file-name name)
    (let ([log (read-benchmark-log file-name)])
      (find
       (lambda (run)
         (string=? (run-name run) name))
       log)))

  
  )