visort.scm 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. ;;; The sort package -- stable vector insertion sort -*- Scheme -*-
  2. ;;; Copyright (c) 1998 by Olin Shivers.
  3. ;;; This code is open-source; see the end of the file for porting and
  4. ;;; more copyright information.
  5. ;;; Olin Shivers 10/98.
  6. ;;; Exports:
  7. ;;; vector-insert-sort < v [start end] -> vector
  8. ;;; vector-insert-sort! < v [start end] -> unspecific
  9. ;;;
  10. ;;; %vector-insert-sort! is also called from vqsort.scm's quick-sort function.
  11. (define (vector-insert-sort elt< v . maybe-start+end)
  12. (call-with-values
  13. (lambda () (vector-start+end v maybe-start+end))
  14. (lambda (start end)
  15. (let ((ans (vector-portion-copy v start end)))
  16. (%vector-insert-sort! elt< ans 0 (- end start))
  17. ans))))
  18. (define (vector-insert-sort! < v . maybe-start+end)
  19. (call-with-values
  20. (lambda () (vector-start+end v maybe-start+end))
  21. (lambda (start end)
  22. (%vector-insert-sort! < v start end))))
  23. (define (%vector-insert-sort! elt< v start end)
  24. (do ((i (+ 1 start) (+ i 1))) ; Invariant: [start,i) is sorted.
  25. ((>= i end))
  26. (let ((val (vector-ref v i)))
  27. (vector-set! v (let lp ((j i)) ; J is the location of the
  28. (if (<= j start)
  29. start ; "hole" as it bubbles down.
  30. (let* ((j-1 (- j 1))
  31. (vj-1 (vector-ref v j-1)))
  32. (cond ((elt< val vj-1)
  33. (vector-set! v j vj-1)
  34. (lp j-1))
  35. (else j)))))
  36. val))))
  37. ;;; Copyright
  38. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  39. ;;; This code is
  40. ;;; Copyright (c) 1998 by Olin Shivers.
  41. ;;; The terms are: You may do as you please with this code, as long as
  42. ;;; you do not delete this notice or hold me responsible for any outcome
  43. ;;; related to its use.
  44. ;;;
  45. ;;; Blah blah blah. Don't you think source files should contain more lines
  46. ;;; of code than copyright notice?
  47. ;;; Code tuning & porting
  48. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  49. ;;;
  50. ;;; This code is tightly bummed as far as I can go in portable Scheme.
  51. ;;;
  52. ;;; The code can be converted to use unsafe vector-indexing and
  53. ;;; fixnum-specific arithmetic ops -- the safety checks done on entry
  54. ;;; to VECTOR-INSERT-SORT and VECTOR-INSERT-SORT! are sufficient to
  55. ;;; guarantee nothing bad will happen. However, note that if you alter
  56. ;;; %VECTOR-INSERT-SORT! to use dangerous primitives, you must ensure
  57. ;;; it is only called from clients that guarantee to observe its
  58. ;;; preconditions. In the implementation, %VECTOR-INSERT-SORT! is only
  59. ;;; called from VECTOR-INSERT-SORT! and the quick-sort code in
  60. ;;; vqsort.scm, and the preconditions are guaranteed for these two
  61. ;;; clients. This should provide *big* speedups. In fact, all the
  62. ;;; code bumming I've done pretty much disappears in the noise unless
  63. ;;; you have a good compiler and also can dump the vector-index checks
  64. ;;; and generic arithmetic -- so I've really just set things up for
  65. ;;; you to exploit.
  66. ;;;
  67. ;;; If your Scheme has a faster mechanism for handling optional arguments
  68. ;;; (e.g., Chez), you should definitely port over to it. Note that argument
  69. ;;; defaulting and error-checking are interleaved -- you don't have to
  70. ;;; error-check defaulted START/END args to see if they are fixnums that are
  71. ;;; legal vector indices for the corresponding vector, etc.