| ## examples/sort_files.av |
| ## sort numbers in files generated by examples/gen_random_data.av |
| |
| use java.io.File; |
| |
| let q = require(__MODULE__.dir + '/qsort.av'); |
| let io = require('io'); |
| let files = count(ARGV) == 0 ? 5 : long(ARGV[0]); |
| let temp_dir = "/tmp"; |
| |
| let temp_files = seq.list(); |
| |
| for i in range(0, files) { |
| let file = "#{temp_dir}#{File.separator}data.#{i}"; |
| p("Sort file #{file}"); |
| |
| let nums = map(io.line_seq(io.file(file)), long); |
| let nums = q.sort(nums); |
| |
| let temp_file = "#{temp_dir}#{File.separator}data.#{i}.temp"; |
| let temp_file = io.file(temp_file); |
| let writer = io.writer(temp_file); |
| for j in nums { |
| write(writer, "#{j}\r\n"); |
| } |
| io.close(writer); |
| |
| seq.add(temp_files, temp_file); |
| |
| p("Wrote sorted numbers to temp file: #{temp_file}"); |
| } |
| |
| p("Begin merge sort"); |
| |
| let result_file = io.file("#{temp_dir}#{File.separator}result_data"); |
| let result_writer = io.writer(result_file); |
| |
| fn generate_source(file) { |
| let source = seq.map(); |
| let reader = io.reader(file); |
| source.val= nil; |
| source.reader = reader; |
| source.next = lambda() -> |
| let val = readLine(reader); |
| if val == nil { |
| source['val'] = nil; |
| } else { |
| source['val'] = long(val); |
| } |
| end; |
| |
| source.next(); |
| return source; |
| } |
| |
| let sources = map(temp_files, generate_source); |
| |
| fn get_min_sources(sources) { |
| if is_empty(sources) { |
| return nil; |
| } |
| let min = sources[0]; |
| let min_val = min.val; |
| |
| for s in sources { |
| if min_val == nil || s.val < min_val { |
| min = s; |
| min_val = s.val; |
| } |
| } |
| |
| return min; |
| } |
| |
| while true { |
| let min_source = get_min_sources(sources); |
| |
| if min_source == nil { |
| break; |
| } |
| |
| write(result_writer, "#{min_source.val}\r\n"); |
| min_source.next(); |
| |
| if min_source.val == nil { |
| io.close(min_source.reader); |
| seq.remove(sources, min_source); |
| } |
| } |
| |
| io.close(result_writer); |
| |
| p("Wrote sorted results to file #{result_file}"); |
| |
| p("Assert results"); |
| |
| let prev = nil; |
| for line in io.line_seq(result_file) { |
| let val = long(line); |
| |
| if prev == nil { |
| prev = val; |
| } elsif prev > val { |
| p("Fatal error, should not happen, prev #{prev} >= current #{val}"); |
| System.exit(1); |
| } else { |
| prev = val; |
| } |
| } |
| |
| p("Results are ok, perfect!"); |