-
Notifications
You must be signed in to change notification settings - Fork 110
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
Makes writeValueRecursively
iterative
#368
Conversation
The method `_Private_IonWriterBase#writeValueRecursively` is recursive in two senses: 1. It visits all of the children in the provided IonReader's current value recursively. 2. The method itself is implemented using recursion. This patch modifies the implementation (#2) to be iterative, eliminating a source of StackOverflowExceptions and offering a modest reduction in CPU cost.
Codecov Report
@@ Coverage Diff @@
## master #368 +/- ##
=========================================
Coverage 64.04% 64.05%
+ Complexity 4838 4835 -3
=========================================
Files 136 136
Lines 21105 21108 +3
Branches 3818 3821 +3
=========================================
+ Hits 13517 13520 +3
+ Misses 6254 6251 -3
- Partials 1334 1337 +3
Continue to review full report at Codecov.
|
// The isNullValue() check above will handle this. | ||
throw new IllegalStateException("isNullValue() was false but IonType was NULL."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered about this, thanks for the clarification
stepIn(IonType.SEXP); | ||
break; | ||
default: | ||
throw new IllegalStateException("Unknown value type: " + type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your mileage may vary here, but what do you think of this expression?
switch (type) {
case NULL: // The isNullValue() check above will handle this.
throw new IllegalStateException("isNullValue() was false but IonType was NULL.");
case BOOL: writeBool(reader.booleanValue()); break;
case INT: writeInt(reader.bigIntegerValue()); break;
case FLOAT: writeFloat(reader.doubleValue()); break;
case DECIMAL: writeDecimal(reader.decimalValue()); break;
case TIMESTAMP: writeTimestamp(reader.timestampValue()); break;
case STRING: writeString(reader.stringValue()); break;
case SYMBOL: writeSymbolToken(reader.symbolValue()); break;
case BLOB: writeBlob(reader.newBytes()); break;
case CLOB: writeClob(reader.newBytes()); break;
case STRUCT: // Intentional fallthrough
case LIST: // Intentional fallthrough
case SEXP: reader.stepIn(); stepIn(type); break;
default:
throw new IllegalStateException("Unexpected value type: " + type);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I adopted the fallthrough for the container types, thanks!
*/ | ||
final void writeValueRecursively(IonType type, IonReader reader) | ||
throws IOException | ||
final void writeValueRecursively(IonType ionType, IonReader reader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.... 🤨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Zack responded offline that while the implementation is no longer recursive the value structure still is. This makes sense, traversing a recursive structure is what this does no matter how it does it.
Thank you for the detailed comments! |
The method
_Private_IonWriterBase#writeValueRecursively
isrecursive in two senses:
current value recursively.
This patch modifies the implementation to be iterative,
eliminating a source of StackOverflowExceptions and offering
a modest reduction in CPU cost.
Benchmark
This benchmark creates an
IonStruct
that is 1,000 levels deep, wraps it in anIonReader
, then useswriteValueRecursively
to write it to a binary Ion stream 100k times. The source can be viewed here.This change does not affect allocations or garbage collection, only CPU time.
Before
After
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.