{"action":"created","comment":{"url":"https://api.github.com/repos/uutils/coreutils/pulls/comments/74674560","id":74674560,"diff_hunk":"@@ -41,22 +46,105 @@ enum SortMode {\n \n struct Settings {\n     mode: SortMode,\n+    merge: bool,\n     reverse: bool,\n     outfile: Option<String>,\n     stable: bool,\n     unique: bool,\n     check: bool,\n+    compare_fns: Vec<fn(&String, &String) -> Ordering>,\n }\n \n impl Default for Settings {\n     fn default() -> Settings {\n         Settings {\n             mode: SortMode::Default,\n+            merge: false,\n             reverse: false,\n             outfile: None,\n             stable: false,\n             unique: false,\n             check: false,\n+            compare_fns: Vec::new(),\n+        }\n+    }\n+}\n+\n+struct MergeableFile<'a> {\n+    lines: Lines<BufReader<Box<Read>>>,\n+    current_line: String,\n+    settings: &'a Settings,\n+}\n+\n+// BinaryHeap depends on `Ord`. Note that we want to pop smallest items\n+// from the heap first, and BinaryHeap.pop() returns the largest, so we\n+// trick it into the right order by calling reverse() here.\n+impl<'a> Ord for MergeableFile<'a> {\n+    fn cmp(&self, other: &MergeableFile) -> Ordering {\n+        compare_by(&self.current_line, &other.current_line, &self.settings).reverse()\n+    }\n+}\n+\n+impl<'a> PartialOrd for MergeableFile<'a> {\n+    fn partial_cmp(&self, other: &MergeableFile) -> Option<Ordering> {\n+        Some(self.cmp(other))\n+    }\n+}\n+\n+impl<'a> PartialEq for MergeableFile<'a> {\n+    fn eq(&self, other: &MergeableFile) -> bool {\n+        Ordering::Equal == compare_by(&self.current_line, &other.current_line, &self.settings)\n+    }\n+}\n+\n+impl<'a> Eq for MergeableFile<'a> {}\n+\n+struct FileMerger<'a> {\n+    heap: BinaryHeap<MergeableFile<'a>>,\n+    settings: &'a Settings,\n+}\n+\n+impl<'a> FileMerger<'a> {\n+    fn new(settings: &'a Settings) -> FileMerger<'a> {\n+        FileMerger {\n+            heap: BinaryHeap::new(),\n+            settings: settings,\n+        }\n+    }\n+    fn push_file(&mut self, mut lines: Lines<BufReader<Box<Read>>>){\n+        match lines.next() {\n+            Some(Ok(next_line)) => {\n+                let mergeable_file = MergeableFile {\n+                    lines: lines,\n+                    current_line: next_line,\n+                    settings: &self.settings,\n+                };\n+                self.heap.push(mergeable_file);\n+            }\n+            _ => {}\n+        }\n+    }\n+}\n+\n+impl<'a> Iterator for FileMerger<'a> {\n+    type Item = String;\n+    fn next(&mut self) -> Option<String> {\n+        match self.heap.pop() {\n+            Some(mut current) => {\n+                match current.lines.next() {\n+                    Some(Ok(next_line)) => {\n+                        let ret = replace(&mut current.current_line, next_line);\n+                        self.heap.push(current);\n+                        return Some(ret);","path":"src/sort/sort.rs","position":null,"original_position":113,"commit_id":"cb1cffa15f11a3a2b52fa1d9afb85582c58714bc","original_commit_id":"59dbcded9a1f2d0c954c733d116ba149fc909318","user":{"login":"alsuren","id":254647,"avatar_url":"https://avatars.githubusercontent.com/u/254647?v=3","gravatar_id":"","url":"https://api.github.com/users/alsuren","html_url":"https://github.com/alsuren","followers_url":"https://api.github.com/users/alsuren/followers","following_url":"https://api.github.com/users/alsuren/following{/other_user}","gists_url":"https://api.github.com/users/alsuren/gists{/gist_id}","starred_url":"https://api.github.com/users/alsuren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alsuren/subscriptions","organizations_url":"https://api.github.com/users/alsuren/orgs","repos_url":"https://api.github.com/users/alsuren/repos","events_url":"https://api.github.com/users/alsuren/events{/privacy}","received_events_url":"https://api.github.com/users/alsuren/received_events","type":"User","site_admin":false},"body":"changed and rebased+force-pushed. I still find it tricky to spot implicit returns (and I've been using coffeescript at work for almost a year ;-) )","created_at":"2016-08-12T23:37:49Z","updated_at":"2016-08-12T23:37:49Z","html_url":"https://github.com/uutils/coreutils/pull/963#discussion_r74674560","pull_request_url":"https://api.github.com/repos/uutils/coreutils/pulls/963","_links":{"self":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/comments/74674560"},"html":{"href":"https://github.com/uutils/coreutils/pull/963#discussion_r74674560"},"pull_request":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/963"}}},"pull_request":{"url":"https://api.github.com/repos/uutils/coreutils/pulls/963","id":81027968,"html_url":"https://github.com/uutils/coreutils/pull/963","diff_url":"https://github.com/uutils/coreutils/pull/963.diff","patch_url":"https://github.com/uutils/coreutils/pull/963.patch","issue_url":"https://api.github.com/repos/uutils/coreutils/issues/963","number":963,"state":"open","locked":false,"title":"Implement sort  --merge","user":{"login":"alsuren","id":254647,"avatar_url":"https://avatars.githubusercontent.com/u/254647?v=3","gravatar_id":"","url":"https://api.github.com/users/alsuren","html_url":"https://github.com/alsuren","followers_url":"https://api.github.com/users/alsuren/followers","following_url":"https://api.github.com/users/alsuren/following{/other_user}","gists_url":"https://api.github.com/users/alsuren/gists{/gist_id}","starred_url":"https://api.github.com/users/alsuren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alsuren/subscriptions","organizations_url":"https://api.github.com/users/alsuren/orgs","repos_url":"https://api.github.com/users/alsuren/repos","events_url":"https://api.github.com/users/alsuren/events{/privacy}","received_events_url":"https://api.github.com/users/alsuren/received_events","type":"User","site_admin":false},"body":"This one is a little more involved than sort --stable. \r\n\r\n* Starts with a quick refactor that I should have done at the end of my sort --stable branch.\r\n* Second commit is a MVP of sort --merge\r\n  * Uses std::collections::BinaryHeap to hold the files (partially sorted by first line, so that the line with the next smallest first line is always available with pop(). Other sorted collections are available. I haven't benchmarked any, but I can if you want).\r\n  * Implements Iterator, to avoid storing any large arrays of strings in memory (--merge is mostly useful when you've had to split a file and sort it in chunks, because it doesn't fit in memory).\r\n* Couple of commits to fix the flags that my initial --merge implementation ignores.\r\n  * Note that --unique pulls in Itertools (for dedup()). Are we okay with that? Will rustc strip out all of the stuff that we don't use?\r\n\r\nI'd be happy to rebase these changes however you want. Also, any hints on improving my coding style would be appreciated (I'm basically only contributing to this project as a way to learn rust).\r\n\r\nNote that I've got quite a few changes in my Cargo.lock, but I had some changes in that file ever since I did my first build from master, so I've not committed them.","created_at":"2016-08-11T20:47:19Z","updated_at":"2016-08-12T23:37:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6f0bf335ed17f4e02d9c70711e15ef3a220fbe54","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/uutils/coreutils/pulls/963/commits","review_comments_url":"https://api.github.com/repos/uutils/coreutils/pulls/963/comments","review_comment_url":"https://api.github.com/repos/uutils/coreutils/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uutils/coreutils/issues/963/comments","statuses_url":"https://api.github.com/repos/uutils/coreutils/statuses/cb1cffa15f11a3a2b52fa1d9afb85582c58714bc","head":{"label":"alsuren:sort--merge","ref":"sort--merge","sha":"cb1cffa15f11a3a2b52fa1d9afb85582c58714bc","user":{"login":"alsuren","id":254647,"avatar_url":"https://avatars.githubusercontent.com/u/254647?v=3","gravatar_id":"","url":"https://api.github.com/users/alsuren","html_url":"https://github.com/alsuren","followers_url":"https://api.github.com/users/alsuren/followers","following_url":"https://api.github.com/users/alsuren/following{/other_user}","gists_url":"https://api.github.com/users/alsuren/gists{/gist_id}","starred_url":"https://api.github.com/users/alsuren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alsuren/subscriptions","organizations_url":"https://api.github.com/users/alsuren/orgs","repos_url":"https://api.github.com/users/alsuren/repos","events_url":"https://api.github.com/users/alsuren/events{/privacy}","received_events_url":"https://api.github.com/users/alsuren/received_events","type":"User","site_admin":false},"repo":{"id":64753790,"name":"coreutils","full_name":"alsuren/coreutils","owner":{"login":"alsuren","id":254647,"avatar_url":"https://avatars.githubusercontent.com/u/254647?v=3","gravatar_id":"","url":"https://api.github.com/users/alsuren","html_url":"https://github.com/alsuren","followers_url":"https://api.github.com/users/alsuren/followers","following_url":"https://api.github.com/users/alsuren/following{/other_user}","gists_url":"https://api.github.com/users/alsuren/gists{/gist_id}","starred_url":"https://api.github.com/users/alsuren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alsuren/subscriptions","organizations_url":"https://api.github.com/users/alsuren/orgs","repos_url":"https://api.github.com/users/alsuren/repos","events_url":"https://api.github.com/users/alsuren/events{/privacy}","received_events_url":"https://api.github.com/users/alsuren/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/alsuren/coreutils","description":"Cross-platform Rust rewrite of the GNU coreutils","fork":true,"url":"https://api.github.com/repos/alsuren/coreutils","forks_url":"https://api.github.com/repos/alsuren/coreutils/forks","keys_url":"https://api.github.com/repos/alsuren/coreutils/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alsuren/coreutils/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alsuren/coreutils/teams","hooks_url":"https://api.github.com/repos/alsuren/coreutils/hooks","issue_events_url":"https://api.github.com/repos/alsuren/coreutils/issues/events{/number}","events_url":"https://api.github.com/repos/alsuren/coreutils/events","assignees_url":"https://api.github.com/repos/alsuren/coreutils/assignees{/user}","branches_url":"https://api.github.com/repos/alsuren/coreutils/branches{/branch}","tags_url":"https://api.github.com/repos/alsuren/coreutils/tags","blobs_url":"https://api.github.com/repos/alsuren/coreutils/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alsuren/coreutils/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alsuren/coreutils/git/refs{/sha}","trees_url":"https://api.github.com/repos/alsuren/coreutils/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alsuren/coreutils/statuses/{sha}","languages_url":"https://api.github.com/repos/alsuren/coreutils/languages","stargazers_url":"https://api.github.com/repos/alsuren/coreutils/stargazers","contributors_url":"https://api.github.com/repos/alsuren/coreutils/contributors","subscribers_url":"https://api.github.com/repos/alsuren/coreutils/subscribers","subscription_url":"https://api.github.com/repos/alsuren/coreutils/subscription","commits_url":"https://api.github.com/repos/alsuren/coreutils/commits{/sha}","git_commits_url":"https://api.github.com/repos/alsuren/coreutils/git/commits{/sha}","comments_url":"https://api.github.com/repos/alsuren/coreutils/comments{/number}","issue_comment_url":"https://api.github.com/repos/alsuren/coreutils/issues/comments{/number}","contents_url":"https://api.github.com/repos/alsuren/coreutils/contents/{+path}","compare_url":"https://api.github.com/repos/alsuren/coreutils/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alsuren/coreutils/merges","archive_url":"https://api.github.com/repos/alsuren/coreutils/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alsuren/coreutils/downloads","issues_url":"https://api.github.com/repos/alsuren/coreutils/issues{/number}","pulls_url":"https://api.github.com/repos/alsuren/coreutils/pulls{/number}","milestones_url":"https://api.github.com/repos/alsuren/coreutils/milestones{/number}","notifications_url":"https://api.github.com/repos/alsuren/coreutils/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alsuren/coreutils/labels{/name}","releases_url":"https://api.github.com/repos/alsuren/coreutils/releases{/id}","deployments_url":"https://api.github.com/repos/alsuren/coreutils/deployments","created_at":"2016-08-02T12:11:30Z","updated_at":"2016-08-02T12:11:31Z","pushed_at":"2016-08-12T23:34:36Z","git_url":"git://github.com/alsuren/coreutils.git","ssh_url":"git@github.com:alsuren/coreutils.git","clone_url":"https://github.com/alsuren/coreutils.git","svn_url":"https://github.com/alsuren/coreutils","homepage":"","size":3385,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"uutils:master","ref":"master","sha":"1c05100cd5a4f43e1b8f66b2c8ba6dea6902df61","user":{"login":"uutils","id":5148717,"avatar_url":"https://avatars.githubusercontent.com/u/5148717?v=3","gravatar_id":"","url":"https://api.github.com/users/uutils","html_url":"https://github.com/uutils","followers_url":"https://api.github.com/users/uutils/followers","following_url":"https://api.github.com/users/uutils/following{/other_user}","gists_url":"https://api.github.com/users/uutils/gists{/gist_id}","starred_url":"https://api.github.com/users/uutils/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uutils/subscriptions","organizations_url":"https://api.github.com/users/uutils/orgs","repos_url":"https://api.github.com/users/uutils/repos","events_url":"https://api.github.com/users/uutils/events{/privacy}","received_events_url":"https://api.github.com/users/uutils/received_events","type":"Organization","site_admin":false},"repo":{"id":11847500,"name":"coreutils","full_name":"uutils/coreutils","owner":{"login":"uutils","id":5148717,"avatar_url":"https://avatars.githubusercontent.com/u/5148717?v=3","gravatar_id":"","url":"https://api.github.com/users/uutils","html_url":"https://github.com/uutils","followers_url":"https://api.github.com/users/uutils/followers","following_url":"https://api.github.com/users/uutils/following{/other_user}","gists_url":"https://api.github.com/users/uutils/gists{/gist_id}","starred_url":"https://api.github.com/users/uutils/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uutils/subscriptions","organizations_url":"https://api.github.com/users/uutils/orgs","repos_url":"https://api.github.com/users/uutils/repos","events_url":"https://api.github.com/users/uutils/events{/privacy}","received_events_url":"https://api.github.com/users/uutils/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uutils/coreutils","description":"Cross-platform Rust rewrite of the GNU coreutils","fork":false,"url":"https://api.github.com/repos/uutils/coreutils","forks_url":"https://api.github.com/repos/uutils/coreutils/forks","keys_url":"https://api.github.com/repos/uutils/coreutils/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uutils/coreutils/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uutils/coreutils/teams","hooks_url":"https://api.github.com/repos/uutils/coreutils/hooks","issue_events_url":"https://api.github.com/repos/uutils/coreutils/issues/events{/number}","events_url":"https://api.github.com/repos/uutils/coreutils/events","assignees_url":"https://api.github.com/repos/uutils/coreutils/assignees{/user}","branches_url":"https://api.github.com/repos/uutils/coreutils/branches{/branch}","tags_url":"https://api.github.com/repos/uutils/coreutils/tags","blobs_url":"https://api.github.com/repos/uutils/coreutils/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uutils/coreutils/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uutils/coreutils/git/refs{/sha}","trees_url":"https://api.github.com/repos/uutils/coreutils/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uutils/coreutils/statuses/{sha}","languages_url":"https://api.github.com/repos/uutils/coreutils/languages","stargazers_url":"https://api.github.com/repos/uutils/coreutils/stargazers","contributors_url":"https://api.github.com/repos/uutils/coreutils/contributors","subscribers_url":"https://api.github.com/repos/uutils/coreutils/subscribers","subscription_url":"https://api.github.com/repos/uutils/coreutils/subscription","commits_url":"https://api.github.com/repos/uutils/coreutils/commits{/sha}","git_commits_url":"https://api.github.com/repos/uutils/coreutils/git/commits{/sha}","comments_url":"https://api.github.com/repos/uutils/coreutils/comments{/number}","issue_comment_url":"https://api.github.com/repos/uutils/coreutils/issues/comments{/number}","contents_url":"https://api.github.com/repos/uutils/coreutils/contents/{+path}","compare_url":"https://api.github.com/repos/uutils/coreutils/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uutils/coreutils/merges","archive_url":"https://api.github.com/repos/uutils/coreutils/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uutils/coreutils/downloads","issues_url":"https://api.github.com/repos/uutils/coreutils/issues{/number}","pulls_url":"https://api.github.com/repos/uutils/coreutils/pulls{/number}","milestones_url":"https://api.github.com/repos/uutils/coreutils/milestones{/number}","notifications_url":"https://api.github.com/repos/uutils/coreutils/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uutils/coreutils/labels{/name}","releases_url":"https://api.github.com/repos/uutils/coreutils/releases{/id}","deployments_url":"https://api.github.com/repos/uutils/coreutils/deployments","created_at":"2013-08-02T16:22:56Z","updated_at":"2016-08-12T22:46:57Z","pushed_at":"2016-08-12T23:34:37Z","git_url":"git://github.com/uutils/coreutils.git","ssh_url":"git@github.com:uutils/coreutils.git","clone_url":"https://github.com/uutils/coreutils.git","svn_url":"https://github.com/uutils/coreutils","homepage":"","size":3745,"stargazers_count":2938,"watchers_count":2938,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":277,"mirror_url":null,"open_issues_count":59,"forks":277,"open_issues":59,"watchers":2938,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/963"},"html":{"href":"https://github.com/uutils/coreutils/pull/963"},"issue":{"href":"https://api.github.com/repos/uutils/coreutils/issues/963"},"comments":{"href":"https://api.github.com/repos/uutils/coreutils/issues/963/comments"},"review_comments":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/963/comments"},"review_comment":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uutils/coreutils/pulls/963/commits"},"statuses":{"href":"https://api.github.com/repos/uutils/coreutils/statuses/cb1cffa15f11a3a2b52fa1d9afb85582c58714bc"}}}}
{"actor":{"display_login":"alsuren"}}