This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new b695bfeec0 IGNITE-23638 Remove unnecessary shrink calls in the 
big_number C++ implementation (#4702)
b695bfeec0 is described below

commit b695bfeec0293e04856f78b22b4619eed2fa0115
Author: Dmitriy Zabotlin <[email protected]>
AuthorDate: Tue Nov 12 15:31:53 2024 +0200

    IGNITE-23638 Remove unnecessary shrink calls in the big_number C++ 
implementation (#4702)
    
    Co-authored-by: dzabotlin <[email protected]>
---
 .../platforms/cpp/ignite/common/big_integer.cpp    |  12 +-
 .../platforms/cpp/ignite/common/bignum_test.cpp    | 171 ++++++++++++---------
 modules/platforms/cpp/ignite/common/detail/mpi.cpp |  16 +-
 modules/platforms/cpp/ignite/common/detail/mpi.h   |  21 ++-
 4 files changed, 120 insertions(+), 100 deletions(-)

diff --git a/modules/platforms/cpp/ignite/common/big_integer.cpp 
b/modules/platforms/cpp/ignite/common/big_integer.cpp
index 89816ac6dd..0ec9b32c63 100644
--- a/modules/platforms/cpp/ignite/common/big_integer.cpp
+++ b/modules/platforms/cpp/ignite/common/big_integer.cpp
@@ -34,8 +34,6 @@ big_integer::big_integer(const int8_t *val, int32_t len, 
int8_t sign, bool big_e
     m_mpi.read(reinterpret_cast<const std::uint8_t *>(val), len, big_endian);
 
     m_mpi.set_sign(sign >= 0 ? detail::mpi_sign::POSITIVE : 
detail::mpi_sign::NEGATIVE);
-
-    m_mpi.shrink();
 }
 
 big_integer::big_integer(const std::byte *data, std::size_t size) {
@@ -60,8 +58,6 @@ big_integer::big_integer(const std::byte *data, std::size_t 
size) {
         }
         m_mpi.make_negative();
     }
-
-    m_mpi.shrink();
 }
 
 void big_integer::assign_int64(int64_t val) {
@@ -115,7 +111,7 @@ std::uint32_t big_integer::bit_length() const noexcept {
         auto last = view.back();
         if ((last & (last - 1)) == 0) {
             bool all_zero = true;
-            for (auto i = std::int64_t(view.size() - 2); i > 0; i--) {
+            for (auto i = std::int64_t(view.size_words() - 2); i > 0; i--) {
                 if (view[i] != 0) {
                     all_zero = false;
                     break;
@@ -140,8 +136,6 @@ void big_integer::store_bytes(std::byte *data) const {
         return;
     }
 
-    m_mpi.shrink();
-
     auto size = byte_size();
     m_mpi.write(reinterpret_cast<std::uint8_t *>(data), size);
 
@@ -237,8 +231,8 @@ int big_integer::compare(const big_integer &other, bool 
ignore_sign) const {
 
 int64_t big_integer::to_int64() const {
     auto mag = m_mpi.magnitude();
-    std::uint64_t high = mag.size() > 1 ? mag[1] : 0;
-    std::uint64_t low = mag.size() > 0 ? mag[0] : 0;
+    std::uint64_t high = mag.size_words() > 1 ? mag[1] : 0;
+    std::uint64_t low = mag.size_words() > 0 ? mag[0] : 0;
     return m_mpi.sign() * int64_t(high << 32 | low);
 }
 
diff --git a/modules/platforms/cpp/ignite/common/bignum_test.cpp 
b/modules/platforms/cpp/ignite/common/bignum_test.cpp
index 434e0e8de5..45eb4f6166 100644
--- a/modules/platforms/cpp/ignite/common/bignum_test.cpp
+++ b/modules/platforms/cpp/ignite/common/bignum_test.cpp
@@ -72,74 +72,84 @@ void CheckDoubleCast(double val) {
 }
 
 TEST(bignum, TestMultiplyBigIntegerArguments) {
-    big_integer bigInt(12345);
+    big_integer big_int(12345);
+
+    {
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
+
+        EXPECT_GE(mag.size_words(), 1);
+        EXPECT_GE(mag.size_bytes(), 4);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 2);
+    }
 
     big_integer res;
 
     // 152399025
-    bigInt.multiply(big_integer(12345), res);
+    big_int.multiply(big_integer(12345), res);
 
     {
         const big_integer::mag_array_view mag = res.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 4);
 
         EXPECT_EQ(mag[0], 152399025UL);
     }
 
     // 152399025
-    bigInt.assign_int64(12345);
-    bigInt.multiply(bigInt, res);
+    big_int.assign_int64(12345);
+    big_int.multiply(big_int, res);
 
     {
         const big_integer::mag_array_view mag = res.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 4);
 
         EXPECT_EQ(mag[0], 152399025UL);
     }
 
     // 152399025
-    bigInt.assign_int64(12345);
-    bigInt.multiply(big_integer(12345), bigInt);
+    big_int.assign_int64(12345);
+    big_int.multiply(big_integer(12345), big_int);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 4);
 
         EXPECT_EQ(mag[0], 152399025UL);
     }
 
     // 152399025
-    bigInt.assign_int64(12345);
-    bigInt.multiply(bigInt, bigInt);
+    big_int.assign_int64(12345);
+    big_int.multiply(big_int, big_int);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 4);
 
         EXPECT_EQ(mag[0], 152399025UL);
     }
 }
 
 TEST(bignum, TestMultiplyBigIntegerBigger) {
-    big_integer bigInt(12345);
+    big_integer big_int(12345);
 
     // 152399025
-    bigInt.multiply(bigInt, bigInt);
+    big_int.multiply(big_int, big_int);
 
     // 3539537889086624823140625
     // 0002 ED86  BBC3 30D1  DDC6 6111
-    big_integer buf = bigInt;
-    bigInt.multiply(buf, bigInt);
-    bigInt.multiply(buf, bigInt);
+    big_integer buf = big_int;
+    big_int.multiply(buf, big_int);
+    big_int.multiply(buf, big_int);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 3);
+        EXPECT_GE(mag.size_words(), 3);
+        EXPECT_GE(mag.size_bytes(), 12);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 11);
 
         EXPECT_EQ(mag[0], 0xDDC66111);
         EXPECT_EQ(mag[1], 0xBBC330D1);
