[armedbear-cvs] r13873 - trunk/abcl/src/org/armedbear/lisp
mevenson at common-lisp.net
mevenson at common-lisp.net
Mon Feb 13 10:02:37 UTC 2012
Author: mevenson
Date: Mon Feb 13 02:02:35 2012
New Revision: 13873
Log:
Restore autoload CL:MERGE as part of ANSI sort triage (See #196).
This was mistakenly removed as part of Jorge Tavares' last commit.
As an optimization, we attempt to invoke the original quicksort
implementation if the new one fails while emitting a warning to the
user.
Modified:
trunk/abcl/src/org/armedbear/lisp/sort.lisp
Modified: trunk/abcl/src/org/armedbear/lisp/sort.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/sort.lisp Sat Feb 11 14:35:40 2012 (r13872)
+++ trunk/abcl/src/org/armedbear/lisp/sort.lisp Mon Feb 13 02:02:35 2012 (r13873)
@@ -304,7 +304,41 @@
;; into one list. This may waste one outer iteration to realize.
(if (eq list-1 (cdr head))
(return list-1))))))
+;;;
+;;; MERGE
+;;;
+;;; From ECL. Should already be user-extensible as it does no type dispatch
+;;; and uses only user-extensible functions.
+(defun merge (result-type sequence1 sequence2 predicate
+ &key key
+ &aux (l1 (length sequence1)) (l2 (length sequence2)))
+ (unless key (setq key #'identity))
+ (do ((newseq (make-sequence result-type (+ l1 l2)))
+ (j 0 (1+ j))
+ (i1 0)
+ (i2 0))
+ ((and (= i1 l1) (= i2 l2)) newseq)
+ (cond ((and (< i1 l1) (< i2 l2))
+ (cond ((funcall predicate
+ (funcall key (elt sequence1 i1))
+ (funcall key (elt sequence2 i2)))
+ (setf (elt newseq j) (elt sequence1 i1))
+ (incf i1))
+ ((funcall predicate
+ (funcall key (elt sequence2 i2))
+ (funcall key (elt sequence1 i1)))
+ (setf (elt newseq j) (elt sequence2 i2))
+ (incf i2))
+ (t
+ (setf (elt newseq j) (elt sequence1 i1))
+ (incf i1))))
+ ((< i1 l1)
+ (setf (elt newseq j) (elt sequence1 i1))
+ (incf i1))
+ (t
+ (setf (elt newseq j) (elt sequence2 i2))
+ (incf i2)))))
;;;
;;; SORT
@@ -376,18 +410,46 @@
(,quicksort-call ,sequence ,mstart ,mend ,mpredicate ,mkey)))))
(defun quicksort (sequence predicate key)
- (let ((end (1- (length sequence))))
- (typecase sequence
- (simple-vector
- (if key
- (quicksort-body simple-vector svref predicate key sequence 0 end)
- (quicksort-body simple-vector svref predicate nil sequence 0 end)))
- (vector
- (if key
- (quicksort-body vector aref predicate key sequence 0 end)
- (quicksort-body vector aref predicate nil sequence 0 end))))
- sequence))
-
+ (handler-case
+ (let ((end (1- (length sequence))))
+ (typecase sequence
+ (simple-vector
+ (if key
+ (quicksort-body simple-vector svref predicate key sequence 0 end)
+ (quicksort-body simple-vector svref predicate nil sequence 0 end)))
+ (vector
+ (if key
+ (quicksort-body vector aref predicate key sequence 0 end)
+ (quicksort-body vector aref predicate nil sequence 0 end))))
+ sequence)
+ (t (e)
+ (warn "~&New quicksort implementation failed with~&'~A'.~&Trying stable implementation...~&" e)
+ (quick-sort sequence 0 (length sequence) predicate key))))
+
+;;; DEPRECATED -- to be removed in abcl-1.4
+;;; From ECL.
+;;; Alternative implementation for quick-sort SORT
+(defun quick-sort (seq start end pred key)
+ (unless key (setq key #'identity))
+ (if (<= end (1+ start))
+ seq
+ (let* ((j start) (k end) (d (elt seq start)) (kd (funcall key d)))
+ (block outer-loop
+ (loop (loop (decf k)
+ (unless (< j k) (return-from outer-loop))
+ (when (funcall pred (funcall key (elt seq k)) kd)
+ (return)))
+ (loop (incf j)
+ (unless (< j k) (return-from outer-loop))
+ (unless (funcall pred (funcall key (elt seq j)) kd)
+ (return)))
+ (let ((temp (elt seq j)))
+ (setf (elt seq j) (elt seq k)
+ (elt seq k) temp))))
+ (setf (elt seq start) (elt seq j)
+ (elt seq j) d)
+ (quick-sort seq start j pred key)
+ (quick-sort seq (1+ j) end pred key))))
;;;
;;; main SORT and STABLE-SORT function calls
More information about the armedbear-cvs
mailing list