- 
                Notifications
    
You must be signed in to change notification settings  - Fork 60
 
msgpack_ext: add string convertion for decimal datetime interval #491
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
base: master
Are you sure you want to change the base?
msgpack_ext: add string convertion for decimal datetime interval #491
Conversation
Added a decimal type conversion function to a string, added tests for this function. Added #322
Added a decimal type conversion function to a string, added tests for this function. Fixed buffer for int64. Added #322
Added a decimal type conversion function to a string, added tests for this function. Fixed name of function. Added #322
Added a decimal type conversion function to a string, added tests for this function. Fixed name of function. Add test for decimal convertion. Added #322
| 
           TestTarantoolBCDCompatibility is FAIL.  | 
    
| 
           return d.Decimal.String() - this method true, but slowly. I will correct the code and comments, at the moment I am looking for a solution to the problem.  | 
    
Added a datetime type conversion function to a string, added tests for this function. Added #322
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.
Please, squash commits into a single relevant-one.
| return ptr.UnmarshalMsgpack(b) | ||
| } | ||
| 
               | 
          ||
| // This method converts Datetime to String - formats to ISO8601. | 
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.
The go-idiomatic way to comment a method.
| // This method converts Datetime to String - formats to ISO8601. | |
| // String converts Datetime to String - formats to ISO8601. | 
| } | ||
| 
               | 
          ||
| func TestDatetimeString(t *testing.T) { | ||
| 
               | 
          
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.
| exponent := d.Decimal.Exponent() | ||
| 
               | 
          ||
| // If exponent is positive, then we use the standard method. | ||
| if exponent > 0 { | ||
| return d.Decimal.String() | ||
| } | ||
| 
               | 
          ||
| scale := -exponent | ||
| 
               | 
          ||
| if !coefficient.IsInt64() { | ||
| return d.Decimal.String() | ||
| } | ||
| 
               | 
          ||
| int64Value := coefficient.Int64() | ||
| 
               | 
          ||
| return d.stringFromInt64(int64Value, int(scale)) | ||
| } | ||
| 
               | 
          ||
| // StringFromInt64 is an internal method for converting int64 | ||
| // and scale to a string (for numbers up to 19 digits) | ||
| func (d Decimal) stringFromInt64(value int64, scale int) string { | ||
| 
               | 
          ||
| var buf [48]byte | ||
| pos := 0 | ||
| 
               | 
          ||
| negative := value < 0 | ||
| if negative { | ||
| if value == math.MinInt64 { | ||
| return d.handleMinInt64(scale) | ||
| } | ||
| buf[pos] = '-' | ||
| pos++ | ||
| value = -value | ||
| } | ||
| 
               | 
          ||
| str := strconv.FormatInt(value, 10) | ||
| length := len(str) | ||
| 
               | 
          ||
| if scale == 0 { | ||
| if pos+length > len(buf) { | ||
| return d.Decimal.String() | ||
| } | ||
| copy(buf[pos:], str) | ||
| pos += length | ||
| return string(buf[:pos]) | ||
| } | ||
| 
               | 
          ||
| if scale >= length { | ||
| 
               | 
          ||
| required := 2 + (scale - length) + length | ||
| if pos+required > len(buf) { | ||
| return d.Decimal.String() | ||
| } | ||
| 
               | 
          ||
| buf[pos] = '0' | ||
| buf[pos+1] = '.' | ||
| pos += 2 | ||
| 
               | 
          ||
| zeros := scale - length | ||
| for i := 0; i < zeros; i++ { | ||
| buf[pos] = '0' | ||
| pos++ | ||
| } | ||
| 
               | 
          ||
| copy(buf[pos:], str) | ||
| pos += length | ||
| } else { | ||
| 
               | 
          ||
| integerLen := length - scale | ||
| 
               | 
          ||
| required := integerLen + 1 + scale | ||
| if pos+required > len(buf) { | ||
| return d.Decimal.String() | ||
| } | ||
| 
               | 
          ||
| copy(buf[pos:], str[:integerLen]) | ||
| pos += integerLen | ||
| 
               | 
          ||
| buf[pos] = '.' | ||
| pos++ | ||
| 
               | 
          ||
| copy(buf[pos:], str[integerLen:]) | ||
| pos += scale | ||
| } | ||
| 
               | 
          ||
| return string(buf[:pos]) | ||
| } | ||
| func (d Decimal) handleMinInt64(scale int) string { | ||
| const minInt64Str = "9223372036854775808" | ||
| 
               | 
          ||
| var buf [48]byte | ||
| pos := 0 | ||
| 
               | 
          ||
| buf[pos] = '-' | ||
| pos++ | ||
| 
               | 
          ||
| length := len(minInt64Str) | ||
| 
               | 
          ||
| if scale == 0 { | ||
| if pos+length > len(buf) { | ||
| return "-" + minInt64Str // Fallback. | ||
| } | ||
| copy(buf[pos:], minInt64Str) | ||
| pos += length | ||
| return string(buf[:pos]) | ||
| } | ||
| 
               | 
          ||
| if scale >= length { | ||
| required := 2 + (scale - length) + length | ||
| if pos+required > len(buf) { | ||
| // Fallback. | ||
| result := "0." + strings.Repeat("0", scale-length) + minInt64Str | ||
| return "-" + result | ||
| } | ||
| 
               | 
          ||
| buf[pos] = '0' | ||
| buf[pos+1] = '.' | ||
| pos += 2 | ||
| 
               | 
          ||
| zeros := scale - length | ||
| for i := 0; i < zeros; i++ { | ||
| buf[pos] = '0' | ||
| pos++ | ||
| } | ||
| 
               | 
          ||
| copy(buf[pos:], minInt64Str) | ||
| pos += length | ||
| } else { | ||
| integerLen := length - scale | ||
| required := integerLen + 1 + scale | ||
| if pos+required > len(buf) { | ||
| return d.Decimal.String() // Fallback | ||
| } | ||
| 
               | 
          ||
| copy(buf[pos:], minInt64Str[:integerLen]) | ||
| pos += integerLen | ||
| 
               | 
          ||
| buf[pos] = '.' | ||
| pos++ | ||
| 
               | 
          ||
| copy(buf[pos:], minInt64Str[integerLen:]) | ||
| pos += scale | ||
| } | ||
| 
               | 
          ||
| return string(buf[:pos]) | ||
| } | ||
| 
               | 
          
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.
This code works faster than if you call the method d.Decimal.String() . Is it okay to leave it?
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.
Please, rename it to String and add benchmarks to compare with shopspring.Decimal if so.
msgpack_ext: add string() for decimal
Added a decimal type conversion function to a string, added tests for this function. Fixed name of function. Add test for decimal convertion. I tried to write an optimized version, but there is a problem with values when working with BCD, insignificant zeros after the decimal point are lost.
Added #322