Skip to content
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

Rewrite Blob to facilitate interop with other libs #1211

Merged
merged 5 commits into from
Sep 27, 2023

Conversation

Baccata
Copy link
Contributor

@Baccata Baccata commented Sep 21, 2023

Rewrite the structure of Blob to help interop with other libraries and
patterns, such as fs2 or scodec.
@Baccata
Copy link
Contributor Author

Baccata commented Sep 21, 2023

@armanbilge, if you could spare the time to give me you your opinion on this, it'd be well appreciated

Copy link
Contributor

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

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

Seems fine. FWIW I think you could get away with just ArraySliceBlob and QueueBlob (also I think JVM special-cases classes with no more than 2 implementations, but don't quote me).

Many ByteBuffers are backed by Array[Byte]s so you can convert them to ArraySliceBlob without copying. In the case where they're not (e.g. off-heap buffer), you'd have to copy to bring it into the ADT, but chances are you'd have to copy at some point anyway. The only case you lose is when you are literally just shoveling bytes between sockets/files without any parsing/transformation, then keeping things in off-heap ByteBuffers could win. Edit: note that FS2 doesn't use off-heap buffers anyway, actually they are kind of hostile to immutable datatypes since they don't GC well.

modules/core/src/smithy4s/Blob.scala Outdated Show resolved Hide resolved
modules/core/src/smithy4s/Blob.scala Show resolved Hide resolved
modules/core/src/smithy4s/Blob.scala Show resolved Hide resolved
* Remove ByteArrayBlob (superseded by ArraySiceBlob)
* Add an `toArraySliceBlob` interface method
* Make class constructors private
* Add smart constructors
hashCode += bytes(i).hashCode()
i += 1
override def asByteBufferUnsafe(offset: Int, size: Int): ByteBuffer = {
val b = buf
Copy link
Contributor

Choose a reason for hiding this comment

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

ByteBuffers are really annoying and hard to work correctly with. This is why I'm skeptical if its worth to give them a designated position in the ADT.

Suggested change
val b = buf
val b = buf.duplicate()

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm 😅 I now realize this is possibly my own mistake in scodec-bits. I need to think about this.

https://github.com/scodec/scodec-bits/blob/ad81e86d47dc1859e48e453df5da402bc8f13abb/core/shared/src/main/scala/scodec/bits/ByteVector.scala#L1466-L1474

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, this was pretty much copied verbatim from scodecs-bits.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in aabf826

@Baccata Baccata marked this pull request as ready for review September 25, 2023 15:12
Comment on lines 92 to 97
try {
val _ = data(6)
fail("expected exception")
} catch {
case _: IndexOutOfBoundsException => ()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
try {
val _ = data(6)
fail("expected exception")
} catch {
case _: IndexOutOfBoundsException => ()
}
intercept[IndexOutOfBoundsException]{ data(6) }

Copy link
Contributor Author

@Baccata Baccata Sep 27, 2023

Choose a reason for hiding this comment

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

Thanks ! b50d8d4


test(s"$name: copyToStream") {
val stream = new ByteArrayOutputStream()
try {
Copy link
Contributor

Choose a reason for hiding this comment

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

the other day I discovered Using and Using.resource to do this kind of resource management

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I was under the impression it was a 2.13+ only thing

b50d8d4

val _ = buffer.get(arr)
}
override def hashCode(): Int = {
import util.hashing.MurmurHash3
Copy link
Contributor

Choose a reason for hiding this comment

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

well that's nice

Copy link
Contributor

@daddykotex daddykotex left a comment

Choose a reason for hiding this comment

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

I'm no expert, so take this review with a grain of salt. I have a few suggestion to improve test readability but that's about it, the rest seems fine to me.

@Baccata Baccata merged commit c69417d into series/0.18 Sep 27, 2023
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.

4 participants