Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
rabbitprincess committed Nov 29, 2022
1 parent 4ce54fa commit 8a528d2
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 82 deletions.
22 changes: 14 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -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
)
19 changes: 17 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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=
1 change: 0 additions & 1 deletion sort/define.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ const (

DEF_headerBitMaskSign byte = 128 // 1000 0000
DEF_headerBitMaskStandardLen byte = 127 // 0111 1111
DEF_headerValueSignPlus byte = DEF_headerBitMaskSign
)
54 changes: 21 additions & 33 deletions sort/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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...)
Expand All @@ -65,38 +64,34 @@ 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)
sRaw += string('0' + high4bit)
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
Expand All @@ -109,7 +104,6 @@ func (t *SnumSort) decodeHeader(header byte) (isMinus bool, lenStandard byte) {
if header&DEF_headerBitMaskSign == 0 {
// 부호(+-) 추출
isMinus = true
// 음수일 경우 헤더 보수처리
header = ^header
}

Expand All @@ -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
}
59 changes: 21 additions & 38 deletions sort/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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()
}

0 comments on commit 8a528d2

Please sign in to comment.