@@ -148,13 +158,15 @@ TEST(bignum, TestMultiplyBigIntegerBigger) {
 
     // 2698355789040138398691723863616167551412718750 ==
     // 0078 FF9A  F760 4E12  4A1F 3179  D038 D455  630F CC9E
-    bigInt.multiply(big_integer(32546826734), bigInt);
-    bigInt.multiply(big_integer(23423079641), bigInt);
+    big_int.multiply(big_integer(32546826734), big_int);
+    big_int.multiply(big_integer(23423079641), big_int);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 5);
+        EXPECT_GE(mag.size_words(), 5);
+        EXPECT_GE(mag.size_bytes(), 20);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 19);
 
         EXPECT_EQ(mag[0], 0x630FCC9E);
         EXPECT_EQ(mag[1], 0xD038D455);
@@ -165,35 +177,41 @@ TEST(bignum, TestMultiplyBigIntegerBigger) {
 }
 
 TEST(bignum, TestPowBigInteger) {
-    big_integer bigInt(12345);
+    big_integer big_int(12345);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_GE(mag.size_words(), 1);
+        EXPECT_GE(mag.size_bytes(), 4);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 2);
 
         EXPECT_EQ(mag[0], 12345);
     }
 
     // 152399025
-    bigInt.pow(2);
+    big_int.pow(2);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 1);
+        EXPECT_GE(mag.size_words(), 1);
+        EXPECT_GE(mag.size_bytes(), 4);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 4);
 
         EXPECT_EQ(mag[0], 152399025UL);
     }
 
     // 3539537889086624823140625
     // 0002 ED86  BBC3 30D1  DDC6 6111
-    bigInt.pow(3);
+    big_int.pow(3);
 
     {
-        const big_integer::mag_array_view mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 3);
+        EXPECT_GE(mag.size_words(), 3);
+        EXPECT_GE(mag.size_bytes(), 12);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 11);
 
         EXPECT_EQ(mag[0], 0xDDC66111);
         EXPECT_EQ(mag[1], 0xBBC330D1);
