Skip to content

Commit 888e99d

Browse files
committed
update int encoding
1 parent 96a4279 commit 888e99d

File tree

3 files changed

+105
-110
lines changed

3 files changed

+105
-110
lines changed

encoder_int.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package bencode
2+
3+
import "unsafe"
4+
5+
const intMask uint64 = 1<<(32<<(^uint(0)>>63)) - 1
6+
7+
var intLookup [100]uint16
8+
9+
// "00010203...96979899" cast to []uint16
10+
var intLELookup = [100]uint16{
11+
0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
12+
0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
13+
0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
14+
0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
15+
0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
16+
0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
17+
0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
18+
0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
19+
0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
20+
0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939,
21+
}
22+
23+
func init() {
24+
var b [2]byte
25+
*(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD)
26+
switch b[0] {
27+
case 0xCD:
28+
intLookup = intLELookup
29+
case 0xAB:
30+
intLookup = [100]uint16{
31+
0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039,
32+
0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139,
33+
0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239,
34+
0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339,
35+
0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439,
36+
0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539,
37+
0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639,
38+
0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739,
39+
0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839,
40+
0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939,
41+
}
42+
default:
43+
panic("could not determine endianness")
44+
}
45+
}
46+
47+
func writeInt(value int64, result *[]byte, offset int, length int) (int, int) {
48+
u64 := uint64(value)
49+
n := u64 & intMask
50+
negative := value < 0
51+
if !negative {
52+
if n < 10 {
53+
length = prepareBuffer(result, offset, length, 1)
54+
(*result)[offset] = byte(n + '0')
55+
offset++
56+
return offset, length
57+
} else if n < 100 {
58+
u := intLELookup[n]
59+
length = prepareBuffer(result, offset, length, 2)
60+
(*result)[offset] = byte(u)
61+
offset++
62+
(*result)[offset] = byte(u >> 8)
63+
offset++
64+
return offset, length
65+
}
66+
} else {
67+
n = -n & intMask
68+
}
69+
var b [22]byte
70+
u := (*[11]uint16)(unsafe.Pointer(&b))
71+
i := 11
72+
for n >= 100 {
73+
j := n % 100
74+
n /= 100
75+
i--
76+
u[i] = intLookup[j]
77+
}
78+
i--
79+
u[i] = intLookup[n]
80+
i *= 2 // convert to byte index
81+
if n < 10 {
82+
i++ // remove leading zero
83+
}
84+
if negative {
85+
i--
86+
b[i] = '-'
87+
}
88+
length = prepareBuffer(result, offset, length, 22)
89+
for _, bt := range b[i:] {
90+
(*result)[offset] = bt
91+
offset++
92+
}
93+
return offset, length
94+
}
95+
96+
func marshalInt(data int64, result *[]byte, offset int, length int) (int, int) {
97+
length = prepareBuffer(result, offset, length, 1)
98+
(*result)[offset] = 'i'
99+
offset++
100+
offset, length = writeInt(data, result, offset, length)
101+
length = prepareBuffer(result, offset, length, 1)
102+
(*result)[offset] = 'e'
103+
offset++
104+
return offset, length
105+
}

marshaler.go

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -22,91 +22,6 @@ func prepareBuffer(result *[]byte, offset int, length int, neededLength int) int
2222
return length
2323
}
2424

