Martin Mucha has posted comments on this change.

Change subject: core: util for removing overlaps in ranges
......................................................................


Patch Set 15:

(15 comments)

I accepted new code for overlaps util, which renders most answers irrelevant, 
since after that change, chain of successive fixes is now possible. But I 
posted the answers anyway.

http://gerrit.ovirt.org/#/c/26403/15/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java
File 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/DisjointRanges.java:

Line 6: import java.util.ListIterator;
Line 7: 
Line 8: import org.ovirt.engine.core.common.utils.Pair;
Line 9: 
Line 10: public class DisjointRanges {
> You should add some javadoc at least for the public methods.
I think this is a classic example of methods so simple and obvious that one 
should not comment them, but OK, added.
DONE.
Line 11: 
Line 12:     private List<Pair<Long, Long>> disjointRanges = new LinkedList<>();
Line 13: 
Line 14: 


Line 8: import org.ovirt.engine.core.common.utils.Pair;
Line 9: 
Line 10: public class DisjointRanges {
Line 11: 
Line 12:     private List<Pair<Long, Long>> disjointRanges = new LinkedList<>();
> Not sure why keeping state is necessary for a static computation.
ok, that static method is wrong, I do agree. Will drop it and fix OO design of 
this class.
Line 13: 
Line 14: 
Line 15:     public static List<Pair<Long, Long>> 
removePotentialOverlaps(List<Pair<Long, Long>> pairs) {
Line 16:         DisjointRanges rwo = new DisjointRanges();


Line 12:     private List<Pair<Long, Long>> disjointRanges = new LinkedList<>();
Line 13: 
Line 14: 
Line 15:     public static List<Pair<Long, Long>> 
removePotentialOverlaps(List<Pair<Long, Long>> pairs) {
Line 16:         DisjointRanges rwo = new DisjointRanges();
> What does rwo mean?
Done
Line 17:         for (Pair<Long, Long> pair : pairs) {
Line 18:             rwo.addRange(pair);
Line 19:         }
Line 20: 


Line 20: 
Line 21:         return rwo.disjointRanges;
Line 22:     }
Line 23: 
Line 24:     public void addRange(Pair<Long, Long> range) {
> Why is this method necessary? Anyone using it except the static method abov
Done
Line 25:         final long addedLeft = range.getFirst();
Line 26:         final long addedRight = range.getSecond();
Line 27: 
Line 28:         addRange(addedLeft, addedRight);


Line 27: 
Line 28:         addRange(addedLeft, addedRight);
Line 29:     }
Line 30: 
Line 31:     public void addRange(long addedLeft, long addedRight) {
> Using apache commons` LongRange this function can be simplified greatly.
ok, this is readable. I can throw away mine implementation with this as a 
replacement.
Line 32:         if (addedLeft > addedRight) {
Line 33:             throw new IllegalArgumentException("badly defined range");
Line 34:         }
Line 35: 


http://gerrit.ovirt.org/#/c/26403/15/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/DisjointRangesTest.java
File 
backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/DisjointRangesTest.java:

Line 3: import java.util.Arrays;
Line 4: import java.util.Collections;
Line 5: import java.util.List;
Line 6: 
Line 7: import org.junit.Assert;
> You should import assert methods statically.
Done
Line 8: import org.junit.Rule;
Line 9: import org.junit.Test;
Line 10: import org.junit.rules.ExpectedException;
Line 11: import org.junit.runner.RunWith;


Line 14: 
Line 15: @RunWith(Parameterized.class)
Line 16: public class DisjointRangesTest {
Line 17: 
Line 18:     private List<Pair<Long, Long>> inputRanges;
> This should be a Collection of ranges, since order shouldn't matter..
It's matter of taste. There are actually recommendations just to stick to List 
as a default if possible to make code more readable. But you're right, that to 
write more versatile code I could  use Collection as a parameter in 
DisjointRanges implementation — argumentation is: for cases when somebody will 
want to pass Set lets say. Fact that order of List is not used is not important.
Line 19:     private final List<Pair<Long, Long>> expectedRanges;
Line 20:     private final Class<? extends Exception> expectedExceptionClass;
Line 21:     private final String expectedErrorMessage;
Line 22: 


Line 15: @RunWith(Parameterized.class)
Line 16: public class DisjointRangesTest {
Line 17: 
Line 18:     private List<Pair<Long, Long>> inputRanges;
Line 19:     private final List<Pair<Long, Long>> expectedRanges;
> This should also be a Collection since there's no need for this API to obli
Need not. While you're right with Collection as input parameter in 
implementation being tested, we do know, what this class produces as an output. 
So this test 'whitetests' that created collection. It's fine. New collection 
instance is created there and filled with new data, it's valid to return 
specific instance even if you're not forced to do so. Returning Collection 
makes it no better, only potentially more problematic when dealing with 
surrounding code, since List is most common collection type. Note: List does 
not necessarily mean, that order of  elements in them are important, it only 
says, that you can use index to access elements. Arrays also is structure with 
order and no one would think about 'fixing' that. EDIT: after change in 
implementation not returning ranges in order I've changed it to Collections as 
requested(not be surprised that Collection type(which is not very common to 
use)  is now lurking through mine code).
Line 20:     private final Class<? extends Exception> expectedExceptionClass;
Line 21:     private final String expectedErrorMessage;
Line 22: 
Line 23:     @Parameterized.Parameters


Line 30:                 { Arrays.asList( pair( 1, 3 ), pair( 2, 5 ) ), 
Arrays.asList( pair( 1, 5 ) ), null, null },
Line 31:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 7 ), pair( 6, 
7) ), Arrays.asList( pair( 1, 3 ), pair(5, 7) ), null, null },
Line 32:                 { Arrays.asList( pair( 1, 2 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 2 ), pair(4, 7) ), null, null },
Line 33:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 3), pair(4, 7 ) ), null, null },
Line 34:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 11) ), Arrays.asList( pair (1, 3), pair( 3, 11 ) ), null, null },
> Not sure how 1-3 and 3-11 aren't overlapping?
Done
Line 35:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 12) ), Arrays.asList( pair( 1, 3), pair(3, 12 ) ), null, null },
Line 36:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 8) ), Arrays.asList( pair( 1, 3), pair(3, 8), pair(9, 11) ), null, 
null },
Line 37:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(-1, 8) ), Arrays.asList( pair( -1, 8), pair(9, 11 ) ), null, null }
Line 38: 


Line 31:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 7 ), pair( 6, 
7) ), Arrays.asList( pair( 1, 3 ), pair(5, 7) ), null, null },
Line 32:                 { Arrays.asList( pair( 1, 2 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 2 ), pair(4, 7) ), null, null },
Line 33:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 3), pair(4, 7 ) ), null, null },
Line 34:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 11) ), Arrays.asList( pair (1, 3), pair( 3, 11 ) ), null, null },
Line 35:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 12) ), Arrays.asList( pair( 1, 3), pair(3, 12 ) ), null, null },
> Same question for 1-3 and 3-12
Done
Line 36:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 8) ), Arrays.asList( pair( 1, 3), pair(3, 8), pair(9, 11) ), null, 
null },
Line 37:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(-1, 8) ), Arrays.asList( pair( -1, 8), pair(9, 11 ) ), null, null }
Line 38: 
Line 39:         });


Line 32:                 { Arrays.asList( pair( 1, 2 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 2 ), pair(4, 7) ), null, null },
Line 33:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 7 ), pair( 4, 
7) ), Arrays.asList( pair( 1, 3), pair(4, 7 ) ), null, null },
Line 34:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 11) ), Arrays.asList( pair (1, 3), pair( 3, 11 ) ), null, null },
Line 35:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 12) ), Arrays.asList( pair( 1, 3), pair(3, 12 ) ), null, null },
Line 36:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(3, 8) ), Arrays.asList( pair( 1, 3), pair(3, 8), pair(9, 11) ), null, 
null },
> Again, 1-3 and 3-8 overlap..
Done
Line 37:                 { Arrays.asList( pair( 1, 3 ), pair( 5, 6 ), pair( 9, 
11), pair(-1, 8) ), Arrays.asList( pair( -1, 8), pair(9, 11 ) ), null, null }
Line 38: 
Line 39:         });
Line 40:     }


Line 44:     }
Line 45: 
Line 46: 
Line 47:     @Rule
Line 48:     public ExpectedException expectedException = 
ExpectedException.none();
> Not sure why you defined this field in the middle of the class..
Done
Line 49: 
Line 50:     public DisjointRangesTest(List<Pair<Long, Long>> inputRanges,
Line 51:             List<Pair<Long, Long>> expectedRanges,
Line 52:             Class<? extends Exception> expectedExceptionClass,


Line 58:         this.expectedErrorMessage = expectedErrorMessage;
Line 59:     }
Line 60: 
Line 61:     @Test
Line 62:     public void test() throws Exception {
> You should randomize the source collection order, as you're using an implem
tests need to perform always the same if possible. Randomization is no good.
Line 63: 
Line 64:         if (expectedExceptionClass != null) {
Line 65:             this.expectedException.expect(expectedExceptionClass);
Line 66:             this.expectedException.expectMessage(expectedErrorMessage);


Line 62:     public void test() throws Exception {
Line 63: 
Line 64:         if (expectedExceptionClass != null) {
Line 65:             this.expectedException.expect(expectedExceptionClass);
Line 66:             this.expectedException.expectMessage(expectedErrorMessage);
> Why do you call with "this"?
tell me, please, why is this so important to you? I know, that 'this' can be 
removed. I asked others about their opinion and for example found a guy, which 
would actually like 'this' to be specified *everytime* when accessing field. 
Actually I don't care of of this modifier: "you want it, use it; you don't want 
to use it, don't use it.".  What objective criteria are you following that 
leads you you to the thinking "this should be removed/discussed?"
Line 67:         }
Line 68: 
Line 69:         List<Pair<Long, Long>> result = 
DisjointRanges.removePotentialOverlaps(inputRanges);
Line 70:         Assert.assertArrayEquals("Input: " + 
Arrays.toString(inputRanges.toArray()) + "\nActual: " + 
Arrays.toString(result.toArray()) + "\n" + "Expected: " + 
Arrays.toString(expectedRanges.toArray()) + "\n\n", expectedRanges.toArray(), 
result.toArray());


Line 66:             this.expectedException.expectMessage(expectedErrorMessage);
Line 67:         }
Line 68: 
Line 69:         List<Pair<Long, Long>> result = 
DisjointRanges.removePotentialOverlaps(inputRanges);
Line 70:         Assert.assertArrayEquals("Input: " + 
Arrays.toString(inputRanges.toArray()) + "\nActual: " + 
Arrays.toString(result.toArray()) + "\n" + "Expected: " + 
Arrays.toString(expectedRanges.toArray()) + "\n\n", expectedRanges.toArray(), 
result.toArray());
> This is a bad assertion since it relies on the order of the arrays, which i
this is a grey area(I hope you'll notice and like this pun). You'd expect more 
blackbox test, I wrote more whitebox one. There's nothing wrong about it; it's 
more like a strawman fallacy. You expect it to be blackbox test, then 
complaining about its whiteness. It's not blackbox test.
I do like that the implementation returns List, I think it's just fine. 
Implementation guaranties, that intervals gets sorted as a side effect, which 
is also nice. 
EDIT: I've just changed implementation as you requested, so no ordered 
side-effect, i.e. I'm comparing lists to have same content. I'll also change 
the return type to Collection for you(not be surprised that Collection 
type(which is not very common to use)  is now lurking through mine code).
Line 71:     }


-- 
To view, visit http://gerrit.ovirt.org/26403
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: Id7dbacd11b610a5885d574356a695c6e879dcdbc
Gerrit-PatchSet: 15
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Martin Mucha <mmu...@redhat.com>
Gerrit-Reviewer: Martin Mucha <mmu...@redhat.com>
Gerrit-Reviewer: Mike Kolesnik <mkole...@redhat.com>
Gerrit-Reviewer: Moti Asayag <masa...@redhat.com>
Gerrit-Reviewer: Yevgeny Zaspitsky <yzasp...@redhat.com>
Gerrit-Reviewer: automat...@ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to