Enable sorting of negative numbers and floats

This commit is contained in:
Tobie Morgan Hitchcock 2016-10-14 07:14:34 +01:00
parent fdb639e517
commit 40a52dfbf1
3 changed files with 90 additions and 101 deletions

View file

@ -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},

View file

@ -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{}) {

View file

@ -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)
}