-
Notifications
You must be signed in to change notification settings - Fork 30
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
Consolidate range macros #422
Conversation
It's tidier. Signed-off-by: mulhern <amulhern@redhat.com>
This step precedes the step where I make a submodule and put the core modules in a submodule called "core". That step is in progress: #421. |
c2c6886
to
9ba6446
Compare
usize could conceivably be larger than u64, so the cast could lose the higher order bits. Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
15431f2
to
97f562b
Compare
For consistency. Signed-off-by: mulhern <amulhern@redhat.com>
So that all can be summed. Signed-off-by: mulhern <amulhern@redhat.com>
It's less repetitive that way. Signed-off-by: mulhern <amulhern@redhat.com>
It's tidier that way. Signed-off-by: mulhern <amulhern@redhat.com>
97f562b
to
a5362c3
Compare
Have verified that current master of stratisd compiles against these changes. |
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.
Macro's are not an easy beast to review IMHO, so I stubbed up some code:
use devicemapper::Bytes;
fn main() {
// This doesn't work?
/*
let array = vec!(Bytes(0), Bytes(1), Bytes(2));
let sum: Bytes = array.iter().sum();
assert_eq!(sum, Bytes(3));
*/
assert_eq!(Bytes(100) / Bytes(10), 10u64); // This works, but inconsistent with others
// assert_eq!( Bytes(100)/Bytes(10), Bytes(10)); // Not supported?
assert_eq!(Bytes(100) / 10u64, Bytes(10));
assert_eq!(Bytes(100) / 10usize, Bytes(10));
assert_eq!(Bytes(100) * 10u64, Bytes(1000));
assert_eq!(Bytes(100) * 10usize, Bytes(1000));
assert_eq!(10u64 * Bytes(100), Bytes(1000));
assert_eq!(10usize * Bytes(100), Bytes(1000));
//assert_eq!( Bytes(10) * Bytes(10), 100u64); // Not supported, but is for / ?
//assert_eq!( Bytes(10) * Bytes(10), Bytes(100)); // Not supported ?
assert_eq!(10usize * Bytes(100), Bytes(1000));
assert_eq!(10u64 * Bytes(100), Bytes(1000));
assert_eq!(Bytes(100) % 10u64, Bytes(0));
assert_eq!(Bytes(100) % 10usize, Bytes(0));
assert_eq!(Bytes(100) % Bytes(10), Bytes(0));
//assert_eq!(10u64 % Bytes(100), Bytes(0)); // Not supported, but is for others
//assert_eq!(10usize % Bytes(100), Bytes(0)); // Not supported, but is for others
assert_eq!(Bytes(100).checked_add(Bytes(10)).unwrap(), Bytes(110));
assert_eq!(Bytes(18446744073709551615).checked_add(Bytes(1)), None);
}
I'm finding some inconsistencies in what is supported for each of the operators, see comments in code.
I believe we should have a unit test for this macro, to ensure to meets our expectations for syntax and for ensuring that the results are calculated correctly.
|
I'm all in favor of having tests, but that ought to be outside the scope of this issue, which adds no new operations. There are a limited number of tests in |
It doesn't compile. Here's the error:
Try adding turbofish
That's because sum is not defined for
and it compiles. This is the way it was, and perhaps the way it always shall be, see for example the Regarding the other questions below, they appear to be all covered by the reasoning explained in the justbytes docs: /~https://github.com/mulkieran/justbytes which I'll quote here: """ This module does not accomodate multi-dimensionality of address ranges. Consequently, multiplying one Range object by another Range object will cause an error to be raised, since bytes^2 is not representable by the module. For most uses any operation which would yield a multi-dimensional quantity is not useful. There are no plans to adapt this package so that it can accomodate multi-dimensionality of address ranges. Numerous computations with address ranges are nonsensical. For example, 2 raised to a power which is some address range, is a meaningless computation. All such operations cause an error to be raised. Some computations with precise, finite, values may yield irrational results. For example, while 2 is rational, its square root is an irrational number. There is no allowed operation on Range objects which can result in an irrational Range value. It turns out that all such operations are either nonsensical or would result in a value with an unrepresentable type. The result type of operations is a Range, where appropriate, or a subtype of Rational, where a numeric value is appropriate.
The appropriate units for Bytes(100) / Bytes(10) is none, so the result to expect is 10, specifically
Bytes(10) * Bytes(10) is 100 bytes^2. This library does not support multidimensionality. Practically speaking, few people try to allocated things in bytes^2, probably because nobody manufactures that kind of storage. This library can't express the result, and few people want it.
Modulus has a mathematical definition, closely related to that for division. What we have is pq + r = x where p is the multiplier, q is the quotient, r is the remainder (modulus), and x is the value. The result of x % p is the value r such that there is some q s.t. pq + r =x and r < p. The units have to agree. So, the units of x and the units of r must be the same. In both your examples, x is a plain number, 10u64 or 10usize. Thus, r must also be a plain number, by necessity, not bytes. In both your examples, the units of p is Bytes. That requires, for the units to correspond that the units of the unknown q that must exist be bytes^-1. Multi-dimensionality is not supported by this library, so this operation is not allowed, as the corresponding operation for division can not yield a representable result.
All the existing operations are consistent with standard arithmetic and well-established rules about dimensionality and units. The omnibus macro does not contain a full set of arithmetic operations. Operations have been added incrementally and even somewhat tentatively. If you think there are some necessary additional operations that should be added, please file an issue. We would require them to conform to the established rust standard library traits to be really useful, generally speaking. |
676d7d0
to
0ca223d
Compare
d7a70d0
to
727d656
Compare
I've filed a whole new bunch of issues, and added some tests
@tasleson review, please? |
Err, I believe it is possible to test Debug and |
In order to verify that the interface provides what we expect. Signed-off-by: mulhern <amulhern@redhat.com>
Comment them to indicate that they are complete, i.e., there are no other ways to define these operations on units and numbers. Of course, there are other dimensions to explored, like checked, saturating, and assigning operators. Leave all that out of the discussion at this time. Signed-off-by: mulhern <amulhern@redhat.com>
By convention, debug! is used for logging. Signed-off-by: mulhern <amulhern@redhat.com>
727d656
to
7e4492f
Compare
Ok, |
A completely unrelated failure in Jenkins. |
A removal of a thindev failed in test cleanup because the thindev was still busy. The removal was in the test itself. Possibly the test infrastructure should be the one to handle the removal. Anyway, trying again. |
One more issue: #426. |
There are more and better tests in range_macros.rs. Signed-off-by: mulhern <amulhern@redhat.com>
Ok. I believe it's ready again. |
@tasleson Please let me know if you have further questions or requests. |
@mulkieran IMHO this should be squashed. |
I can reduce it to a few fewer commits. But I don't think it should be squashed altogether. |
Superceded by #427. |
the guaranteed succesful
u64::from
when converting a usize to a u64.