@@ -210,12 +228,14 @@ TEST(bignum, TestPowBigInteger) {
     //  54E6 FF91  13FF 7B0A  455C F649  F4CD 37D0  C5B0 0507  1BFD 9083
     //  8F13 08B4  D962 08FC  FBC0 B5AB  F9F9 06C9  94B3 9715  8C43 C94F
     //  4891 09E5  57AA 66C9  A4F4 3494  A938 89FE  87AF 9056  7D90 17A1
-    bigInt.pow(10);
+    big_int.pow(10);
 
     {
-        const big_integer::mag_array_view &mag = bigInt.get_magnitude();
+        const big_integer::mag_array_view &mag = big_int.get_magnitude();
 
-        EXPECT_EQ(mag.size(), 26);
+        EXPECT_EQ(mag.size_words(), 26);
+        EXPECT_EQ(mag.size_bytes(), 104);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 102);
 
         EXPECT_EQ(mag[0], 0x7D9017A1);
         EXPECT_EQ(mag[1], 0x87AF9056);
@@ -245,33 +265,33 @@ TEST(bignum, TestPowBigInteger) {
         EXPECT_EQ(mag[25], 0x0000B4D0);
     }
 
-    bigInt.assign_int64(-1);
+    big_int.assign_int64(-1);
 
-    bigInt.pow(57298735);
-    EXPECT_EQ(bigInt.to_int64(), -1);
+    big_int.pow(57298735);
+    EXPECT_EQ(big_int.to_int64(), -1);
 
-    bigInt.pow(325347312);
-    EXPECT_EQ(bigInt.to_int64(), 1);
+    big_int.pow(325347312);
+    EXPECT_EQ(big_int.to_int64(), 1);
 
-    bigInt.assign_int64(2);
+    big_int.assign_int64(2);
 
-    bigInt.pow(10);
-    EXPECT_EQ(bigInt.to_int64(), 1024);
+    big_int.pow(10);
+    EXPECT_EQ(big_int.to_int64(), 1024);
 
-    bigInt.assign_int64(-2);
+    big_int.assign_int64(-2);
 
-    bigInt.pow(10);
-    EXPECT_EQ(bigInt.to_int64(), 1024);
+    big_int.pow(10);
+    EXPECT_EQ(big_int.to_int64(), 1024);
 
-    bigInt.assign_int64(2);
+    big_int.assign_int64(2);
 
-    bigInt.pow(11);
-    EXPECT_EQ(bigInt.to_int64(), 2048);
+    big_int.pow(11);
+    EXPECT_EQ(big_int.to_int64(), 2048);
 
-    bigInt.assign_int64(-2);
+    big_int.assign_int64(-2);
 
-    bigInt.pow(11);
-    EXPECT_EQ(bigInt.to_int64(), -2048);
+    big_int.pow(11);
+    EXPECT_EQ(big_int.to_int64(), -2048);
 }
 
 TEST(bignum, TestMultiplyDivideSimple) {
@@ -920,25 +940,25 @@ TEST(bignum, TestScalingSmall) {
 }
 
 TEST(bignum, TestScalingBig) {
-    big_integer bigInt(69213205262741);
+    big_integer big_int(69213205262741);
 
     big_decimal decimal;
     EXPECT_EQ(decimal.get_precision(), 1);
 
     // 4790467782742318458842833081
-    bigInt.multiply(bigInt, bigInt);
+    big_int.multiply(big_int, big_int);
 
-    decimal = big_decimal(bigInt, 0);
+    decimal = big_decimal(big_int, 0);
     EXPECT_EQ(decimal.get_precision(), 28);
 
     // 22948581577492104846692006446607391554788985798427952561
-    bigInt.multiply(bigInt, bigInt);
+    big_int.multiply(big_int, big_int);
 
-    decimal = big_decimal(bigInt, 0);
+    decimal = big_decimal(big_int, 0);
     EXPECT_EQ(decimal.get_precision(), 56);
 
     // 22948581577492104846692006446607391554.788985798427952561
-    decimal = big_decimal(bigInt, 18);
+    decimal = big_decimal(big_int, 18);
 
     // 22948581577492104846692006446607391554
     decimal.set_scale(0, decimal);
@@ -946,7 +966,7 @@ TEST(bignum, TestScalingBig) {
     EXPECT_EQ(decimal.get_precision(), 38);
 
     // 22948581.577492104846692006446607391554788985798427952561
-    decimal = big_decimal(bigInt, 48);
+    decimal = big_decimal(big_int, 48);
 
     // 22948581
     decimal.set_scale(0, decimal);
@@ -958,13 +978,13 @@ TEST(bignum, TestScalingBig) {
     // 436301540552945788827650832722026963914694916372255230793492080431332686
     // 268324254350022490844698008329270553114204362445999680199136593689695140
     // 0874934591063287320666899465891248127072522251998904759858801
-    bigInt.pow(5);
+    big_int.pow(5);
 
     // 63647190455381106.030680614025402628690608799785691446392543129561015071
     // 243630154055294578882765083272202696391469491637225523079349208043133268
     // 626832425435002249084469800832927055311420436244599968019913659368969514
     // 00874934591063287320666899465891248127072522251998904759858801
-    decimal = big_decimal(bigInt, 260);
+    decimal = big_decimal(big_int, 260);
     EXPECT_EQ(decimal.get_precision(), 277);
 
     // 63647190455381106
@@ -972,6 +992,17 @@ TEST(bignum, TestScalingBig) {
 
     EXPECT_EQ(decimal.get_precision(), 17);
     EXPECT_EQ(decimal.to_int64(), 63647190455381106L);
+
+    decimal = big_decimal(1, 10000);
+    {
+        EXPECT_EQ(decimal.byte_size(), 3);
+        auto mag = decimal.get_unscaled_value().get_magnitude();
+        EXPECT_EQ(mag.size_words(), 1);
+        EXPECT_EQ(mag.size_bytes(), 4);
+        EXPECT_EQ(mag.size_bytes_non_zero(), 1);
+
+        EXPECT_EQ(mag[0], 0x1);
+    }
 }
 
 TEST(bignum, TestDecimalSimple) {
@@ -1089,25 +1120,25 @@ TEST(bignum, TestPrecisionSimple) {
 }
 
 TEST(bignum, TestPrecisionChange) {
-    big_integer bigInt(32421);
+    big_integer big_int(32421);
 
     // 75946938183
-    bigInt.multiply(big_integer(2342523), bigInt);
+    big_int.multiply(big_integer(2342523), big_int);
 
     // 4244836901495581620
-    bigInt.multiply(big_integer(55892140), bigInt);
+    big_int.multiply(big_integer(55892140), big_int);
 
     // 1361610054778960404282184020
-    bigInt.multiply(big_integer(320768521), bigInt);
+    big_int.multiply(big_integer(320768521), big_int);
 
     // 1454144449122723409814375680476734820
-    bigInt.multiply(big_integer(1067959541), bigInt);
+    big_int.multiply(big_integer(1067959541), big_int);
 
     // 117386322514277938455905731466723946155156640
-    bigInt.multiply(big_integer(80725352), bigInt);
+    big_int.multiply(big_integer(80725352), big_int);
 
     // 1173863225142779384559.05731466723946155156640
-    big_decimal decimal(bigInt, 23);
+    big_decimal decimal(big_int, 23);
 
     EXPECT_EQ(decimal.get_precision(), 45);
     EXPECT_EQ(decimal.get_scale(), 23);
diff --git a/modules/platforms/cpp/ignite/common/detail/mpi.cpp 
b/modules/platforms/cpp/ignite/common/detail/mpi.cpp
index 852ca0d05c..f38445d080 100644
--- a/modules/platforms/cpp/ignite/common/detail/mpi.cpp
+++ b/modules/platforms/cpp/ignite/common/detail/mpi.cpp
@@ -79,7 +79,6 @@ mpi::mpi(const mpi &other) {
     init();
 
     check(mbedtls_mpi_copy(val, other.val));
-    check(mbedtls_mpi_shrink(val, 0));
 }
 
 mpi::mpi(mpi &&other) noexcept {
@@ -144,7 +143,7 @@ unsigned short mpi::length() const noexcept {
 }
 
 mpi::mag_view mpi::magnitude() const noexcept {
-    return {val->p, val->n};
+    return {val->p, val->n, mbedtls_mpi_size(val)};
 }
 
 bool mpi::is_zero() const noexcept {
@@ -189,7 +188,6 @@ mpi mpi::operator+(const mpi &addendum) const {
     mpi result;
 
     check(mbedtls_mpi_add_mpi(result.val, val, addendum.val));
-    result.shrink();
 
     return result;
 }
@@ -198,7 +196,6 @@ mpi mpi::operator-(const mpi &subtrahend) const {
     mpi result;
 
     check(mbedtls_mpi_sub_mpi(result.val, val, subtrahend.val));
-    result.shrink();
 
     return result;
 }
@@ -207,7 +204,6 @@ mpi mpi::operator*(const mpi &factor) const {
     mpi result;
 
     check(mbedtls_mpi_mul_mpi(result.val, val, factor.val));
-    result.shrink();
 
     return result;
 }
@@ -216,7 +212,6 @@ mpi mpi::operator/(const mpi &divisor) const {
     mpi result;
 
     check(mbedtls_mpi_div_mpi(result.val, nullptr, val, divisor.val));
-    result.shrink();
 
     return result;
 }
@@ -225,34 +220,28 @@ mpi mpi::operator%(const mpi &divisor) const {
     mpi remainder;
 
     check(mbedtls_mpi_div_mpi(nullptr, remainder.val, val, divisor.val));
-    remainder.shrink();
 
     return remainder;
 }
 
 void mpi::add(const mpi &addendum) {
     check(mbedtls_mpi_add_mpi(val, val, addendum.val));
-    shrink();
 }
 
 void mpi::subtract(const mpi &subtrahend) {
     check(mbedtls_mpi_sub_mpi(val, val, subtrahend.val));
-    shrink();
 }
 
 void mpi::multiply(const mpi &factor) {
     check(mbedtls_mpi_mul_mpi(val, val, factor.val));
-    shrink();
 }
 
 void mpi::divide(const mpi &divisor) {
     check(mbedtls_mpi_div_mpi(val, nullptr, val, divisor.val));
-    shrink();
 }
 
 void mpi::modulo(const mpi &divisor) {
     check(mbedtls_mpi_div_mpi(nullptr, val, val, divisor.val));
-    shrink();
 }
 
 void mpi::shrink(size_t limbs) {
@@ -268,9 +257,6 @@ mpi mpi::div_and_mod(const mpi &divisor, mpi &remainder) 
const {
 
     check(mbedtls_mpi_div_mpi(result.val, remainder.val, val, divisor.val));
 
-    result.shrink();
-    remainder.shrink();
-
     return result;
 }
 
diff --git a/modules/platforms/cpp/ignite/common/detail/mpi.h 
b/modules/platforms/cpp/ignite/common/detail/mpi.h
index 929f127a3b..908e9dfc76 100644
--- a/modules/platforms/cpp/ignite/common/detail/mpi.h
+++ b/modules/platforms/cpp/ignite/common/detail/mpi.h
@@ -45,12 +45,19 @@ struct mpi {
      * Support class for the mpi magnitude.
      */
     struct mag_view {
-        mag_view(mpi::word *ptr, const unsigned short sz)
+        mag_view(mpi::word *ptr, const unsigned short sz, std::size_t sz_nz)
             : m_ptr{ptr}
-            , m_size{sz} {}
+            , m_size{sz}
+            , m_size_non_zero{sz_nz} {}
 
-        /** Returns size of the magnitude. */
-        [[nodiscard]] std::size_t size() const noexcept { return m_size; }
+        /** Returns allocated size of the magnitude array in words. */
+        [[nodiscard]] std::size_t size_words() const noexcept { return m_size; 
}
+
+        /** Returns allocated size of the magnitude array in bytes. */
+        [[nodiscard]] std::size_t size_bytes() const noexcept { return 
size_words() * sizeof(mpi::word); }
+
+        /** Returns number of the significant bytes of the magnitude, leading 
zeros not counted. */
+        [[nodiscard]] std::size_t size_bytes_non_zero() const noexcept { 
return m_size_non_zero; }
 
         /** Subscript operator. */
         [[nodiscard]] const mpi::word &operator[](const std::size_t n) const { 
return m_ptr[n]; }
@@ -59,7 +66,7 @@ struct mpi {
         [[nodiscard]] mpi::word &operator[](const std::size_t n) { return 
m_ptr[n]; }
 
         /** Checks if the magnitude is empty. */
-        [[nodiscard]] bool empty() const noexcept { return size() == 0; }
+        [[nodiscard]] bool empty() const noexcept { return size_words() == 0; }
 
         /** Returns pointer to the magnitude beginning. */
         [[nodiscard]] mpi::word *begin() { return m_ptr; }
@@ -88,8 +95,10 @@ struct mpi {
     private:
         /** Pointer to the magnitude array. */
         mpi::word *const m_ptr;
-        /** Size of the array. */
+        /** Size of the array in words. */
         unsigned short m_size;
+        /** Bytes number of the array. Leading zeros not counted. */
+        std::size_t m_size_non_zero;
     };
 
     /** Default constructor. */

Reply via email to