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

IonRawBinaryWriter_1_1 annotations #661

Merged

Conversation

popematt
Copy link
Contributor

@popematt popematt commented Dec 1, 2023

Issue #, if available:

None

Description of changes:

There are two commits in this PR.

The first commit refactors some tests. It adds an autoClose option to the assertWriterOutputEquals function and an assertWriterThrows function, and it updates the test cases to use those.

The second commit adds annotations to IonRawBinaryWriter_1_1.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

* [writeAnnotations] may be called more than once to build up a list of annotations.
*/
fun writeAnnotations(annotation0: Int, annotation1: Int, vararg annotations: Int)
fun writeAnnotations(annotations: IntArray)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ I realized that it (a) made the implementation cleaner and (b) just made sense to be explicit about the array here, so I changed the function signature.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this ever need to be called from Java? What does that look like?

Copy link
Contributor Author

@popematt popematt Dec 6, 2023

Choose a reason for hiding this comment

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

For now, I don't think the Ion 1.1 raw writer needs to be called from Java. However, it is callable from Java. IntArray is Kotlin's name for int[].

As for removing the vararg parameter—instead of this:

writer.writeAnnotations(1, 2, 3, 4, 5);

Now you have to be explicit about the array:

write.writeAnnotations(new int[]{1, 2, 3, 4, 5})

This is a reversible decision.

}

private data class ContainerInfo(
var type: ContainerType? = null,
var isDelimited: Boolean = false,
var position: Long = -1,
var length: Long = -1,
var length: Long = 0,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ As I was working on annotations, I realized that it made more sense to always initialize the length of the ContainerInfo to 0. I also added a clear() function after I realized I might be leaking state between containers.


// Update the container length (unless it's Top)
if (currentContainer.type != Top) currentContainer.length += numBytesWritten
currentContainer.length += numBytesWritten
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ A long is pretty big, and it doesn't hurt anyone to have the length of Top being tracked, so I got rid of the branching here (and similarly in stepOut()).

@popematt popematt changed the title Ion11writer annotations IonRawBinaryWriter_1_1 annotations Dec 1, 2023
@popematt popematt requested a review from tgregg December 2, 2023 00:55
* [writeAnnotations] may be called more than once to build up a list of annotations.
*/
fun writeAnnotations(annotation0: Int, annotation1: Int, vararg annotations: Int)
fun writeAnnotations(annotations: IntArray)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this ever need to be called from Java? What does that look like?

* are being added one by one.
*/
private inline fun ensureAnnotationSpace(n: Int) {
if (annotationsIdBuffer.size < n || annotationsTextBuffer.size < n) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these grow independently? Does that significantly complicate things?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way I have it implemented right now, if position x of annotatationsTextBuffer is null, then we know to use the value from annotationsIdBuffer, so it does simplify the write logic if annotatationsTextBuffer is at least as large as annotationsIdBuffer, and if one has to be as least as large as the other, it simplifies the "growing" logic if we just make them the same size. I am not too concerned about the efficiency of growing both arrays at the same time because realistically, we don't expect there to be 10+ annotations for nearly all use cases.

}
if (annotationFlexSymFlag == FLEX_SYMS_REQUIRED) {
buffer.writeByte(OpCodes.ANNOTATIONS_MANY_FLEX_SYM)
buffer.reserve(lengthPrefixPreallocation)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this should be capped at 1 rather than using the same value used for containers. It seems less likely that your annotations would grow larger than can be described in a 1-byte FlexUInt.

That said, making a change here is probably only valuable if it simplifies the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does marginally simplify the code because the minimum we always need to preallocate is 1, so if we're also capping it at 1, then we can just hard-code it to 1.

return writeFlexInt(sid);
} else {
writeByte((byte) 0x01);
writeByte((byte) 0x70);
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about changing the spec so that this is 0x90 instead? That way it at least aligns with the upper nibble type (9 = symbol, whereas 7 = timestamp)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like that, and I suspect that was probably the intention, but then parts of the spec were modified without fully updating other parts of the spec.

Copy link

codecov bot commented Dec 7, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

❗ No coverage uploaded for pull request base (ion-11-encoding@79c8e5c). Click here to learn what that means.

Additional details and impacted files
@@                Coverage Diff                 @@
##             ion-11-encoding     #661   +/-   ##
==================================================
  Coverage                   ?   64.64%           
  Complexity                 ?     5703           
==================================================
  Files                      ?      199           
  Lines                      ?    24695           
  Branches                   ?     4386           
==================================================
  Hits                       ?    15963           
  Misses                     ?     7433           
  Partials                   ?     1299           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@popematt popematt merged commit 015c6a0 into amazon-ion:ion-11-encoding Dec 7, 2023
8 of 32 checks passed
@popematt popematt deleted the ion11writer-annotations branch December 7, 2023 22:18
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.

2 participants