Skip to content

Commit

Permalink
Make HTTP JSON response encoding more efficient
Browse files Browse the repository at this point in the history
Currently we use a fast JSON encoder to encode results. Then put that in
a map, and run json.Marshal on that map. This PR changes that to
generate the JSON response in a similar way to how fast
encoder works, i.e. by operating on a bytes.Buffer directly.
  • Loading branch information
manishrjain committed Dec 19, 2018
1 parent d71ecc8 commit ae1d9f3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
35 changes: 24 additions & 11 deletions dgraph/cmd/alpha/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package alpha

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -117,13 +118,27 @@ func queryHandler(w http.ResponseWriter, r *http.Request) {
return
}

response := map[string]interface{}{}
var out bytes.Buffer
writeEntry := func(key string, js []byte) {
out.WriteRune('"')
out.WriteString(key)
out.WriteRune('"')
out.WriteRune(':')
out.Write(js)
}

e := query.Extensions{
Txn: resp.Txn,
Latency: resp.Latency,
}
response["extensions"] = e
js, err := json.Marshal(e)
if err != nil {
x.SetStatusWithData(w, x.Error, err.Error())
return
}
out.WriteRune('{')
writeEntry("extensions", js)
out.WriteRune(',')

// User can either ask for schema or have a query.
if len(resp.Schema) > 0 {
Expand All @@ -135,18 +150,16 @@ func queryHandler(w http.ResponseWriter, r *http.Request) {
x.SetStatusWithData(w, x.Error, "Unable to marshal schema")
return
}
mp := map[string]interface{}{}
mp["schema"] = json.RawMessage(string(js))
response["data"] = mp
} else {
response["data"] = json.RawMessage(string(resp.Json))
}

if js, err := json.Marshal(response); err == nil {
w.Write(js)
writeEntry("data", nil)
out.WriteRune('{')
writeEntry("schema", js)
out.WriteRune('}')
} else {
x.SetStatusWithData(w, x.Error, "Unable to marshal response")
writeEntry("data", resp.Json)
}
out.WriteRune('}')
w.Write(out.Bytes())
}

func mutationHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
9 changes: 2 additions & 7 deletions query/outputnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -145,10 +144,8 @@ func (fj *fastJsonNode) IsEmpty() bool {

func valToBytes(v types.Val) ([]byte, error) {
switch v.Tid {
case types.BinaryID:
// Encode to base64 and add "" around the value.
b := fmt.Sprintf("%q", v.Value.([]byte))
return []byte(b), nil
case types.BinaryID, types.StringID, types.DefaultID:
return []byte(fmt.Sprintf("%q", v.Value)), nil
case types.IntID:
return []byte(fmt.Sprintf("%d", v.Value)), nil
case types.FloatID:
Expand All @@ -158,8 +155,6 @@ func valToBytes(v types.Val) ([]byte, error) {
return []byte("true"), nil
}
return []byte("false"), nil
case types.StringID, types.DefaultID:
return []byte(strconv.Quote(v.Value.(string))), nil
case types.DateTimeID:
return v.Value.(time.Time).MarshalJSON()
case types.GeoID:
Expand Down

0 comments on commit ae1d9f3

Please sign in to comment.