Skip to content

Commit

Permalink
[linkedin#222]: Make TextualFromNative output deterministic
Browse files Browse the repository at this point in the history
  • Loading branch information
fgalic committed Aug 2, 2022
1 parent 5ec5a5e commit 7a4a769
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
14 changes: 13 additions & 1 deletion map.go
Expand Up @@ -15,6 +15,7 @@ import (
"io"
"math"
"reflect"
"sort"
)

func makeMapCodec(st map[string]*Codec, namespace string, schemaMap map[string]interface{}, cb *codecBuilder) (*Codec, error) {
Expand Down Expand Up @@ -243,8 +244,10 @@ func genericMapTextEncoder(buf []byte, datum interface{}, defaultCodec *Codec, c
var atLeastOne bool

buf = append(buf, '{')
sortedKeys := sortKeys(mapValues)

for key, value := range mapValues {
for _, key := range sortedKeys {
value := mapValues[key]
atLeastOne = true

// Find a codec for the key
Expand Down Expand Up @@ -305,3 +308,12 @@ func convertMap(datum interface{}) (map[string]interface{}, error) {
}
return mapValues, nil
}

func sortKeys(m map[string]interface{}) (keys []string) {
for key, _ := range m {
keys = append(keys, key)
}

sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
return keys
}
55 changes: 55 additions & 0 deletions map_test.go
Expand Up @@ -173,3 +173,58 @@ func ExampleMap() {
fmt.Println(string(buf))
// Output: {"f1":{"k1":3.5}}
}

func ExampleMapDeterministic() {
codec, err := NewCodec(`{
"name":"r1",
"type":"record",
"fields":[
{
"name":"f1",
"type":{
"type":"double"
}
},
{
"name":"a1",
"type":{
"type":"double"
}
},
{
"name":"b2",
"type":{
"type":"double"
}
},
{
"name":"c3",
"type":{
"type":"double"
}
},
{
"name":"d4",
"type":{
"type":"double"
}
}
]
}`)
if err != nil {
log.Fatal(err)
}

buf, err := codec.TextualFromNative(nil, map[string]interface{}{
"f1": 3.5,
"a1": 3.5,
"b2": 3.5,
"c3": 3.5,
"d4": 3.5,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(buf))
// Output: {"a1":3.5,"b2":3.5,"c3":3.5,"d4":3.5,"f1":3.5}
}

0 comments on commit 7a4a769

Please sign in to comment.