[movitz-cvs] CVS update: movitz/losp/muerte/hash-tables.lisp

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Mon Jun 13 23:00:26 UTC 2005


Update of /project/movitz/cvsroot/movitz/losp/muerte
In directory common-lisp.net:/tmp/cvs-serv18056

Modified Files:
	hash-tables.lisp 
Log Message:
Improved hash-tables somewhat: dynamically grow and rehash. Also,
decreased the hash-table-size of dumped hash-tables, which apparently
decreased the image-size by 10%.

Date: Tue Jun 14 01:00:26 2005
Author: ffjeld

Index: movitz/losp/muerte/hash-tables.lisp
diff -u movitz/losp/muerte/hash-tables.lisp:1.6 movitz/losp/muerte/hash-tables.lisp:1.7
--- movitz/losp/muerte/hash-tables.lisp:1.6	Sun May  8 03:18:29 2005
+++ movitz/losp/muerte/hash-tables.lisp	Tue Jun 14 01:00:25 2005
@@ -10,7 +10,7 @@
 ;;;; Author:        Frode Vatvedt Fjeld <frodef at acm.org>
 ;;;; Created at:    Mon Feb 19 19:09:05 2001
 ;;;;                
-;;;; $Id: hash-tables.lisp,v 1.6 2005/05/08 01:18:29 ffjeld Exp $
+;;;; $Id: hash-tables.lisp,v 1.7 2005/06/13 23:00:25 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -31,7 +31,8 @@
 (defstruct (hash-table (:constructor make-hash-table-object))
   test
   bucket
-  sxhash)
+  sxhash
+  count)
 
 (defun make-hash-table (&key (test 'eql) (size 47) rehash-size rehash-threshold)
   (declare (ignore rehash-size rehash-threshold))
@@ -45,16 +46,17 @@
     (make-hash-table-object
      :test test
      :bucket (make-array (* 2 size) :initial-element '--no-hash-key--)
-     :sxhash sxhash)))
+     :sxhash sxhash
+     :count 0)))
 
-(defun hash-table-count (hash-table)
-  (do* ((bucket (hash-table-bucket hash-table))
-	(length (length bucket))
-	(count 0)
-	(i 0 (+ i 2)))
-      ((>= i length) count)
-    (unless (eq (svref bucket i) '--no-hash-key--)
-      (incf count))))
+;;;(defun hash-table-count (hash-table)
+;;;  (do* ((bucket (hash-table-bucket hash-table))
+;;;	(length (length bucket))
+;;;	(count 0)
+;;;	(i 0 (+ i 2)))
+;;;      ((>= i length) count)
+;;;    (unless (eq (svref bucket i) '--no-hash-key--)
+;;;      (incf count))))
 
 (defun hash-table-iterator (bucket index)
   (when index
@@ -182,12 +184,30 @@
       ((>= c bucket-length)
        (error "Hash-table bucket is full, needs rehashing, which isn't implemented."))
     (let ((k (svref%unsafe bucket index2)))
-      (when (or (eq k '--no-hash-key--)
-		(funcall test k key))
+      (cond
+       ((eq k '--no-hash-key--)
+	(let ((new-count (1+ (hash-table-count hash-table))))
+	  (cond
+	   ((>= (truncate (* new-count 8) 3) bucket-length)
+	    ;; Rehash..
+	    (setf (hash-table-bucket hash-table) (make-array (* 2 (+ bucket-length 7))
+							     :initial-element '--no-hash-key--)
+		  (hash-table-count hash-table) 0)
+	    (do ((i 0 (+ i 2)))
+		((>= i bucket-length))
+	      (let ((old-key (svref%unsafe bucket i)))
+		(unless (eq old-key '--no-hash-key--)
+		  (setf (gethash old-key hash-table)
+		    (svref%unsafe bucket (1+ i))))))
+	    (return (setf (gethash key hash-table) value)))
+	   (t (return (setf (hash-table-count hash-table) new-count
+			    (svref%unsafe bucket index2) key
+			    (svref%unsafe bucket (1+ index2)) value))))))
+       ((funcall test k key)
 	(return (setf (svref%unsafe bucket index2) key
-		      (svref%unsafe bucket (1+ index2)) value))))
-    (when (>= (incf index2 2) bucket-length)
-      (setf index2 0))))
+		      (svref%unsafe bucket (1+ index2)) value)))
+       ((>= (incf index2 2) bucket-length)
+	(setf index2 0))))))
 
 (defun gethash-string (key-string start end hash-table &optional default (key 'identity))
   (let ((bucket (hash-table-bucket hash-table)))
@@ -223,6 +243,7 @@
       (when (or (eq x '--no-hash-key--)
 		(funcall (hash-table-test hash-table) x key))
 	(setf (svref bucket index2) '--no-hash-key--)
+	(decf (hash-table-count hash-table))
 	;; Now we must rehash any entries that might have been
 	;; displaced by the one we have now removed.
 	(do ((i (rem (+ index2 2) bucket-length)
@@ -237,6 +258,7 @@
 	(return t)))))
 
 (defun clrhash (hash-table)
+  (setf (hash-table-count hash-table) 0)
   (do* ((bucket (hash-table-bucket hash-table))
 	(bucket-length (length bucket))
 	(i 0 (+ i 2)))




More information about the Movitz-cvs mailing list