Skip to content

Add initial chunk argument to StreamingByteReader - #3135

Closed
moradology wants to merge 1 commit into
locationtech:masterfrom
moradology:feature/sbr-initialChunk
Closed

moradology wants to merge 1 commit into
locationtech:masterfrom
moradology:feature/sbr-initialChunk

Conversation

@moradology

@moradology moradology commented Oct 22, 2019 •

Copy link
Copy Markdown
Contributor

Overview

The streaming byte reader is often used to read metadata from file
headers. Optimal chunking behavior for tif headers vs tif bodies means
that the default chunk size isn't suitable for quickly reading metadata

  • in particular when the file header is particularly long. The
    StreamingByteReader now supports an initialChunk argument which
    preloads a chunk of the specified size to avoid multiple reads.

This also fixes a broken test in geotrellis.util and enables CI running of geotrellis.util tests

Checklist

  • docs/CHANGELOG.rst updated, if necessary
  • New user API has useful Scaladoc strings
  • Unit tests added for bug-fix or new feature

Notes

This fix allows users that wish to specify an initial read size to do so. Unfortunately, as of now, the API leans on implicit conversions to turn RangeReader instances into StreamingByteReaders. Without a more robust configuration system, then, setting the initialChunk of a StreamingByteReader depends on explicitly constructing said StreamingByteReader instance

See #3127

The streaming byte reader is often used to read metadata from file
headers. Optimal chunking behavior for tif headers vs tif bodies means
that the default chunk size isn't suitable for quickly reading metadata
- in particular when the file header is particularly long. The
StreamingByteReader now supports an `initialChunk` argument which
preloads a chunk of the specified size to avoid multiple reads.
@moradology
moradology requested a review from pomadchin October 22, 2019 16:05
val bytes = Array.ofDim[Byte](ensuredLength)
chunkBuffer.get(bytes)
filePosition += length
filePosition += ensuredLength

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This set of changes was necessary to get tests to pass. getBytes now only attempts to read the length of bytes which can be ensured by ensureChunk

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch!

@pomadchin pomadchin left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's good, thank you!
I have some questions about how StreamingByteReader parameters should be configured in the RasterSources API.

It doesn't really completely cover #3126 since the issue probably requires some extra comments below why these changes were made and how this PR resolves the issue.

Also requires a rebase on top of master due to the CHANGELOG format change.

val bytes = Array.ofDim[Byte](ensuredLength)
chunkBuffer.get(bytes)
filePosition += length
filePosition += ensuredLength

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch!

* @return A new instance of StreamingByteReader
*/
class StreamingByteReader(rangeReader: RangeReader, chunkSize: Int = 45876) extends ByteReader {
class StreamingByteReader(rangeReader: RangeReader, chunkSize: Int = 45876, initialChunk: Int = 0) extends ByteReader {

@pomadchin pomadchin Oct 22, 2019 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since we're heavily using SPI to spawn RangeReader instances, does it make sense to move both chunkSize and initialChunk into reference.conf? This would looks similar to GDAL settings in this case. Otherwise it would be hard to use this functionality with RasterSources as they are generalized. Is it a good interface change in general?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

also mentioning here @echeipesh as it looks like we can get it into the next (& a very close) release.

@echeipesh

echeipesh commented Oct 23, 2019 •

Copy link
Copy Markdown
Contributor

I don't think this PR should be merged. Its good to document the investigation into #3127 and basically closes that issue.

But it's not really possible to use the change effectively. User doesn't have a way to know what the reasonable initial read should be. There is a risk of reading way too much for tiffs that don't have a lot of segments or overviews and not reading enough for tiffs that do in fact have a huge header.

Potential and non-trivial solutions could be:

  • Have GeoTiff reader make an educated guess on how much to read during the initial stages of header read (not sure if if this is possible in reality)
  • Have ability to read N-pages, aligned and in LRU cache (if thrashing was observed when reading the headers)

@echeipesh echeipesh closed this Oct 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants