{"action":"created","issue":{"url":"https://api.github.com/repos/akeranen/the-one/issues/31","repository_url":"https://api.github.com/repos/akeranen/the-one","labels_url":"https://api.github.com/repos/akeranen/the-one/issues/31/labels{/name}","comments_url":"https://api.github.com/repos/akeranen/the-one/issues/31/comments","events_url":"https://api.github.com/repos/akeranen/the-one/issues/31/events","html_url":"https://github.com/akeranen/the-one/pull/31","id":190243260,"number":31,"title":"Bugfix: compareByQueueMode() method causing IllegalArgumentException","user":{"login":"kenog","id":4290797,"avatar_url":"https://avatars.githubusercontent.com/u/4290797?v=3","gravatar_id":"","url":"https://api.github.com/users/kenog","html_url":"https://github.com/kenog","followers_url":"https://api.github.com/users/kenog/followers","following_url":"https://api.github.com/users/kenog/following{/other_user}","gists_url":"https://api.github.com/users/kenog/gists{/gist_id}","starred_url":"https://api.github.com/users/kenog/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kenog/subscriptions","organizations_url":"https://api.github.com/users/kenog/orgs","repos_url":"https://api.github.com/users/kenog/repos","events_url":"https://api.github.com/users/kenog/events{/privacy}","received_events_url":"https://api.github.com/users/kenog/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-11-18T06:07:13Z","updated_at":"2016-11-27T15:54:42Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/akeranen/the-one/pulls/31","html_url":"https://github.com/akeranen/the-one/pull/31","diff_url":"https://github.com/akeranen/the-one/pull/31.diff","patch_url":"https://github.com/akeranen/the-one/pull/31.patch"},"body":"When using the PropherRouter, I experienced the following exception:\r\n\r\nException in thread \"main\" java.lang.IllegalArgumentException: Comparison method violates its general contract!\r\nat java.util.TimSort.mergeLo(TimSort.java:777)\r\nat java.util.TimSort.mergeAt(TimSort.java:514)\r\nat java.util.TimSort.mergeCollapse(TimSort.java:441)\r\nat java.util.TimSort.sort(TimSort.java:245)\r\nat java.util.Arrays.sort(Arrays.java:1512)\r\nat java.util.ArrayList.sort(ArrayList.java:1454)\r\nat java.util.Collections.sort(Collections.java:175)\r\nat routing.ProphetRouter.tryOtherMessages(ProphetRouter.java:246)\r\nat routing.ProphetRouter.update(ProphetRouter.java:206)\r\nat core.DTNHost.update(DTNHost.java:346)\r\nat core.World.updateHosts(World.java:198)\r\nat core.World.update(World.java:167)\r\nat ui.DTNSimTextUI.runSim(DTNSimTextUI.java:29)\r\nat ui.DTNSimUI.start(DTNSimUI.java:77)\r\nat core.DTNSim.main(DTNSim.java:85)\r\n\r\nI tracked it down to being caused by the method compareByQueueMode() of the MessageRouter class. It is called by some comparators used in the Prophet- and MaxProp-based routing protocols.\r\nThe problem here is that in case the hashcodes of the two messages are equal, there is still a possibility, that the function does not return 0. In that case, the same result (-1 or 1) is returned, regardless of the order of the arguments, the method is called with. This behavior violates the contract for the compare method as defined in the [Java documentation](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-):\r\n> \"The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.\"\r\n\r\nTherefore, the above shown exception is thrown. To mitigate this, I adapted the behavior to the behavior in the FIFO case of the method. Now the function is compliant to the requirements and does not throw an exception anymore."},"comment":{"url":"https://api.github.com/repos/akeranen/the-one/issues/comments/263129662","html_url":"https://github.com/akeranen/the-one/pull/31#issuecomment-263129662","issue_url":"https://api.github.com/repos/akeranen/the-one/issues/31","id":263129662,"user":{"login":"akeranen","id":3415174,"avatar_url":"https://avatars.githubusercontent.com/u/3415174?v=3","gravatar_id":"","url":"https://api.github.com/users/akeranen","html_url":"https://github.com/akeranen","followers_url":"https://api.github.com/users/akeranen/followers","following_url":"https://api.github.com/users/akeranen/following{/other_user}","gists_url":"https://api.github.com/users/akeranen/gists{/gist_id}","starred_url":"https://api.github.com/users/akeranen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeranen/subscriptions","organizations_url":"https://api.github.com/users/akeranen/orgs","repos_url":"https://api.github.com/users/akeranen/repos","events_url":"https://api.github.com/users/akeranen/events{/privacy}","received_events_url":"https://api.github.com/users/akeranen/received_events","type":"User","site_admin":false},"created_at":"2016-11-27T15:54:42Z","updated_at":"2016-11-27T15:54:42Z","body":"Good catch. And I think your proposed fix is good too. The downside of this fix is that it changes the ordering so implementations before this fix will have different order when using this mode, but I think that's fine. @tk721 can you perhaps double check that this is OK before we merge?"}}
{"actor":{"display_login":"akeranen"}}