Skip to content

Commit 7503a07

Browse files
authored
Merge branch 'master' into master
2 parents ec1a8a5 + 43d8e33 commit 7503a07

File tree

16 files changed

+709
-112
lines changed

16 files changed

+709
-112
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
* Added type assertion checks to enhance type safety and prevent unexpected panics in critical sections of the codebase
2+
* Added Flush method for topic writer
23

34
## v3.66.0
45
* Added experimental package `retry/budget` for limit second and subsequent retry attempts

internal/allocator/allocator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func New() (v *Allocator) {
6868
return allocatorPool.Get()
6969
}
7070

71+
//nolint:funlen
7172
func (a *Allocator) Free() {
7273
a.valueAllocator.free()
7374
a.typeAllocator.free()

internal/decimal/decimal.go

Lines changed: 109 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package decimal
33
import (
44
"math/big"
55
"math/bits"
6-
7-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xstring"
86
)
97

108
const (
@@ -99,27 +97,56 @@ func Parse(s string, precision, scale uint32) (*big.Int, error) {
9997
return v, nil
10098
}
10199

100+
s, neg, specialValue := setSpecialValue(s, v)
101+
if specialValue != nil {
102+
return specialValue, nil
103+
}
104+
var err error
105+
v, err = parseNumber(s, v, precision, scale, neg)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
return v, nil
111+
}
112+
113+
func setSpecialValue(s string, v *big.Int) (string, bool, *big.Int) {
114+
s, neg := parseSign(s)
115+
116+
return parseSpecialValue(s, neg, v)
117+
}
118+
119+
func parseSign(s string) (string, bool) {
102120
neg := s[0] == '-'
103121
if neg || s[0] == '+' {
104122
s = s[1:]
105123
}
124+
125+
return s, neg
126+
}
127+
128+
func parseSpecialValue(s string, neg bool, v *big.Int) (string, bool, *big.Int) {
106129
if isInf(s) {
107130
if neg {
108-
return v.Set(neginf), nil
131+
return s, neg, v.Set(neginf)
109132
}
110133

111-
return v.Set(inf), nil
134+
return s, neg, v.Set(inf)
112135
}
113136
if isNaN(s) {
114137
if neg {
115-
return v.Set(negnan), nil
138+
return s, neg, v.Set(negnan)
116139
}
117140

118-
return v.Set(nan), nil
141+
return s, neg, v.Set(nan)
119142
}
120143

121-
integral := precision - scale
144+
return s, neg, nil
145+
}
122146

147+
func parseNumber(s string, v *big.Int, precision, scale uint32, neg bool) (*big.Int, error) {
148+
var err error
149+
integral := precision - scale
123150
var dot bool
124151
for ; len(s) > 0; s = s[1:] {
125152
c := s[0]
@@ -131,12 +158,10 @@ func Parse(s string, precision, scale uint32) (*big.Int, error) {
131158

132159
continue
133160
}
134-
if dot {
135-
if scale > 0 {
136-
scale--
137-
} else {
138-
break
139-
}
161+
if dot && scale > 0 {
162+
scale--
163+
} else if dot {
164+
break
140165
}
141166

142167
if !isDigit(c) {
@@ -155,30 +180,10 @@ func Parse(s string, precision, scale uint32) (*big.Int, error) {
155180
}
156181
integral--
157182
}
158-
//nolint:nestif
159183
if len(s) > 0 { // Characters remaining.
160-
c := s[0]
161-
if !isDigit(c) {
162-
return nil, syntaxError(s)
163-
}
164-
plus := c > '5'
165-
if !plus && c == '5' {
166-
var x big.Int
167-
plus = x.And(v, one).Cmp(zero) != 0 // Last digit is not a zero.
168-
for !plus && len(s) > 1 {
169-
s = s[1:]
170-
c := s[0]
171-
if !isDigit(c) {
172-
return nil, syntaxError(s)
173-
}
174-
plus = c != '0'
175-
}
176-
}
177-
if plus {
178-
v.Add(v, one)
179-
if v.Cmp(pow(ten, precision)) >= 0 {
180-
v.Set(inf)
181-
}
184+
v, err = handleRemainingDigits(s, v, precision)
185+
if err != nil {
186+
return nil, err
182187
}
183188
}
184189
v.Mul(v, pow(ten, scale))
@@ -189,26 +194,54 @@ func Parse(s string, precision, scale uint32) (*big.Int, error) {
189194
return v, nil
190195
}
191196

197+
func handleRemainingDigits(s string, v *big.Int, precision uint32) (*big.Int, error) {
198+
c := s[0]
199+
if !isDigit(c) {
200+
return nil, syntaxError(s)
201+
}
202+
plus := c > '5'
203+
if !plus && c == '5' {
204+
var x big.Int
205+
plus = x.And(v, one).Cmp(zero) != 0 // Last digit is not a zero.
206+
for !plus && len(s) > 1 {
207+
s = s[1:]
208+
c := s[0]
209+
if !isDigit(c) {
210+
return nil, syntaxError(s)
211+
}
212+
plus = c != '0'
213+
}
214+
}
215+
if plus {
216+
v.Add(v, one)
217+
if v.Cmp(pow(ten, precision)) >= 0 {
218+
v.Set(inf)
219+
}
220+
}
221+
222+
return v, nil
223+
}
224+
192225
// Format returns the string representation of x with the given precision and
193226
// scale.
194227
func Format(x *big.Int, precision, scale uint32) string {
195-
switch {
196-
case x.CmpAbs(inf) == 0:
228+
// Check for special values and nil pointer upfront.
229+
if x == nil {
230+
return "0"
231+
}
232+
if x.CmpAbs(inf) == 0 {
197233
if x.Sign() < 0 {
198234
return "-inf"
199235
}
200236

201237
return "inf"
202-
203-
case x.CmpAbs(nan) == 0:
238+
}
239+
if x.CmpAbs(nan) == 0 {
204240
if x.Sign() < 0 {
205241
return "-nan"
206242
}
207243

208244
return "nan"
209-
210-
case x == nil:
211-
return "0"
212245
}
213246

214247
v := big.NewInt(0).Set(x)
@@ -232,42 +265,59 @@ func Format(x *big.Int, precision, scale uint32) string {
232265

233266
digit.Mod(v, ten)
234267
d := int(digit.Int64())
235-
if d != 0 || scale == 0 || pos > 0 {
236-
const numbers = "0123456789"
237-
pos--
238-
bts[pos] = numbers[d]
268+
269+
pos--
270+
if d != 0 || scale == 0 || pos >= 0 {
271+
setDigitAtPosition(bts, pos, d)
239272
}
273+
240274
if scale > 0 {
241275
scale--
242276
if scale == 0 && pos > 0 {
277+
bts[pos-1] = '.'
243278
pos--
244-
bts[pos] = '.'
245279
}
246280
}
247281
}
248-
if scale > 0 {
249-
for ; scale > 0; scale-- {
250-
if precision == 0 {
251-
return errorTag
252-
}
253-
precision--
254-
pos--
255-
bts[pos] = '0'
256-
}
257282

283+
for ; scale > 0; scale-- {
284+
if precision == 0 {
285+
pos = 0
286+
287+
break
288+
}
289+
precision--
258290
pos--
259-
bts[pos] = '.'
291+
bts[pos] = '0'
260292
}
293+
261294
if bts[pos] == '.' {
262295
pos--
263296
bts[pos] = '0'
264297
}
298+
265299
if neg {
266300
pos--
267301
bts[pos] = '-'
268302
}
269303

270-
return xstring.FromBytes(bts[pos:])
304+
return string(bts[pos:])
305+
}
306+
307+
func abs(x *big.Int) (*big.Int, bool) {
308+
v := big.NewInt(0).Set(x)
309+
neg := x.Sign() < 0
310+
if neg {
311+
// Convert negative to positive.
312+
v.Neg(x)
313+
}
314+
315+
return v, neg
316+
}
317+
318+
func setDigitAtPosition(bts []byte, pos, digit int) {
319+
const numbers = "0123456789"
320+
bts[pos] = numbers[digit]
271321
}
272322

273323
// BigIntToByte returns the 16-byte array representation of x.

0 commit comments

Comments
 (0)