Add extra methods to convert between uint64 and big-endian bytes slice (#11338)

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
pull/11339/head
zhenshan.cao 2021-11-05 19:10:59 +08:00 committed by GitHub
parent db2a0a3bd3
commit 9885838593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 7 deletions

View File

@ -85,7 +85,8 @@ func (t *timestampOracle) loadTimestamp() (time.Time, error) {
// save timestamp, if lastTs is 0, we think the timestamp doesn't exist, so create it,
// otherwise, update it.
func (t *timestampOracle) saveTimestamp(ts time.Time) error {
data := typeutil.Uint64ToBytes(uint64(ts.UnixNano()))
//we use big endian here for compatibility issues
data := typeutil.Uint64ToBytesBigEndian(uint64(ts.UnixNano()))
err := t.txnKV.Save(t.key, string(data))
if err != nil {
return errors.WithStack(err)

View File

@ -52,8 +52,8 @@ func Int64ToBytes(v int64) []byte {
return b
}
// BytesToUint64 converts a byte slice to uint64.
func BytesToUint64(b []byte) (uint64, error) {
// BigEndianBytesToUint64 converts a byte slice (big endian) to uint64.
func BigEndianBytesToUint64(b []byte) (uint64, error) {
if len(b) != 8 {
return 0, fmt.Errorf("Failed to convert []byte to uint64: invalid data, must 8 bytes, but %d", len(b))
}
@ -62,12 +62,25 @@ func BytesToUint64(b []byte) (uint64, error) {
return binary.BigEndian.Uint64(b), nil
}
// Uint64ToBytesBigEndian converts uint64 to a byte slice(big endian).
func Uint64ToBytesBigEndian(v uint64) []byte {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, v)
return b
}
// BytesToUint64 converts a byte slice to uint64.
func BytesToUint64(b []byte) (uint64, error) {
if len(b) != 8 {
return 0, fmt.Errorf("Failed to convert []byte to uint64: invalid data, must 8 bytes, but %d", len(b))
}
return common.Endian.Uint64(b), nil
}
// Uint64ToBytes converts uint64 to a byte slice.
func Uint64ToBytes(v uint64) []byte {
b := make([]byte, 8)
// do not use little or common endian for compatibility issues(the msgid used in rocksmq is using this)
binary.BigEndian.PutUint64(b, v)
common.Endian.PutUint64(b, v)
return b
}

View File

@ -65,6 +65,22 @@ func TestConversion(t *testing.T) {
assert.NotNil(t, err)
})
t.Run("TestConvertUint64BigEndian", func(t *testing.T) {
comp := func(u uint64) {
ub := Uint64ToBytesBigEndian(u)
u1, err := BigEndianBytesToUint64(ub)
assert.Nil(t, err)
assert.Equal(t, u, u1)
}
comp(uint64(314))
comp(uint64(0))
comp(uint64(75123348654273))
comp(uint64(math.MaxUint64))
_, err := BytesToUint64([]byte("ab"))
assert.NotNil(t, err)
})
t.Run("TestSliceRemoveDuplicate", func(t *testing.T) {
ret := SliceRemoveDuplicate(1)
assert.Equal(t, 0, len(ret))

View File

@ -27,7 +27,8 @@ var ZeroTimestamp = Timestamp(0)
// ParseTimestamp returns a timestamp for a given byte slice.
func ParseTimestamp(data []byte) (time.Time, error) {
nano, err := BytesToUint64(data)
//we use big endian here for compatibility issues
nano, err := BigEndianBytesToUint64(data)
if err != nil {
return ZeroTime, err
}