diff --git a/go.mod b/go.mod index 4f6c760..1185ae3 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,14 @@ -module github.com/gokch/snum_sort - -go 1.19 - -require ( - github.com/ericlagergren/decimal v0.0.0-20211103172832-aca2edc11f73 - github.com/google/go-cmp v0.5.9 -) +module github.com/gokch/snum_sort + +go 1.19 + +require ( + github.com/ericlagergren/decimal v0.0.0-20211103172832-aca2edc11f73 + github.com/stretchr/testify v1.8.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index 8e668b9..9c00c8b 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,25 @@ github.com/apmckinlay/gsuneido v0.0.0-20190404155041-0b6cd442a18f/go.mod h1:JU2DOj5Fc6rol0yaT79Csr47QR0vONGwJtBNGRD7jmc= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/ericlagergren/decimal v0.0.0-20211103172832-aca2edc11f73 h1:odNUt+pGupjtZyfaNIGLT/PUxT7r3fZ0Kf+QH9reIoM= github.com/ericlagergren/decimal v0.0.0-20211103172832-aca2edc11f73/go.mod h1:5sruVSMrZCk0U4hwRaGD0D8wIMFVsBWQqG74jQDFg4k= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sort/define.go b/sort/define.go index f718451..6050842 100644 --- a/sort/define.go +++ b/sort/define.go @@ -10,5 +10,4 @@ const ( DEF_headerBitMaskSign byte = 128 // 1000 0000 DEF_headerBitMaskStandardLen byte = 127 // 0111 1111 - DEF_headerValueSignPlus byte = DEF_headerBitMaskSign ) diff --git a/sort/sort.go b/sort/sort.go index 6eb37db..8bc3315 100644 --- a/sort/sort.go +++ b/sort/sort.go @@ -18,21 +18,20 @@ type SnumSort struct { } func (t *SnumSort) Encode() (enc []byte, err error) { - // 문자열 추출 - var bigRaw *big.Int + // get raw bigRaw, lenDecimal, isMinus := t.Snum.GetRaw() raw := bigRaw.String() - if raw == "0" { // s_num 이 0일 경우 후처리 + if raw == "0" { // 0 일 경우 전처리 lenDecimal = DEF_digitDecimalMax } lenTotal := len(raw) - // 헤더 제작 + // make header posStartDot := t.makePosStartDot(lenTotal, lenDecimal) - header := t.encodeHeader(posStartDot, isMinus) + header := t.encodeHeader(posStartDot) - // 데이터 제작 - dataCompress := make([]byte, 0, lenTotal) // n_len / 2 + (n_len%2!=0)?1:0 + // make body + dataCompress := make([]byte, 0, lenTotal) // len / 2 + (len%2!=0)?1:0 numOri := []byte(raw) for i := 0; i < lenTotal; i++ { b4 := numOri[i] - byte('0') @@ -42,18 +41,18 @@ func (t *SnumSort) Encode() (enc []byte, err error) { dataCompress[i/2] += b4 } } - // 부호가 음수(-) 일 경우 데이터 비트 반전 + // if minus, reverse bit if isMinus == true { + header = ^header lenData := len(dataCompress) for i := 0; i < lenData; i++ { - dataCompress[i] = ^dataCompress[i] // 비트 반전 + dataCompress[i] = ^dataCompress[i] } - // 음수의 경우 무조건 끝에 역정렬 알고리즘을 위한 비교마감(cut) 수치 0xFF 를 넣는다. - dataCompress = append(dataCompress, 0xFF) + dataCompress = append(dataCompress, 0xFF) // append last 0xFF } - // 헤더와 데이터를 합쳐 bt_ret 제작 + // make enc enc = make([]byte, 0, DEF_lenHeader+(lenTotal/2)) enc = append(enc, header) enc = append(enc, dataCompress...) @@ -65,26 +64,22 @@ func (t *SnumSort) Decode(enc []byte) (err error) { return errors.New("too short") } - // 헤더 정보 추출 - 부호 / 길이 + // Decode header info isMinus, lenHeader := t.decodeHeader(enc[0]) - if len(enc) == 2 && enc[1] == 0 { // _bt_num 이 0 일 경우 후처리 + if len(enc) == 2 && enc[1] == 0 { // 0 일 경우 후처리 lenHeader = byte(DEF_digitDecimalMax) } - // 데이터 추출 및 big int 설정 - var sRaw string data := enc[1:] - // 전처리 - 헤더에 따른 정보가 음수 일 경우 if isMinus == true { - // 마지막 0xFF 분리 - data = data[:len(data)-1] - // 비트 반전(데이터) - for i := 0; i < len(data); i++ { + data = data[:len(data)-1] // separate last 0xFF + for i := 0; i < len(data); i++ { // reverse bit data[i] = ^data[i] } } - // string 제작 + // make string + var sRaw string for i := 0; i < len(data); i++ { high4bit := data[i] >> 4 low4bit := data[i] - (high4bit << 4) @@ -92,11 +87,11 @@ func (t *SnumSort) Decode(enc []byte) (err error) { sRaw += string('0' + low4bit) } - // total, decimal len 추출 + // set total, decimal len lenTotal := len(sRaw) lenDecimal := t.makeLenDecimal(lenTotal, lenHeader) - // snum 세팅 + // set snum big, _ := big.NewInt(0).SetString(sRaw, 10) t.Snum.SetRaw(big, lenDecimal, isMinus) return nil @@ -109,7 +104,6 @@ func (t *SnumSort) decodeHeader(header byte) (isMinus bool, lenStandard byte) { if header&DEF_headerBitMaskSign == 0 { // 부호(+-) 추출 isMinus = true - // 음수일 경우 헤더 보수처리 header = ^header } @@ -131,13 +125,7 @@ func (t *SnumSort) makePosStartDot(lenTotal int, lenDecimal int) (posStartDot in return posStartDot } -func (t *SnumSort) encodeHeader(posStartDot int, isMinus bool) (header byte) { - // 헤더 제작 - 제작시 양수로 가정하고 제작 후 -> 후 처리에서 음수를 반영 - header = DEF_headerValueSignPlus | byte(posStartDot) - - // 음수의 경우 비트반전 - if isMinus == true { - header = ^header - } +func (t *SnumSort) encodeHeader(posStartDot int) (header byte) { + header = DEF_headerBitMaskSign | byte(posStartDot) return header } diff --git a/sort/sort_test.go b/sort/sort_test.go index 798196c..2ba3ea4 100644 --- a/sort/sort_test.go +++ b/sort/sort_test.go @@ -6,41 +6,28 @@ import ( "strings" "testing" - "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" ) -func Test_encode_decode(_t *testing.T) { +// Byte_encode, Byte_decode +// string -> bigint -> binary -> bigint -> string +func TestSort_encode_decode(t *testing.T) { fn := func(input string, expect string) { if expect == "" { expect = input } - - // Byte_encode, Byte_decode - // string -> bigint -> binary -> bigint -> string numSort := NewSnumSort(input) enc, err := numSort.Encode() - if err != nil { - _t.Error(err) - return - } + require.NoError(t, err) err = numSort.Decode(enc) - if err != nil { - _t.Error(err) - return - } + require.NoError(t, err) recovery, err := numSort.GetStr() - if err != nil { - _t.Error(err) - return - } + require.NoError(t, err) - if expect != recovery { - _t.Errorf("expect: %s, recovery: %s", expect, recovery) - return - } + require.Equalf(t, expect, recovery, "input - %s", input) } // 0 @@ -166,40 +153,36 @@ func Test_encode_decode(_t *testing.T) { } } -func Test_sort(_t *testing.T) { +func Test_sort(t *testing.T) { type Input struct { - Sn string - Bt []byte + snum string + encode []byte } oris := make([]*Input, 0, 100) - checks := make([]*Input, 0, 100) + sorts := make([]*Input, 0, 100) input := func(snum string) { sorted := NewSnumSort(snum) bt, err := sorted.Encode() - if err != nil { - _t.Errorf("input - %s | err - %v", snum, err) - } + require.NoError(t, err) - data := &Input{Sn: snum, Bt: bt} + data := &Input{snum: snum, encode: bt} oris = append(oris, data) - checks = append(checks, data) + sorts = append(sorts, data) } - check := func() { + sort := func() { // sort checks - sort.SliceStable(checks, func(i, j int) bool { - cmp := bytes.Compare(checks[i].Bt, checks[j].Bt) - if cmp == 1 { + sort.SliceStable(sorts, func(i, j int) bool { + cmp := bytes.Compare(sorts[i].encode, sorts[j].encode) + if cmp < 0 { return true } return false }) // cmp ori and sorts - if cmp.Diff(oris, checks) != "" { - _t.Errorf("err - oris != sorts\n%s", cmp.Diff(oris, checks)) - } + require.EqualValues(t, oris, sorts) } input("-" + strings.Repeat("9", DEF_digitIntegerMax) + "." + strings.Repeat("9", DEF_digitDecimalMax)) // 음수 최소값 input("-" + strings.Repeat("9", DEF_digitIntegerMax)) @@ -243,6 +226,6 @@ func Test_sort(_t *testing.T) { input(strings.Repeat("9", DEF_digitIntegerMax)) input(strings.Repeat("9", DEF_digitIntegerMax) + "." + strings.Repeat("9", DEF_digitDecimalMax)) // 양수 최대값 - check() + sort() // print() }