25-
func writeIntFirstBuffer(value uint32, result *[]byte, offset int, length int) (int, int) {
26-
length = prepareBuffer(result, offset, length, 3)
27-
start := value >> 24
28-
if start == 0 {
29-
(*result)[offset] = byte(value >> 16)
30-
offset++
31-
(*result)[offset] = byte(value >> 8)
32-
offset++
33-
} else if start == 1 {
34-
(*result)[offset] = byte(value >> 8)
35-
offset++
36-
}
37-
(*result)[offset] = byte(value)
38-
offset++
39-
return offset, length
40-
}
41-
42-
func writeIntBuffer(value uint32, result *[]byte, offset int, length int) (int, int) {
43-
length = prepareBuffer(result, offset, length, 3)
44-
(*result)[offset] = byte(value >> 16)
45-
offset++
46-
(*result)[offset] = byte(value >> 8)
47-
offset++
48-
(*result)[offset] = byte(value)
49-
offset++
50-
return offset, length
51-
}
52-
53-
func writeInt(value int64, result *[]byte, offset int, length int) (int, int) {
54-
if value < 0 {
55-
value = -value
56-
length = prepareBuffer(result, offset, length, 1)
57-
(*result)[offset] = '-'
58-
offset++
59-
}
60-
q1 := value / 1000
61-
if q1 == 0 {
62-
return writeIntFirstBuffer(digits[value], result, offset, length)
63-
}
64-
r1 := value - q1*1000
65-
q2 := q1 / 1000
66-
if q2 == 0 {
67-
offset, length = writeIntFirstBuffer(digits[q1], result, offset, length)
68-
return writeIntBuffer(digits[r1], result, offset, length)
69-
}
70-
r2 := q1 - q2*1000
71-
q3 := q2 / 1000
72-
if q3 == 0 {
73-
offset, length = writeIntFirstBuffer(digits[q2], result, offset, length)
74-
offset, length = writeIntBuffer(digits[r2], result, offset, length)
75-
return writeIntBuffer(digits[r1], result, offset, length)
76-
}
77-
r3 := q2 - q3*1000
78-
q4 := q3 / 1000
79-
if q4 == 0 {
80-
offset, length = writeIntFirstBuffer(digits[q3], result, offset, length)
81-
offset, length = writeIntBuffer(digits[r3], result, offset, length)
82-
offset, length = writeIntBuffer(digits[r2], result, offset, length)
83-
return writeIntBuffer(digits[r1], result, offset, length)
84-
}
85-
r4 := q3 - q4*1000
86-
q5 := q4 / 1000
87-
if q5 == 0 {
88-
offset, length = writeIntFirstBuffer(digits[q4], result, offset, length)
89-
offset, length = writeIntBuffer(digits[r4], result, offset, length)
90-
offset, length = writeIntBuffer(digits[r3], result, offset, length)
91-
offset, length = writeIntBuffer(digits[r2], result, offset, length)
92-
return writeIntBuffer(digits[r1], result, offset, length)
93-
}
94-
r5 := q4 - q5*1000
95-
q6 := q5 / 1000
96-
if q6 == 0 {
97-
offset, length = writeIntFirstBuffer(digits[q5], result, offset, length)
98-
} else {
99-
offset, length = writeIntFirstBuffer(digits[q6], result, offset, length)
100-
r6 := q5 - q6*1000
101-
offset, length = writeIntBuffer(digits[r6], result, offset, length)
102-
}
103-
offset, length = writeIntBuffer(digits[r5], result, offset, length)
104-
offset, length = writeIntBuffer(digits[r4], result, offset, length)
105-
offset, length = writeIntBuffer(digits[r3], result, offset, length)
106-
offset, length = writeIntBuffer(digits[r2], result, offset, length)
107-
return writeIntBuffer(digits[r1], result, offset, length)
108-
}
109-
11025
func Marshal(data interface{}) ([]byte, error) {
11126
return MarshalTo(make([]byte, 512), data)
11227
}
@@ -185,17 +100,6 @@ func marshal(data interface{}, result *[]byte, offset int, length int) (int, int
185100
}
186101
}
187102

188-
func marshalInt(data int64, result *[]byte, offset int, length int) (int, int) {
189-
length = prepareBuffer(result, offset, length, 1)
190-
(*result)[offset] = 'i'
191-
offset++
192-
offset, length = writeInt(data, result, offset, length)
193-
length = prepareBuffer(result, offset, length, 1)
194-
(*result)[offset] = 'e'
195-
offset++
196-
return offset, length
197-
}
198-
199103
func marshalBytes(data []byte, result *[]byte, offset int, length int) (int, int) {
200104
dataLength := len(data)
201105
offset, length = writeInt(int64(dataLength), result, offset, length)

util.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,6 @@ import (
66
"unsafe"
77
)
88

9-
var digits []uint32
10-
11-
func init() {
12-
digits = make([]uint32, 1000)
13-
for i := uint32(0); i < 1000; i++ {
14-
digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
15-
if i < 10 {
16-
digits[i] += 2 << 24
17-
} else if i < 100 {
18-
digits[i] += 1 << 24
19-
}
20-
}
21-
}
22-
239
const strSliceLen = 20
2410

2511
func sortStrings(ss []string) {

0 commit comments

Comments
 (0)