Changeset 7693 for branches/working-0710


Ignore:
Timestamp:
Nov 20, 2007, 3:06:48 PM (12 years ago)
Author:
gb
Message:

New hash-table iteration interface.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/working-0710/ccl/lib/hash.lisp

    r7511 r7693  
    210210
    211211
    212 (defun start-hash-table-iterator (hash state)
    213   (let (vector locked)
    214     (unless (hash-table-p hash)
    215       (setf (hti.hash-table state) nil)         ; for finish-hash-table-iterator
    216       (report-bad-arg hash 'hash-table))
    217 
    218     (without-interrupts
    219      (setf (hti.hash-table state) hash)
    220      (setf (hti.lock state) (setq locked (not (eq :readonly (lock-hash-table-for-map hash)))))
    221      (when locked (%lock-gc-lock))
    222      (setq vector (nhash.vector hash))
    223      (setf (hti.vector state) vector)
    224      (setf (hti.index state) (nhash.vector-size vector))
    225      (setf (hti.prev-iterator state) (nhash.iterator hash)
    226            (nhash.iterator hash) state)
    227      (when (%needs-rehashing-p hash)
    228        (%rehash hash)))))
    229  
    230 ;;; this is as fast as the lappy version
    231 
    232 (defun do-hash-table-iteration (state)
    233   (let ((vector (hti.vector state))
    234         (index (hti.index state))
    235         key value)
    236     (declare (optimize (speed 3) (safety 0)))
    237     (if (setf (hti.index state)
    238               (if index
    239                 (loop
    240                   (if (eq index 0)(return (setq index nil)))
    241                   (locally (declare (fixnum index))
    242                     (setq index (- index 1))
    243                     (let* ((vector-index (index->vector-index index)))
    244                       (declare (fixnum vector-index))
    245                       (setq key (%svref vector vector-index))
    246                       (unless (or (eq key (%unbound-marker))
    247                                   (eq key (%slot-unbound-marker)))
    248                         (setq value (%svref vector (the fixnum (1+ vector-index))))
    249                         (return index)))))))
    250       (let* ((hash (hti.hash-table state)))
    251         (setf (nhash.vector.cache-idx (setq vector (nhash.vector hash))) index
    252               (nhash.vector.cache-key vector) key
    253               (nhash.vector.cache-value vector) value)
    254         (values t key value)))))
    255 
    256 (defun finish-hash-table-iterator (state)
    257   (without-interrupts
    258    (let ((hash (hti.hash-table state))
    259          (locked (hti.lock state)))
    260      (when hash
    261        (setf (hti.hash-table state) nil)
    262        (when locked
    263          (unlock-hash-table hash nil)
    264          (%unlock-gc-lock))
    265        (when (eq state (nhash.iterator hash))
    266          (setf (nhash.iterator hash) (hti.prev-iterator state)))
    267        (setf
    268         (hti.index state)  nil
    269         (hti.vector state) nil
    270         (hti.lock state)   nil)))))
     212
     213(defun next-hash-table-iteration (state)
     214  (do* ((hash (nhti.hash-table state))
     215        (index (nhti.index state) (1+ index))
     216        (keys (nhti.keys state))
     217        (nkeys (nhti.nkeys state))
     218        (missing (cons nil nil)))
     219       ((>= index nkeys)
     220        (setf (nhti.index state) nkeys)
     221        (values nil nil nil))
     222    (declare (fixnum index nkeys)
     223             (simple-vector keys)
     224             (dynamic-extent missing))
     225    (let* ((key (svref keys index))
     226           (value (gethash key hash missing)))
     227      (unless (eq value missing)
     228        (setf (nhti.index state) (1+ index))
     229        (return (values t key value))))))
     230
     231
    271232
    272233(defun maphash (function hash-table)
Note: See TracChangeset for help on using the changeset viewer.