-
Notifications
You must be signed in to change notification settings - Fork 84
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
Fix offset in acquire, inside() method #498
Conversation
9db8446
to
4066cfd
Compare
else | ||
acquireNextByteStore0(offset + adding - 1, false); | ||
if (adding > 0 && !bytesStore.inside(offset, checkSize0(adding))) { | ||
acquireNextByteStore0(offset, false); |
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 old else is the cause of #452, this bug is repeated throughout the bytes implementations. The basic error is
if (!bytesStore.inside(offset, length)) {
bytesStore.acquire(offset + length);
}
This works most of the time when you're writing forwards sequentially because if what you're writing won't fit in currentStore + offset, it'll usually fit in the store that gets acquired (nextStore) because that will start at currentStore + 1
The error shows up in the forward direction when you jump ahead a cycle (see what I added to the test)
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.
e.g.
for a mapped file with chunksize 100, overlap 20
the sequential case
writeLong(50, some-long); // positioned in the first chunk
writeLong(119, some-long);
-> if (!bytesStore.inside(119, 8)) { // false
bytesStore.acquire(127); // loads second store, which happens to contain 119->127, so OK
the non-sequential case (broken)
writeLong(50, some-long); // positioned in the first chunk
writeLong(199, some-long);
-> if (!bytesStore.inside(199, 8)) { // false
bytesStore.acquire(207); // loads third store, which does not contain 199->207, so FAIL
the backwards traversal case (broken)
writeLong(150, some-long); // positioned in the second chunk
writeLong(99, some-long);
-> if (!bytesStore.inside(99, 8)) { // false
bytesStore.acquire(107); // loads second store, which does not contain 99->107, so FAIL
if (!bytesStore.inside(offset, 1)) { | ||
bytesStore = acquireNextByteStore0(offset + 1, false); | ||
if (!bytesStore.inside(offset, 2)) { | ||
bytesStore = acquireNextByteStore0(offset, false); |
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.
example of the bug
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.
Agreed, I saw that on Monday.
if (!bytesStore.inside(offset, 3)) { | ||
bytesStore = acquireNextByteStore0(offset + 3, false); | ||
if (!bytesStore.inside(offset, 4)) { | ||
bytesStore = acquireNextByteStore0(offset, false); |
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.
and again
if (!bytesStore.inside(offset, 7)) { | ||
bytesStore = acquireNextByteStore0(offset + 7, false); | ||
if (!bytesStore.inside(offset, 8)) { | ||
bytesStore = acquireNextByteStore0(offset, false); |
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.
and again
if (!bytesStore.inside(readPosition, 3)) { | ||
bytesStore = acquireNextByteStore0(readPosition + 3, true); | ||
if (!bytesStore.inside(readPosition, 4)) { | ||
bytesStore = acquireNextByteStore0(readPosition, true); |
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.
and again
public boolean inside(@NonNegative long offset, @NonNegative long buffer) { | ||
return false; | ||
public boolean inside(@NonNegative long offset, @NonNegative long bufferSize) { | ||
return offset == 0 && bufferSize == 0; |
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.
an array of zero length at position zero is inside the empty store
// go back to the first store | ||
checkWritePosition(bytes, CHUNK_SIZE - 1, 0); | ||
// write to just before the start of the third bytes store (i.e. not in the 1st plus overlap or 2nd plus overlap) | ||
checkWritePosition(bytes, 3 * CHUNK_SIZE - size + 1, 2 * CHUNK_SIZE); |
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 reproduces the bug. If you pop the last commit (with the fix in it) off, you will see it blow.
* as the 1st byte is written at offset, and the last at offset+n-1 | ||
* <p> | ||
* Use this test to determine if an offset is considered safe to write to. Note that it checks we are | ||
* inside the BytesStore limits *including* the overlap |
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 still feel strongly that we make this intuitive rather than writing a convoluted comment as to why it's not and how to use it "correctly".
10aedc9
to
d47b069
Compare
d47b069
to
d581211
Compare
@@ -213,21 +212,21 @@ public long start() { | |||
@Override | |||
public boolean compareAndSwapInt(@NonNegative long offset, int expected, int value) | |||
throws BufferOverflowException, IllegalStateException { | |||
writeCheckOffset(offset, 4); | |||
writeCheckOffset(offset, Integer.BYTES); |
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.
nice
7317da2
to
80530a3
Compare
…onstants, ensure overlapSize <= chunkSize, remove minimum overlapSize. Fixes #481
80530a3
to
f359b12
Compare
Kudos, SonarCloud Quality Gate passed! |
Fixes #481
Hide whitespace when reviewing, one file had an extra indent through the whole file that I removed