Enable sorting of negative numbers and floats
This commit is contained in:
parent
fdb639e517
commit
40a52dfbf1
3 changed files with 90 additions and 101 deletions
|
@ -220,10 +220,10 @@ func TestMain(t *testing.T) {
|
|||
IB: true,
|
||||
IF: false,
|
||||
IT: clock,
|
||||
II: float64(19387),
|
||||
II: float64(19387.1),
|
||||
ID: float64(183784.13413),
|
||||
INA: []interface{}{true, false, nil, "Test", clock, float64(192), 1.1, 1.2, 1.3},
|
||||
AIN: []interface{}{true, false, nil, "Test", clock, float64(192), float64(MaxNumber), 1.1, 1.2, 1.3, []interface{}{"Test"}},
|
||||
INA: []interface{}{true, false, nil, "Test", clock, int64(192), 1.1, 1.2, 1.3},
|
||||
AIN: []interface{}{true, false, nil, "Test", clock, int64(192), 1.1, 1.2, 1.3, []interface{}{"Test"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -236,12 +236,12 @@ func TestMain(t *testing.T) {
|
|||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: nil},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: false},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: true},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -9223372036854775807},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -2147483647},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -32767},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -12},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -2},
|
||||
// &Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -1},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -9223372036854775807},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -2147483647},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -32767},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -12},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -2},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: -1},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: 0},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: 1},
|
||||
&Thing{KV: "kv", NS: "ns", DB: "db", TB: "person", ID: 2},
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"bufio"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -122,66 +123,84 @@ func (r *reader) FindString() (val string) {
|
|||
return
|
||||
}
|
||||
|
||||
func (r *reader) FindNumber() (val float64) {
|
||||
if r.ReadNext(cNUMBER) {
|
||||
if r.ReadNext(cNILL) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &val)
|
||||
val = 0 - val
|
||||
r.ReadNext(cTERM)
|
||||
} else if r.ReadNext(cBOOL) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &val)
|
||||
r.ReadNext(cTERM)
|
||||
func (r *reader) FindNumber() (val interface{}) {
|
||||
var dec uint64
|
||||
var num float64
|
||||
if r.ReadNext(cNEG) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &dec)
|
||||
num = math.Float64frombits(^dec)
|
||||
r.ReadNext(cEND)
|
||||
} else if r.ReadNext(cPOS) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &dec)
|
||||
num = math.Float64frombits(dec)
|
||||
r.ReadNext(cEND)
|
||||
}
|
||||
if math.Trunc(num) == num {
|
||||
return int64(math.Trunc(num))
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
func (r *reader) FindDouble() (val float64) {
|
||||
var dec uint64
|
||||
if r.ReadNext(cNEG) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &dec)
|
||||
val = math.Float64frombits(^dec)
|
||||
r.ReadNext(cEND)
|
||||
} else if r.ReadNext(cPOS) {
|
||||
binary.Read(r.Reader, binary.BigEndian, &dec)
|
||||
val = math.Float64frombits(dec)
|
||||
r.ReadNext(cEND)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberInt() (val int) {
|
||||
return int(r.FindNumber())
|
||||
return int(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberInt8() (val int8) {
|
||||
return int8(r.FindNumber())
|
||||
return int8(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberInt16() (val int16) {
|
||||
return int16(r.FindNumber())
|
||||
return int16(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberInt32() (val int32) {
|
||||
return int32(r.FindNumber())
|
||||
return int32(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberInt64() (val int64) {
|
||||
return int64(r.FindNumber())
|
||||
return int64(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberUint() (val uint) {
|
||||
return uint(r.FindNumber())
|
||||
return uint(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberUint8() (val uint8) {
|
||||
return uint8(r.FindNumber())
|
||||
return uint8(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberUint16() (val uint16) {
|
||||
return uint16(r.FindNumber())
|
||||
return uint16(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberUint32() (val uint32) {
|
||||
return uint32(r.FindNumber())
|
||||
return uint32(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberUint64() (val uint64) {
|
||||
return uint64(r.FindNumber())
|
||||
return uint64(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberFloat32() (val float32) {
|
||||
return float32(r.FindNumber())
|
||||
return float32(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindNumberFloat64() (val float64) {
|
||||
return float64(r.FindNumber())
|
||||
return float64(r.FindDouble())
|
||||
}
|
||||
|
||||
func (r *reader) FindArray() (val []interface{}) {
|
||||
|
|
|
@ -17,7 +17,10 @@ package keys
|
|||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type writer struct {
|
||||
|
@ -38,94 +41,61 @@ func (w *writer) Write(i interface{}) {
|
|||
w.Writer.Write(v)
|
||||
|
||||
case string:
|
||||
w.Writer.Write([]byte(v))
|
||||
w.writeString(v)
|
||||
|
||||
case time.Time:
|
||||
binary.Write(w.Writer, binary.BigEndian, v.UnixNano())
|
||||
w.writeTime(v)
|
||||
|
||||
case uint:
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case uint8:
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case uint16:
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case uint32:
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case uint64:
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
w.writeNumber(float64(v))
|
||||
|
||||
case int:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case int8:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case int16:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case int32:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case int64:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
w.writeNumber(float64(v))
|
||||
|
||||
case float32:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
|
||||
w.writeNumber(float64(v))
|
||||
case float64:
|
||||
if v < 0 {
|
||||
w.Write(bNILL)
|
||||
binary.Write(w.Writer, binary.BigEndian, 0-float64(v))
|
||||
} else {
|
||||
w.Write(bBOOL)
|
||||
binary.Write(w.Writer, binary.BigEndian, float64(v))
|
||||
}
|
||||
w.writeNumber(float64(v))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (w *writer) writeString(v string) {
|
||||
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&v))))
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
func (w *writer) writeTime(v time.Time) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(v.UTC().UnixNano()))
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
func (w *writer) writeNumber(v float64) {
|
||||
b := make([]byte, 8)
|
||||
if v < 0 {
|
||||
w.Write(bNEG)
|
||||
binary.BigEndian.PutUint64(b, ^math.Float64bits(v))
|
||||
} else {
|
||||
w.Write(bPOS)
|
||||
binary.BigEndian.PutUint64(b, math.Float64bits(v))
|
||||
}
|
||||
w.Write(b)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue