-
Notifications
You must be signed in to change notification settings - Fork 7
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
Resolving TODO: PrimVar for UniqCounter #508
Conversation
-- | ||
-- TODO: could we use a PrimVar here? | ||
newtype UniqCounter m = UniqCounter (StrictMVar m Word64) | ||
newtype UniqCounter m = UniqCounter (PrimVar (PrimState m) Word64) |
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.
newtype UniqCounter m = UniqCounter (PrimVar (PrimState m) Word64) | |
newtype UniqCounter s = UniqCounter (PrimVar s Word64) |
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.
Changing (PrimState m)
to s
here causes a lot of "upstream" breakages in the type-class constraint which call functions that interact with UniqCounter
. Generally it requires creating a new type variable s
in addition to the existing m
, and adding PrimState m ~ s
in a lot of places.
Is there a technical reason to make this change? Performance or memory implications I might not be aware of?
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.
It's not incorrect, it's just more restrictive to require m
instead of s
. We should add at least a TODO to change it, even if it would cause code changes elsewhere
bc26381
to
6387479
Compare
|
||
-- | | ||
-- This call to @unsafeCoerce@ relies on the machine's binary representation of | ||
-- the @Int@ type to be safe. The binary representation must be 64-bots wide, a |
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 @Int@ type to be safe. The binary representation must be 64-bots wide, a | |
-- the @Int@ type to be safe. The binary representation must be 64-bits wide, a |
-- | ||
-- TODO: could we use a PrimVar here? | ||
newtype UniqCounter m = UniqCounter (StrictMVar m Word64) | ||
newtype UniqCounter m = UniqCounter (PrimVar (PrimState m) Word64) |
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.
It's not incorrect, it's just more restrictive to require m
instead of s
. We should add at least a TODO to change it, even if it would cause code changes elsewhere
newtype UniqCounter m = UniqCounter (StrictMVar m Word64) | ||
-- Additionally, it is safe to @unsafeCoerce@ between `Int` and `Word64` for | ||
-- the same reason, the use must guarantee a 2's compliment representation for | ||
-- signed integral types. See thethis module's @convert@ function for more info. |
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.
-- signed integral types. See thethis module's @convert@ function for more info. | |
-- signed integral types. See this module's @convert@ function for more info. |
-- | | ||
-- This call to @unsafeCoerce@ relies on the machine's binary representation of |
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.
-- | | |
-- This call to @unsafeCoerce@ relies on the machine's binary representation of | |
-- | This call to @unsafeCoerce@ relies on the machine's binary representation of |
-- TODO: could we use a PrimVar here? | ||
newtype UniqCounter m = UniqCounter (StrictMVar m Word64) | ||
-- Additionally, it is safe to @unsafeCoerce@ between `Int` and `Word64` for | ||
-- the same reason, the use must guarantee a 2's compliment representation for |
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 same reason, the use must guarantee a 2's compliment representation for | |
-- the same reason, the use must guarantee a 2's complement representation for |
-- the @Int@ type to be safe. The binary representation must be 64-bots wide, a | ||
-- given guarantee by the user according to the @README.md@. Additionally, the | ||
-- binary representation of @Int@ must form an additive ring which is homomorphic | ||
-- with @Word64@ (such as 2's compliment); i.e.: |
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.
-- with @Word64@ (such as 2's compliment); i.e.: | |
-- with @Word64@ (such as 2's complement); i.e.: |
-- @ | ||
-- let limit = maxBound :: Int | ||
-- in forall (x :: Int). | ||
-- (unsafeCoerce limit :: Word64) + (unsafeCoerce x :: Word64) === unsafeCoerce (limit + x) | ||
-- @ |
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.
Let's make this into a test!
-- TODO: could we use a PrimVar here? | ||
newtype UniqCounter m = UniqCounter (StrictMVar m Word64) | ||
-- Additionally, it is safe to @unsafeCoerce@ between `Int` and `Word64` for | ||
-- the same reason, the use must guarantee a 2's compliment representation for |
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.
Are there cases where ints are not represented as 2's complement? Does it depend on GHC, gcc
, the OS, the machine architecture?
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.
I don't think there's any strong reason why the counter should be represented by a Word64
or an Int
. So I don't think we need to get into the weeds about unsafe conversions. We can both UniqueCounter
and Unique
as Int
and convert to RunNumber
safely.
Similarly, I'm not sure there's any strong reason that RunNumber
needs to be Word64
rather than Int
.
-- @ | ||
{-# INLINE convert #-} | ||
convert :: Int -> Word64 | ||
convert = unsafeCoerce |
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.
I don't see why we need to unsafely coerce. An ordinary conversion should be just fine, no?
I'll take this one over since @recursion-ninja is away. I'm going to simplify to use |
We only use |
6387479
to
d406ff0
Compare
We still can. We initialise the unique counter at 0, so they'll all be positive. |
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
I was thinking about when the counter would wrap around from |
d406ff0
to
6fa48f1
Compare
It certainly would not happen for a Cardano node since those only run on 64bit platforms. And for any other use case on a 32bit platform, it would only happen after 2 billion table duplications within the same session. At which point the bigger problem would be the clashes not the negative number. |
RunNumber is rather unnecessarily a Word64 when Int would do just fine and involve fewer conversions. Also add TableId and CursorId newtypes (rather than raw Word64) and make these use Int too for the same reasons. Add and use direct conversion functions uniqueTo{Table,Cursor}Id.
6fa48f1
to
4dcde00
Compare
Description
Updating the mutable pointer type of
UniqCounter
to be aPrimVar
rather than aStrictMVar
.