nicktindall commented on PR #16865:
URL: https://github.com/apache/lucene/pull/16865#issuecomment-6380166939
Thanks both. I've pushed a version that uses an `AtomicLong` with
compare-and-set, as @uschindler suggested, and that also closes the stale-write
race @chrisberkhout raised.
The problem with `compareAndSet(-1, size)` is that it can't tell the `-1`
it read before computing from a `-1` written by an invalidation during the
computation. So each invalidation now writes a new negative token instead
(`-2`, `-3`, …, never reused). Sizes are always ≥ 0, so a negative value always
means "not cached":
```java
final long state = sizeInBytes.get();
if (state >= 0) {
return state;
}
long size = 0;
for (final String fileName : files()) {
size += info.dir.fileLength(fileName);
}
sizeInBytes.compareAndSet(state, size);
return size;
private void generationAdvanced() {
sizeInBytes.set(lastInvalidationToken.decrementAndGet());
...
}
```
If the segment is invalidated during the computation, the field holds a
different token and the CAS fails, so a stale size is never cached, not even
briefly. Every token is unique, so this also holds with concurrent
invalidations. The tokens need their own counter because once a size is cached,
the field no longer records which tokens have been used. Reads of a cached
value are still a single volatile read, and IOException propagates normally.
What this doesn't do:
- The returned size can still be out of date by the time the caller uses it.
- It doesn't address the `ConcurrentModificationException` risk in
`files()`, which reads mutable collections. Callers that need a consistent view
of the segment still need writer-side synchronization. I'm happy to open a
separate issue for that.
I've also added a CHANGES entry under 10.7.0 Bug Fixes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]