-
-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
im-util: Add Sort, SortBy adapters #46
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good, thanks!, but we need to add tests for Sort
and SortBy
:-). I know the implementation is shared between all the sort stream adapters, but… eh…
I started updating the tests and I think I found a bug. Check this test which currently passes (ignore the copy-pasted comments), I don't see how that could make any sense. |
Yeah so this is unrelated to my changes, this also succeeds on #[test]
fn bug() {
let mut ob = ObservableVector::<char>::from(vector!['d', 'e', 'b', 'g']);
let (values, mut sub) = ob.subscribe().sort_by(&|a, b| b.cmp(a));
assert_eq!(values, vector!['g', 'e', 'd', 'b']);
ob.set(0, 'c');
assert_next_eq!(sub, VectorDiff::Remove { index: 2 });
assert_next_eq!(sub, VectorDiff::Insert { index: 2, value: 'c' });
drop(ob);
assert_closed!(sub);
} |
This isn’t technically a bug. The Remove + Insert can indeed be simplified into a single Set if the index is the same. I can add this as an optimisation, which is likely to be necessary for performance reason. Good catch. |
Right. Just very unexpected :) I guess I should finish the tests independently of that optimization. |
Hmm, actually, this optimisation is already present, and even tested. The test: eyeball/eyeball-im-util/tests/it/sort.rs Lines 337 to 343 in 71e0a72
The code: eyeball/eyeball-im-util/src/vector/sort.rs Lines 504 to 531 in 71e0a72
|
Actually, it's not a bug… Taking this code: let mut ob = ObservableVector::<char>::from(vector!['d', 'e', 'b', 'g']);
let (values, mut sub) = ob.subscribe().sort_by(&|a, b| b.cmp(a));
assert_eq!(values, vector!['g', 'e', 'd', 'b']);
ob.set(0, 'c');
assert_next_eq!(sub, VectorDiff::Remove { index: 2 });
assert_next_eq!(sub, VectorDiff::Insert { index: 2, value: 'c' }); So, when doing eyeball/eyeball-im-util/src/vector/sort.rs Lines 488 to 502 in 71e0a72
The And indeed, if you change let mut ob = ObservableVector::<char>::from(vector!['d', 'e', 'b', 'g']);
let (values, mut sub) = ob.subscribe().sort_by(&|a, b| a.cmp(b));
assert_eq!(values, vector!['b', 'd', 'e', 'g']);
ob.set(0, 'c');
assert_next_eq!(sub, VectorDiff::Set { index: 1, value: 'c' });
drop(ob);
assert_closed!(sub); I know, it's surprising, but it's indeed perfectly logical. One thing that is questionnable though: is it correct to assume that if 2 indices are side-by-side, we can optimise it, like if we have |
OK, see #49 for the fix. Thanks for noticing this! |
eyeball-im-util/tests/it/sort_by.rs
Outdated
/* // Another value, that is moved to the left. | ||
ob.set(0, 'a'); | ||
assert_next_eq!(sub, VectorDiff::Remove { index: 1 }); | ||
assert_next_eq!(sub, VectorDiff::Insert { index: 0, value: 'a' }); | ||
|
||
// Another value, that is moved to the right. | ||
ob.set(0, 'f'); | ||
assert_next_eq!(sub, VectorDiff::Remove { index: 0 }); | ||
assert_next_eq!(sub, VectorDiff::Insert { index: 2, value: 'f' }); | ||
|
||
// Another value, that is moved to the right-most position. | ||
ob.set(0, 'h'); | ||
assert_next_eq!(sub, VectorDiff::Remove { index: 2 }); | ||
assert_next_eq!(sub, VectorDiff::Insert { index: 3, value: 'h' }); | ||
|
||
// Same operation, at another index, just for fun. | ||
ob.set(2, 'f'); | ||
assert_next_eq!(sub, VectorDiff::Remove { index: 0 }); | ||
assert_next_eq!(sub, VectorDiff::Insert { index: 1, value: 'f' }); | ||
|
||
// Items in the vector have been updated and are not sorted. | ||
assert_eq!(*ob, vector!['h', 'e', 'f', 'g']); */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I didn't finish the tests after finding the issue you fixed in #49. Updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
No description provided.