Skip to content

Conversation

@tlrx
Copy link
Member

@tlrx tlrx commented Mar 11, 2024

This change adds a variant of the existing SharedBytes.copyToCacheFileAligned that is not limited to copy only a given length of bytes but copies all bytes that can be read from the InputStream.

It also adds a variant of the existing BlobCacheUtils.computeRange() method that computes range of bytes to expand over a complete regions, instead of being limited to the length of the blob.

Finally, it removes an assertion that a CacheFile cannot write a range larger than the blob length.

@tlrx tlrx added >non-issue :Distributed Indexing/Engine Anything around managing Lucene and the Translog in an open shard. v8.14.0 labels Mar 11, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticsearchmachine elasticsearchmachine added the Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. label Mar 11, 2024
Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Ideally we'd add a test here for the new method, but I can see how that might be cumbersome. If that is the reasoning I am ok to proceed as is, we'll test this from stateless then.

final RangeAvailableHandler reader,
final RangeMissingHandler writer
) throws Exception {
assert assertOffsetsWithinFileLength(rangeToWrite.start(), rangeToWrite.length(), length);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add assert rangeToWrite.start() >= 0 instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might also be great to comment on why we allow rangeToWrite beyond the blob length since it is not intuitive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both comments make sense, I pushed fe84866

Copy link
Contributor

@fcofdez fcofdez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@ywangd ywangd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

}

public static ByteRange computeRange(long rangeSize, long position, long size) {
return ByteRange.of((position / rangeSize) * rangeSize, (((position + size - 1) / rangeSize) + 1) * rangeSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to reuse computeRange(rangeSize, position, size, Long.MAX_VALUE) instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it would be OK, but I prefer to have a dedicated method.

final RangeAvailableHandler reader,
final RangeMissingHandler writer
) throws Exception {
assert assertOffsetsWithinFileLength(rangeToWrite.start(), rangeToWrite.length(), length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might also be great to comment on why we allow rangeToWrite beyond the blob length since it is not intuitive.

Comment on lines +207 to +214
if (buffer.hasRemaining()) {
// ensure that last write is aligned on 4k boundaries (= page size)
final int remainder = buffer.position() % PAGE_SIZE;
final int adjustment = remainder == 0 ? 0 : PAGE_SIZE - remainder;
buffer.position(buffer.position() + adjustment);
}
bytesCopied += positionalWrite(fc, fileChannelPos + bytesCopied, buffer);
progressUpdater.accept(bytesCopied);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly for my education: With the existing version of this method, we adjust bytesCopied with the page alignment before invoke progressUpdater. I think this is beacuse ProgressListenableActionFuture has a few assertions that expect bytesCopied not exceeding its end value (example).

We don't need the same adjustment here for the callback because ProgressListenableActionFuture should always be created with page aligned end value and this is guaranteed by the new BlobCacheUtils#computeRange method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is beacuse ProgressListenableActionFuture has a few assertions that expect bytesCopied not exceeding its end value (example).

Yes, we cannot update progress to a value that would exceed the pending range in the SparseFileTracker.

We don't need the same adjustment here for the callback because ProgressListenableActionFuture should always be created with page aligned end value and this is guaranteed by the new BlobCacheUtils#computeRange method?

Yes 👍

@tlrx tlrx merged commit ebf3550 into elastic:main Mar 13, 2024
@tlrx tlrx deleted the 2024/03/11/shared-blob-cache-adjustments branch March 13, 2024 12:54
@tlrx
Copy link
Member Author

tlrx commented Mar 13, 2024

Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Distributed Indexing/Engine Anything around managing Lucene and the Translog in an open shard. >non-issue Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. v8.14.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants