Add an ImmutableByteArray implementation#139
Conversation
Preparation for replacing ByteBuffer in generated classes since ByteBuffer is not immutable and maintains mutable state.
|
@j-baker Didn't you have one of those somewhere already? |
| } | ||
|
|
||
| /** Copies this byte array into the provided byte array beginning at offset and up to the provided length. */ | ||
| public void copy(byte[] array, int offset, int length) { |
There was a problem hiding this comment.
would prefer to rename the array parameter something along the lines of destination
There was a problem hiding this comment.
bikeshed: method name copyTo?
There was a problem hiding this comment.
yep, will rename to copyTo
| public byte[] getBytes() { | ||
| byte[] unsafe = new byte[safe.length]; | ||
| System.arraycopy(safe, 0, unsafe, 0, safe.length); | ||
| return unsafe; |
There was a problem hiding this comment.
return safe.clone() is simpler.
There was a problem hiding this comment.
I'd prefer to know we're doing this using the System copy primitives, and so going to keep this relatively small amount of code, confidently given test coverage.
| } | ||
|
|
||
| /** Returns a new read-only {@link ByteBuffer} backed by this byte array. */ | ||
| public ByteBuffer getByteBuffer() { |
There was a problem hiding this comment.
Thoughts on as or to over get?
There was a problem hiding this comment.
I guess “asNewByteBuffer”?
There was a problem hiding this comment.
Not sure new is necessary here, since the byte buffer isn't mutable. It happens to be new, but that makes no difference to api consumers.
Our data could just as easily be backed by a heap ByteBuffer rather than byte[], in which case we wouldn't create new objects.
There was a problem hiding this comment.
Since this is a constant time/memory operation unlike getBytes the originalgetByteBuffer is probably best here.
There was a problem hiding this comment.
ok, for symmetry this will be called asByteBuffer (no "new").
|
|
||
| /** Returns a copy of this byte array. */ | ||
| @JsonValue | ||
| public byte[] getBytes() { |
There was a problem hiding this comment.
It might be helpful to include some indication in the method name that we're making a copy, which is potentially expensive.
There was a problem hiding this comment.
“asNewByteArray”?
| import java.util.Arrays; | ||
|
|
||
| /** An immutable {@code byte[]} wrapper. */ | ||
| public final class ImmutableByteArray { |
There was a problem hiding this comment.
Thoughts on naming this Binary to couple this with the cojure primitive? Byte array is an implementation detail.
There was a problem hiding this comment.
Maybe ImmutableBytes? “binary” translates a few different ways — sometimes as a stream — so would avoid the direct naming here. Also open to “ByteString” or just “Bytes”.
There was a problem hiding this comment.
Bytes is reasonable, though I prefer Binary. Other types have different java bindings based on context, int, OptionalInt, List<Integer> for example.
Bytes sounds a bit like a utility rather than a data object (see com.google.common.primitives.Bytes).
There was a problem hiding this comment.
why not just ByteArray? why don't prefix other classes with Immutable even if they are, e.g. ResourceIdentifier.
There was a problem hiding this comment.
going to go with "Bytes"
| public boolean equals(Object obj) { | ||
| return this == obj | ||
| || (obj instanceof ImmutableByteArray && Arrays.equals(safe, ((ImmutableByteArray) obj).safe)); | ||
| } |
There was a problem hiding this comment.
Missing toString, though I'm not sure what I'd expect a binary toString to do. Perhaps class name and length?
There was a problem hiding this comment.
added toString that includes the size but nothing else
| } | ||
|
|
||
| /** Returns a copy of this byte array. */ | ||
| @JsonValue |
There was a problem hiding this comment.
Should we move @JsonValue to getByteBuffer and avoid duplicating contents for serialization? Annotation may apply to the safe field, but I've not tested that type of usage.
There was a problem hiding this comment.
sure, I'll move it to the other method. It's more appropriate to label a method than a private member, so we'll stick with methods.
schlosna
left a comment
There was a problem hiding this comment.
palantir/atlasdb#2020 was one place where we didn't want to require a 3rd party dependency in public API that this could be useful.
| } | ||
|
|
||
| /** Copies this byte array into the provided byte array beginning at offset and up to the provided length. */ | ||
| public void copy(byte[] array, int offset, int length) { |
There was a problem hiding this comment.
bikeshed: method name copyTo?
|
|
||
| /** Constructs a new {@link ImmutableByteArray} read from the provided {@link ByteBuffer}. */ | ||
| public static ImmutableByteArray from(ByteBuffer buffer) { | ||
| ByteBuffer local = buffer.duplicate(); |
There was a problem hiding this comment.
can you add a comment saying why this duplicate is necessary?
| assertThat(immutable.getBytes()[0]).isEqualTo((byte) 0); | ||
|
|
||
| input[0] = 1; | ||
|
|
There was a problem hiding this comment.
nit: could cut this line (34) and the one above (30)
There was a problem hiding this comment.
added a comment on what line 33 is doing, believe the whitespace improves readability
|
|
||
| @Test | ||
| public void testConstructionCopiesArrayWithRange() { | ||
| byte[] input = new byte[]{0, 1, 2}; |
There was a problem hiding this comment.
also test end by doing {0,1,2,3} --> {1,2}?
uschi2000
left a comment
There was a problem hiding this comment.
looks good modulo the naming discussion and one docs suggestion.
Preparation for replacing ByteBuffer in generated classes since ByteBuffer is not
immutable and maintains mutable state.