Advertisement
Thomas_Cloostermans

multiway-merge-sort

May 2nd, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 7.42 KB | None | 0 0
  1. #lang r6rs
  2.  
  3. ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  4. ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  5. ;-*-*                                                                 *-*-
  6. ;-*-*                    Balanced Multiway Merge Sort                 *-*-
  7. ;-*-*                                                                 *-*-
  8. ;-*-*                        Wolfgang De Meuter                       *-*-
  9. ;-*-*                   2010  Software Languages Lab                  *-*-
  10. ;-*-*                    Vrije Universiteit Brussel                   *-*-
  11. ;-*-*                                                                 *-*-
  12. ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  13. ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  14.  
  15. (library
  16.  (multiway-merge-sort)
  17.  (export sort!)
  18.  (import (rnrs base)
  19.          (rnrs control)
  20.          (rnrs io simple)
  21.          (rename (a-d sorting internal comparative quicksort-m3-bounded) (sort quicksort))
  22.          (prefix (a-d heap standard) heap:)
  23.          (prefix (a-d disk file-system) fs:)
  24.          (prefix (a-d disk disk) disk:)
  25.          (prefix (a-d file sequential input-file) in:)
  26.          (prefix (a-d file sequential output-file) out:)
  27.          (prefix (a-d sorting external outputfile-with-varying-runs) ofcr:)
  28.          (prefix (a-d sorting external inputfile-with-varying-runs) ifcr:)
  29.          (a-d scheme-tools)) ; import random-integer
  30.  
  31.  (define rlen 10)
  32.  (define irun '())
  33.  
  34.  (define (read-run! file)
  35.    (let loop
  36.      ((indx 0))
  37.      (cond ((or (= indx rlen) (not (in:has-more? file)))
  38.             indx)
  39.            (else
  40.             (heap:insert! irun (in:read file))
  41.             (loop (+ indx 1))))))
  42.  
  43.  (define (write-run! ofcr imax)
  44.    (let loop
  45.      ((indx 0))
  46.      (ofcr:write! ofcr (heap:delete! irun))
  47.      (if (< (+ indx 1) imax)
  48.          (loop (+ indx 1)))))
  49.  
  50.  (define (make-aux-bundle disks <<?)
  51.    (define p (floor (/ (vector-length disks) 2)))
  52.    (define in  (make-vector p))
  53.    (define out (make-vector p))
  54.    (define name "aux-")
  55.    (set! irun (heap:new rlen
  56.                           (lambda (c1 c2)
  57.                             (<<? c1 c2))))
  58.    (do ((i 0 (+ i 1)))
  59.      ((= i p))
  60.      (vector-set! out i (ofcr:new (vector-ref disks i)
  61.                                   (string-append name (number->string i))
  62.                                   +inf.0))
  63.      (vector-set! in i (ofcr:new (vector-ref disks (+ p i))
  64.                                  (string-append name (number->string (+ p i)))
  65.                                  +inf.0))
  66.      (ofcr:reread! (vector-ref in i))) ; we need input files in "in" (c.f. rewrite! in next phase)!
  67.    (make-bundle p in out))
  68.  
  69.  (define (delete-aux-bundle! files)
  70.    (for-each-input files
  71.                    (lambda (file indx)
  72.                      (ifcr:delete! file)))
  73.    (for-each-output files
  74.                     (lambda (file indx)
  75.                       (ofcr:delete! file))))
  76.  
  77.  (define (make-bundle p in out)
  78.    (cons p (cons in out)))
  79.  (define (order files)
  80.    (car files))
  81.  (define (input files indx)
  82.    (vector-ref (cadr files) indx))
  83.  (define (output files indx)
  84.    (vector-ref (cddr files) indx))
  85.  
  86.  (define (for-each-input files proc)
  87.    (define nrfs (order files))
  88.    (do ((indx 0 (+ indx 1)))
  89.      ((= indx nrfs))
  90.      (proc (input files indx) indx)))
  91.  (define (for-each-output files proc)
  92.    (define nrfs (order files))
  93.    (do ((indx 0 (+ indx 1)))
  94.      ((= indx nrfs))
  95.      (proc (output files indx) indx)))
  96.  
  97.  (define (swap-files!? files)
  98.    (define (switch-refs)
  99.      (define tmp input)
  100.      (set! input  output)
  101.      (set! output tmp))
  102.    (define p (order files))
  103.    ;(define old-run-length (ofcr:run-length (output files 0)))
  104.    ;(define new-run-length (* p old-run-length))
  105.    (for-each-output files (lambda (outp indx)
  106.                             (ofcr:reread! outp )));old-run-length)))
  107.    (for-each-input files (lambda (inpt indx)
  108.                            (ifcr:rewrite! inpt )));new-run-length)))
  109.    (switch-refs)
  110.    (ifcr:has-more? (input files 1))
  111.    )
  112.  
  113.  (define (next-file indx p)
  114.    (mod (+ indx 1) p))
  115.  
  116.  (define (write-loop file buffer)
  117.    (when (not (heap:empty? buffer))
  118.      (ofcr:write! file (heap:delete! buffer))
  119.      (write-loop file buffer)
  120.      )
  121.    )
  122.  
  123.  
  124. (define (distribute! inpt files <<?)
  125.   (define buffer (heap:new rlen (lambda (c1 c2)
  126.                             (<<? c1 c2))))
  127.   (define p (order files))
  128.   (let loop ((indx 0))
  129.    
  130.     (cond ((not (in:has-more? inpt))
  131.            (write-loop (output files indx) buffer)
  132.            (swap-files!? files)
  133.            )
  134.           ((heap:empty? buffer) (heap:insert! buffer (in:read inpt)) (loop indx))
  135.           ((<<? (in:peek inpt) (heap:peek buffer))
  136.            (write-loop (output files indx) buffer)
  137.            (ofcr:new-run! (output files indx))
  138.            (loop (next-file indx p))
  139.            )
  140.           ((heap:full? buffer)
  141.            (ofcr:write! (output files indx) (heap:delete! buffer))
  142.            (heap:insert! buffer (in:read inpt))
  143.            (loop indx))
  144.           (else (heap:insert! buffer (in:read inpt))
  145.            (loop indx))
  146.           )
  147.     )
  148.   )
  149.          
  150.          
  151. ; (define (distribute! inpt files <<?)
  152. ;   (define p (order files))
  153. ;   (let loop
  154. ;     ((indx 0))
  155. ;     (let ((nmbr (read-run! inpt)))
  156. ;       (when (not (= nmbr 0))
  157. ;         ;(quicksort irun nmbr <<?)
  158. ;         (write-run! (output files indx) nmbr)
  159. ;         (ofcr:new-run! (output files indx))
  160. ;         (loop (next-file indx p)))))
  161. ;   (swap-files!? files))
  162.  
  163.  (define (collect! files inpt)
  164.    (define last (input files 0))
  165.    (newline)
  166.    (display 'collect)
  167.    (in:rewrite! inpt)
  168.    (let loop
  169.      ((rcrd (ifcr:read last)))
  170.      (out:write! inpt rcrd)
  171.      (if (ifcr:run-has-more? last)
  172.          (loop (ifcr:read last))))
  173.    (out:close-write! inpt))
  174.  
  175.  (define (read-from-files? heap files)
  176.    (for-each-input
  177.     files
  178.     (lambda (file indx)
  179.      
  180.       (when (ifcr:has-more? file)
  181.         (newline)
  182.         (display 'problem)
  183.         (if (not (ifcr:run-has-more? file))
  184.             (ifcr:new-run! file)
  185.             )
  186.        
  187.         (heap:insert! heap (cons indx (ifcr:read file)))
  188.         (newline)
  189.         (display "no problem"))
  190.       ))
  191.    (not (heap:empty? heap)))
  192.  
  193.  (define (serve heap files)
  194.    (define el (heap:delete! heap))
  195.    (define indx (car el))
  196.    (define rcrd (cdr el))
  197.    (if (ifcr:run-has-more? (input files indx))
  198.        (heap:insert! heap (cons indx (ifcr:read (input files indx)))))
  199.    rcrd)
  200.  
  201.  (define (merge! files <<?)
  202.    (define heap (heap:new (order files)
  203.                           (lambda (c1 c2)
  204.                             (<<? (cdr c1) (cdr c2)))))
  205.    (let merge-files
  206.      ((out-idx 0))
  207.      (cond ((read-from-files? heap files)
  208.             (let merge-p-runs
  209.               ((rcrd (serve heap files)))
  210.               (ofcr:write! (output files out-idx) rcrd)
  211.               (if (not (heap:empty? heap))
  212.                   (merge-p-runs (serve heap files))))
  213.            
  214.             (ofcr:new-run! (output files out-idx))
  215.             (merge-files (next-file out-idx (order files))))
  216.            ((swap-files!? files)
  217.             (merge-files 0)))))
  218.  
  219.  (define (sort! file dsks <<?)
  220.    (define files (make-aux-bundle dsks <<?))
  221.    (distribute! file files <<?)
  222.    (merge! files <<?)
  223.    (collect! files file)
  224.    (delete-aux-bundle! files)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement