jonhoo / flurry

A port of Java's ConcurrentHashMap to Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

resize_stamp is positive even though it is supposed to be negative

soruh opened this issue · comments

commented

The resize stamp returned by the resize_stamp function

Must be negative when shifted left by RESIZE_STAMP_SHIFT.

(See: ConcurrentHashMap.java:2253)
but it appears to always be positive. (At least through simple "print debugging" while running the tests)

This might be a simple misunderstanding on my part, so feel free to close this issue if I just got something wrong.

Hmm, my read on that is that the return value from resize_stamp itself is not necessarily negative, but its return value, when it is shifted left by RESIZE_STAMP_SHIFT, must be negative. It is not clear to me that we uphold that though. I think there is an expectation that we are using 32-bit integers, which we are not (we're using isize), so we either need to fix that, or we need to use std::mem::size_of::<isize>() * 8 in place of 32 to define MAX_RESIZERS and RESIZE_STAMP_SHIFT, and half that to define RESIZE_STAMP_BITS. Some unit tests for that would be excellent!

commented

What I saw is the shifted value not being negative, that's why I was concerned, especially since we set size_ctl and it must be negative to indicate a resize.

I'll see if I can write some unit tests for that and try to fix it. I'll finish up reserve first though.

I think what they are getting at is that if you shift a 1 all the way to the leftmost bit, the number should become negative (the leftmost bit is usually the "sign" bit). We should make sure that is indeed the case in our code, because presumably they rely on that fact!

commented

That's what I assumed as well and that's why I was concerned that our code apparently doesn't do this.

I think it might also have something to do with how rust & java handle shift differently (in java we have >> and >>> for signed and unsigned shift respectively), but I think rust just decides what to do based on the type (so on a u32 we do an unsigned shift and on a i32 we do a signed shift) am not 100% certain on that though.

We'll probably need to cast to u32, shift, cast to i32 and then cast to isize.
(If isize is i64 our sign bit would be in the wrong place: rust playground)

commented

We should make sure that is indeed the case in our code, because presumably they rely on that fact!

They rely on it quite heavily, since it controls if the map is resizing or not...

Actually, it does look like << will do the right thing (that is, eventually turn the number negative). We just need to make sure those constants have the right values. Currently I think they are right of an i32, but we are using isize, so that won't be right on anything but 32-bit platforms.

commented

e54f12e for #28 should fix this