ayushpranjal-dremio commented on code in PR #12306:
URL: https://github.com/apache/arrow/pull/12306#discussion_r869332563
##########
cpp/src/gandiva/gdv_function_stubs.cc:
##########
@@ -296,6 +296,215 @@ CAST_NUMERIC_FROM_VARBINARY(double, arrow::DoubleType,
FLOAT8)
#undef GDV_FN_CAST_VARCHAR_INTEGER
#undef GDV_FN_CAST_VARCHAR_REAL
+GDV_FORCE_INLINE
+int64_t unsigned_long_div(int64_t x, int32_t m) {
+ if (x >= 0) {
+ return x / m;
+ }
+ return x / m + 2 * (LONG_MAX / m) + 2 / m + (x % m + 2 * (LONG_MAX % m) + 2
% m) / m;
+}
+
+GDV_FORCE_INLINE
+int64_t encode(int32_t radix, int32_t fromPos, const char* value, int32_t
valueLen) {
+ int64_t val = 0;
+ int64_t bound = unsigned_long_div(-1 - radix, radix);
+
+ for (int i = fromPos; i < valueLen && value[i] >= 0; i++) {
+ if (val >= bound) {
+ if (unsigned_long_div(-1 - value[i], radix) < val) {
+ return -1;
+ }
+ }
+ val = val * radix + value[i];
+ }
+ return val;
+}
+
+GDV_FORCE_INLINE
+void decode(uint64_t val, int32_t radix, char* value, int32_t valueLen) {
+ for (int i = 0; i < valueLen; i++) {
+ value[i] = static_cast<char>(0);
+ }
+
+ for (int i = valueLen - 1; val != 0; i--) {
+ uint64_t q = unsigned_long_div(val, radix);
+ value[i] = static_cast<char>((val - q * radix));
+ val = q;
+ }
+}
+
+// From Decimal to Any Base
+GDV_FORCE_INLINE
+char character_for_digit(int32_t value, int32_t radix) {
+ // This function is similar to Character.forDigit in Java
+ int digit = 0;
+ digit = value % radix;
+ if (digit < 10) {
+ return static_cast<char>(digit + '0');
+ } else {
+ return static_cast<char>(digit + 'A' - 10);
+ }
+}
+
+// From any base to Decimal
+GDV_FORCE_INLINE
+int64_t character_digit(char value, int32_t radix, int32_t& valid_entry) {
+ // This function is similar to Character.digit in Java
+ if ((radix <= 0) || (radix > 36)) {
+ valid_entry = -1;
+ return -1;
+ }
+
+ if (radix <= 10) {
+ if (value >= '0' && value < '0' + radix) {
+ return value - '0';
+ } else {
+ valid_entry = -1;
+ return -1;
+ }
+ } else if (value >= '0' && value <= '9') {
+ return value - '0';
+ } else if (value >= 'a' && value < 'a' + radix - 10) {
+ return value - 'a' + 10;
+ } else if (value >= 'A' && value < 'A' + radix - 10) {
+ return value - 'A' + 10;
+ }
+ valid_entry = -1;
+ return -1;
+}
+
+GDV_FORCE_INLINE
+void byte2char(int32_t radix, int32_t fromPos, char* value, int32_t valueLen) {
Review Comment:
Add a comment on what this function is supposed to do. Also add unit tests
for helper functions.
##########
cpp/src/gandiva/gdv_function_stubs.cc:
##########
@@ -296,6 +296,215 @@ CAST_NUMERIC_FROM_VARBINARY(double, arrow::DoubleType,
FLOAT8)
#undef GDV_FN_CAST_VARCHAR_INTEGER
#undef GDV_FN_CAST_VARCHAR_REAL
+GDV_FORCE_INLINE
+int64_t unsigned_long_div(int64_t x, int32_t m) {
+ if (x >= 0) {
+ return x / m;
+ }
+ return x / m + 2 * (LONG_MAX / m) + 2 / m + (x % m + 2 * (LONG_MAX % m) + 2
% m) / m;
+}
+
+GDV_FORCE_INLINE
+int64_t encode(int32_t radix, int32_t fromPos, const char* value, int32_t
valueLen) {
+ int64_t val = 0;
+ int64_t bound = unsigned_long_div(-1 - radix, radix);
+
+ for (int i = fromPos; i < valueLen && value[i] >= 0; i++) {
+ if (val >= bound) {
+ if (unsigned_long_div(-1 - value[i], radix) < val) {
+ return -1;
+ }
+ }
+ val = val * radix + value[i];
+ }
+ return val;
+}
+
+GDV_FORCE_INLINE
+void decode(uint64_t val, int32_t radix, char* value, int32_t valueLen) {
+ for (int i = 0; i < valueLen; i++) {
+ value[i] = static_cast<char>(0);
+ }
+
+ for (int i = valueLen - 1; val != 0; i--) {
+ uint64_t q = unsigned_long_div(val, radix);
+ value[i] = static_cast<char>((val - q * radix));
+ val = q;
+ }
+}
+
+// From Decimal to Any Base
+GDV_FORCE_INLINE
+char character_for_digit(int32_t value, int32_t radix) {
+ // This function is similar to Character.forDigit in Java
+ int digit = 0;
+ digit = value % radix;
+ if (digit < 10) {
+ return static_cast<char>(digit + '0');
+ } else {
+ return static_cast<char>(digit + 'A' - 10);
+ }
+}
+
+// From any base to Decimal
+GDV_FORCE_INLINE
+int64_t character_digit(char value, int32_t radix, int32_t& valid_entry) {
+ // This function is similar to Character.digit in Java
+ if ((radix <= 0) || (radix > 36)) {
+ valid_entry = -1;
+ return -1;
+ }
+
+ if (radix <= 10) {
+ if (value >= '0' && value < '0' + radix) {
+ return value - '0';
+ } else {
+ valid_entry = -1;
+ return -1;
+ }
+ } else if (value >= '0' && value <= '9') {
+ return value - '0';
+ } else if (value >= 'a' && value < 'a' + radix - 10) {
+ return value - 'a' + 10;
+ } else if (value >= 'A' && value < 'A' + radix - 10) {
+ return value - 'A' + 10;
+ }
+ valid_entry = -1;
+ return -1;
+}
+
+GDV_FORCE_INLINE
+void byte2char(int32_t radix, int32_t fromPos, char* value, int32_t valueLen) {
+ for (int i = fromPos; i < valueLen; i++) {
+ value[i] = static_cast<char>(character_for_digit(value[i], radix));
+ }
+}
+
+GDV_FORCE_INLINE
+void char2byte(int32_t radix, int32_t fromPos, char* value, int32_t valueLen,
+ int32_t* valid_entry) {
Review Comment:
Add a comment on what this function is supposed to do. Also add unit tests
for helper functions.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]