#! /bin/sh
exec ../src/sizzle -s $0 $*
!#
;; scripts/examine-symbol-table.scm
;;
;; Copyright (C) 2000 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
;;
;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; 
;; This software is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;; 
;; You should have received a copy of the GNU General Public License
;; along with this package; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.  

;; This scripts prints out some statistics about symbol table usage,
;; hash function quality etc.

(define (help)
  (display "Usage: examine-symbol-table.scm [-h] [--help]\n"))

(define (print-symbol-list ls bc)
;  (for-each (lambda (x) (display x) (display #\space)) ls)
  (display bc) (newline)
  (display "Some symbol table statistics\n")
  (display "  Items in symbol table:          ")
  (display (length ls))
  (newline)
  (display "  Capacity used:                  ")
  (display (/ (* (length ls) 100)
	      (vector-length (symbol-table))))
  (display "%")
  (newline)
  (let ((len (vector-length bc))
	(longest 0)
	(non-null 0)
	(avg 0))
    (do ((i 0 (+ i 1)))
	((= i len) #t)
      (set! avg (+ (vector-ref bc i) avg))
      (if (> (vector-ref bc i) longest)
	  (set! longest (vector-ref bc i)))
      (if (> (vector-ref bc i) 0)
	  (begin
	    (set! non-null (+ non-null 1)))))
    (display "  Longest bucket size:            ")
    (display longest)
    (newline)
    (display "  Average bucket size (all):      ")
    (display (/ avg (vector-length (symbol-table))))
    (newline)
    (display "  Average bucket size (non-null): ")
    (display (/ avg non-null))
    (newline)))

(define (walk-symbol-table)
  (let* ((symtab (symbol-table))
	(bucket-counter (make-vector (vector-length symtab) 0)))
    (let loop ((idx (- (vector-length symtab) 1))
	       (symbol-list '()))
      (let inner ((ptr (vector-ref symtab idx))
		  (symbol-list symbol-list))
	(cond ((pair? ptr)
	       (vector-set! bucket-counter idx 
			    (+ (vector-ref bucket-counter idx) 1))
	       (inner (cdr ptr) (cons (car ptr) symbol-list)))
	      (else
	       (cond ((> idx 0)
		      (loop (- idx 1) symbol-list))
		     (else
		      (print-symbol-list symbol-list bucket-counter)))))))))
	       
(define (handle-command-line command-line)
  (cond ((or (member "-h" command-line) (member "--help" command-line))
	 (help))
	(else (walk-symbol-table))))

(handle-command-line (command-line))
