Skip to content

Conversation

@ianbotsf
Copy link
Contributor

Issue #

(none)

Description of changes

This change implements Kotlin/Native support for BigInteger/BigDecimal by way of the IonSpin kotlin-multiplatform-bignum library. This change adds a workaround for building smithy-kotlin on Amazon Linux 2 because of linking issues with zlib (see runtime/build.gradle.kts).

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

@ianbotsf ianbotsf added the no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly. label Dec 19, 2024
@ianbotsf ianbotsf requested a review from a team as a code owner December 19, 2024 23:51
kotlin.incremental.js=true
kotlin.incremental.multiplatform=true
kotlin.mpp.stability.nowarn=true
kotlin.native.binary.sourceInfoType=libbacktrace
Copy link
Contributor

Choose a reason for hiding this comment

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

Were you able to get better stack traces with this enabled? I remember you said it didn't help, so I'd rather leave it off if it's not working as expected

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, will remove. I eventually discovered that full stack traces are available in the build artifacts (e.g., build/reports/tests/linuxX64Test/index.html) just not in the console output.


actual override fun equals(other: Any?): Boolean = other is BigDecimal && delegate == other.delegate
public actual override fun equals(other: Any?): Boolean = other is BigDecimal && delegate == other.delegate
public actual override fun hashCode(): Int = 31 + delegate.hashCode()
Copy link
Contributor

Choose a reason for hiding this comment

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

Usually 31 is multiplied in these hashCode implementations, is this intentional addition? Is there any reason we can't just take the delegate's hash 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.

Yes, I intentionally used addition instead of multiplication although either should work. I wanted to avoid using the unmodified hash code from the delegate because that would bin them the same if they were both added to a hashed container (e.g., Set). That's unlikely but also trivial to avoid.

Comment on lines +48 to +52
public actual operator fun plus(other: BigDecimal): BigDecimal =
coalesceOrCreate(delegate + other.delegate, this, other)

public actual operator fun minus(other: BigDecimal): BigDecimal =
coalesceOrCreate(delegate - other.delegate, this, other)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice 👍

public actual override fun toString(): String = toString(10)
public actual fun toString(radix: Int): String = delegate.toString(radix)

public actual override fun hashCode(): Int = 17 + delegate.hashCode()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question about adding 17, can we just take the delegate's hash code?

Comment on lines +13 to 25
private companion object {
/**
* Returns a new or existing [BigDecimal] wrapper for the given delegate [value]
* @param value The delegate value to wrap
* @param left A candidate wrapper which may already contain [value]
* @param right A candidate wrapper which may already contain [value]
*/
fun coalesceOrCreate(value: IonSpinBigDecimal, left: BigDecimal, right: BigDecimal): BigDecimal = when (value) {
left.delegate -> left
right.delegate -> right
else -> BigDecimal(value)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like this coalesceOrCreate might be a candidate for a generic function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That'd be nice but our BigInteger and BigDecimal definitions don't have a common interface which defines val delegate as a public member. I'd rather not add one either since the delegate is an internal implementation detail.

Copy link
Contributor

@0marperez 0marperez left a comment

Choose a reason for hiding this comment

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

Nothing to add beyond what Matas said

@github-actions

This comment has been minimized.

@ianbotsf ianbotsf added the acknowledge-api-break Acknowledge that a change is API breaking and may be backwards-incompatible. Review carefully! label Jan 10, 2025
@github-actions
Copy link

Affected Artifacts

Changed in size
Artifact Pull Request (bytes) Latest Release (bytes) Delta (bytes) Delta (percentage)
http-test-jvm.jar 61,633 58,718 2,915 4.96%
crt-util-jvm.jar 21,443 20,954 489 2.33%
runtime-core-jvm.jar 816,521 812,469 4,052 0.50%
aws-signing-tests-jvm.jar 456,614 456,568 46 0.01%
test-suite-jvm.jar 96,907 97,180 -273 -0.28%
aws-signing-common-jvm.jar 66,491 71,313 -4,822 -6.76%

@ianbotsf ianbotsf merged commit f025d2b into kn-main Jan 10, 2025
21 of 22 checks passed
@ianbotsf ianbotsf deleted the kn-bignums branch January 10, 2025 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acknowledge-api-break Acknowledge that a change is API breaking and may be backwards-incompatible. Review carefully! no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants