+ (luna-define-class elmo-location-map ()
+ (location-alist location-hash max-number)))
+
+(defmacro elmo-location-map-alist (entity)
+ `(luna-slot-value ,entity 'location-alist))
+
+(defmacro elmo-location-map-set-alist (entity value)
+ `(luna-set-slot-value ,entity 'location-alist ,value))
+
+(defmacro elmo-location-map-hash (entity)
+ `(luna-slot-value ,entity 'location-hash))
+
+(defmacro elmo-location-map-set-hash (entity value)
+ `(luna-set-slot-value ,entity 'location-hash ,value))
+
+(defmacro elmo-location-map-max-number (entity)
+ `(luna-slot-value ,entity 'max-number))
+
+(defmacro elmo-location-map-set-max-number (entity value)
+ `(luna-set-slot-value ,entity 'max-number ,value))
+
+
+(defmacro elmo-location-map-key (number)
+ `(concat "#" (int-to-string ,number)))
+
+(defun elmo-location-map-load (location-map directory)
+ (elmo-location-map-setup
+ location-map
+ (elmo-msgdb-location-load directory)))
+
+(defun elmo-location-map-save (location-map directory)
+ (let ((alist (elmo-location-map-alist location-map)))
+ (elmo-msgdb-location-save
+ directory
+ (cons (cons (elmo-location-map-max-number location-map) nil)
+ alist))))
+
+(defun elmo-location-map-setup (location-map &optional locations)
+ "Setup internal data of LOCATION-MAP by LOCATIONS.
+Return a location alist."
+ (let ((hash (elmo-make-hash (length locations)))
+ (max-number 0))
+ ;; Set number-max and hashtables.
+ (dolist (pair locations)
+ (setq max-number (max max-number (car pair)))
+ (when (cdr pair)
+ (elmo-set-hash-val (cdr pair) pair hash)
+ (elmo-set-hash-val (elmo-location-map-key (car pair)) pair hash)))
+ (let ((inhibit-quit t))
+ (elmo-location-map-set-max-number location-map max-number)
+ (elmo-location-map-set-hash location-map hash)
+ (elmo-location-map-set-alist location-map locations))))
+
+(defun elmo-location-map-teardown (location-map)
+ (elmo-location-map-set-alist location-map nil)
+ (elmo-location-map-set-hash location-map nil))
+
+(defun elmo-location-map-update (location-map locations)
+ "Update location alist in LOCATION-MAP by LOCATIONS.
+Return new location alist."
+ (let ((old-hash (elmo-location-map-hash location-map))
+ (new-hash (elmo-make-hash (length locations)))
+ (number (elmo-location-map-max-number location-map))
+ new-alist)
+ (setq new-alist
+ (mapcar
+ (lambda (location)
+ (let ((entry (or (elmo-get-hash-val location old-hash)
+ (cons (setq number (1+ number)) location))))
+ (elmo-set-hash-val (elmo-location-map-key (car entry))
+ entry
+ new-hash)
+ (elmo-set-hash-val location entry new-hash)
+ entry))
+ locations))
+ (let ((inhibit-quit t))
+ (elmo-location-map-set-max-number location-map number)
+ (elmo-location-map-set-hash location-map new-hash)
+ (elmo-location-map-set-alist location-map new-alist))))
+
+(defun elmo-location-map-remove-numbers (location-map numbers)
+ (let ((alist (elmo-location-map-alist location-map))
+ (hash (elmo-location-map-hash location-map)))
+ (dolist (number numbers)
+ (let* ((key (elmo-location-map-key number))
+ (entry (elmo-get-hash-val key hash))
+ (inhibit-quit t))
+ (elmo-location-map-set-alist
+ location-map
+ (setq alist (delq entry alist)))
+ (elmo-clear-hash-val key hash)
+ (elmo-clear-hash-val (cdr entry) hash)))))
+
+(defun elmo-map-message-number (location-map location)
+ "Return number of the message in the MAPPER with LOCATION."
+ (car (elmo-get-hash-val
+ location
+ (elmo-location-map-hash location-map))))
+
+(defun elmo-map-message-location (location-map number)
+ "Return location of the message in the MAPPER with NUMBER."
+ (cdr (elmo-get-hash-val
+ (elmo-location-map-key number)
+ (elmo-location-map-hash location-map))))