liveBook · Manning

Psort

As explained in Clojure: The Essential Reference

psort is a book-specific sorting function that processes externally stored chunks in parallel and lazily exposes their merged ordering.

psort sorts data too large to keep in memory by splitting the input into chunks, sorting those chunks in parallel, writing them to disk, and lazily merging them into one ordered sequence. section 8.3.5

Its operation has two practical phases:

  • Partition an id-range, fetch each portion, sort it, and save the ordered chunk externally. section 8.3.5
  • Compare the first value from each chunk, emit the winner, and lazily load subsequent values as needed. section 8.3.5
  • Accept either the default compare comparator or a supplied comparator. section 8.3.5

Consume only the beginning

(take 10 (psort (IdRange. 0 10000))) ;; (0 1 2 3 4 5 6 7 8 9) The result exposes an ordered sequence while avoiding a full in-memory realization unless the caller requests it. section 8.3.5

(defn sort-all                ; #1
  ([colls]
   (sort-all compare colls))
  ([cmp colls]
   (lazy-seq
     (if (some identity (map first colls))
       (let [[[win & lose] & xs] (sort-by first cmp colls)] ; #2
         (cons win (sort-all cmp (if lose (conj xs lose) xs))))))))

(defn- load-chunk [fname]
  (read-string (slurp fname)))

(defn psort                   ; #3
  ([id-range]
   (psort compare id-range))
  ([cmp id-range]
   (->> (r/fold 10000 concat (partial sort cmp) id-range)
        (map load-chunk)
        (sort-all cmp))))

(take 10 (psort (IdRange. 0 10000))) ; #4
;; (0 1 2 3 4 5 6 7 8 9)

Browse the implementation of sort-all, chunk loading, psort arities, and the lazy merge example. section 8.3.5

How Clojure: The Essential Reference covers it

How deep it goes
Explains parallel chunk creation, disk storage, comparator configuration, and lazy multiway merging through implementation code.
Examples
Uses IdRange, temporary chunk files, sort-all, and a take expression producing the first ten values.
What it assumes
Assumes an id-range data provider, sortable values, and familiarity with Clojure reducers and sequences.
What you can do after
Apply it via psort to obtain ordered results without loading the entire dataset into memory.
How it connects
Connects reducers, comparators, temporary files, lazy sequences, and external sorting.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.