Skip to content
Snippets Groups Projects
Commit b98d37ac authored by Manish R Jain's avatar Manish R Jain
Browse files

Merge pull request #81 from dgraph-io/benchmarking

Benchmarking
parents f1750167 34ba6dbc
No related branches found
No related tags found
No related merge requests found
......@@ -42,12 +42,12 @@ func main() {
c := graph.NewDGraphClient(conn)
r, err := c.Query(context.Background(), &graph.Request{Query: *q})
resp, err := c.Query(context.Background(), &graph.Request{Query: *q})
if err != nil {
x.Err(glog, err).Fatal("Error in getting response from server")
}
// TODO(pawan): Remove this later
fmt.Printf("Subgraph %+v", r)
fmt.Printf("Subgraph %+v", resp.N)
}
The files in this folder contain gobencoded data for a processed SubGraph for
the following queries. The number at the end(10,100,1000) of the files
represents the number of entities in the results of the query.
Actors query
{
me(_xid_:m.08624h) {
type.object.name.en
film.actor.film {
film.performance.film {
type.object.name.en
}
}
}
}
Directors query
{
me(_xid_:m.05dxl_) {
type.object.name.en
film.director.film {
film.film.genre {
type.object.name.en
}
}
}
}
14 May 2016
Benchmarking tests were run for ToJson and ToProtocolBuffer methods. Results
from the `go test` command are tabulated below.
BenchmarkToJSON_10_Actor 20000 92797 ns/op 22616 B/op 319 allocs/op
BenchmarkToJSON_10_Director 20000 87246 ns/op 21111 B/op 303 allocs/op
BenchmarkToJSON_100_Actor 2000 774767 ns/op 207893 B/op 2670 allocs/op
BenchmarkToJSON_100_Director 2000 579467 ns/op 142811 B/op 2103 allocs/op
BenchmarkToJSON_1000_Actor 200 7903001 ns/op 1904863 B/op 24712 allocs/op
BenchmarkToJSON_1000_Director 300 4335375 ns/op 957728 B/op 16115 allocs/op
BenchmarkToPB_10_Actor 100000 19672 ns/op 3176 B/op 60 allocs/op
BenchmarkToPB_10_Director 100000 17891 ns/op 3096 B/op 60 allocs/op
BenchmarkToPB_100_Actor 10000 372288 ns/op 30728 B/op 556 allocs/op
BenchmarkToPB_100_Director 5000 221506 ns/op 37272 B/op 701 allocs/op
BenchmarkToPB_1000_Actor 500 2612757 ns/op 296486 B/op 5383 allocs/op
BenchmarkToPB_1000_Director 300 3980677 ns/op 395600 B/op 7376 allocs/op
We can see that ToProtocolBuffer method allocates less memory and takes lesser
time than ToJson method.
File added
File added
File added
File added
File added
File added
......@@ -10,8 +10,10 @@ It is generated from these files:
It has these top-level messages:
Request
Value
Latency
Property
Node
Response
*/
package graph
......@@ -42,29 +44,41 @@ func (m *Request) String() string { return proto.CompactTextString(m)
func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type Value struct {
Str string `protobuf:"bytes,1,opt,name=str" json:"str,omitempty"`
type Latency struct {
Parsing string `protobuf:"bytes,1,opt,name=parsing" json:"parsing,omitempty"`
Processing string `protobuf:"bytes,2,opt,name=processing" json:"processing,omitempty"`
Pb string `protobuf:"bytes,3,opt,name=pb" json:"pb,omitempty"`
}
func (m *Value) Reset() { *m = Value{} }
func (m *Value) String() string { return proto.CompactTextString(m) }
func (*Value) ProtoMessage() {}
func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Latency) Reset() { *m = Latency{} }
func (m *Latency) String() string { return proto.CompactTextString(m) }
func (*Latency) ProtoMessage() {}
func (*Latency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type Property struct {
Prop string `protobuf:"bytes,1,opt,name=prop" json:"prop,omitempty"`
Val []byte `protobuf:"bytes,2,opt,name=val,proto3" json:"val,omitempty"`
}
func (m *Property) Reset() { *m = Property{} }
func (m *Property) String() string { return proto.CompactTextString(m) }
func (*Property) ProtoMessage() {}
func (*Property) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
type Node struct {
Uid uint64 `protobuf:"varint,1,opt,name=uid" json:"uid,omitempty"`
Xid string `protobuf:"bytes,2,opt,name=xid" json:"xid,omitempty"`
Attribute string `protobuf:"bytes,3,opt,name=attribute" json:"attribute,omitempty"`
Properties map[string]*Value `protobuf:"bytes,4,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Children []*Node `protobuf:"bytes,5,rep,name=children" json:"children,omitempty"`
Uid uint64 `protobuf:"varint,1,opt,name=uid" json:"uid,omitempty"`
Xid string `protobuf:"bytes,2,opt,name=xid" json:"xid,omitempty"`
Attribute string `protobuf:"bytes,3,opt,name=attribute" json:"attribute,omitempty"`
Properties []*Property `protobuf:"bytes,4,rep,name=properties" json:"properties,omitempty"`
Children []*Node `protobuf:"bytes,5,rep,name=children" json:"children,omitempty"`
}
func (m *Node) Reset() { *m = Node{} }
func (m *Node) String() string { return proto.CompactTextString(m) }
func (*Node) ProtoMessage() {}
func (*Node) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*Node) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *Node) GetProperties() map[string]*Value {
func (m *Node) GetProperties() []*Property {
if m != nil {
return m.Properties
}
......@@ -78,10 +92,36 @@ func (m *Node) GetChildren() []*Node {
return nil
}
type Response struct {
N *Node `protobuf:"bytes,1,opt,name=n" json:"n,omitempty"`
L *Latency `protobuf:"bytes,2,opt,name=l" json:"l,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *Response) GetN() *Node {
if m != nil {
return m.N
}
return nil
}
func (m *Response) GetL() *Latency {
if m != nil {
return m.L
}
return nil
}
func init() {
proto.RegisterType((*Request)(nil), "graph.Request")
proto.RegisterType((*Value)(nil), "graph.Value")
proto.RegisterType((*Latency)(nil), "graph.Latency")
proto.RegisterType((*Property)(nil), "graph.Property")
proto.RegisterType((*Node)(nil), "graph.Node")
proto.RegisterType((*Response)(nil), "graph.Response")
}
// Reference imports to suppress errors if they are not otherwise used.
......@@ -95,7 +135,7 @@ const _ = grpc.SupportPackageIsVersion2
// Client API for DGraph service
type DGraphClient interface {
Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Node, error)
Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
type dGraphClient struct {
......@@ -106,8 +146,8 @@ func NewDGraphClient(cc *grpc.ClientConn) DGraphClient {
return &dGraphClient{cc}
}
func (c *dGraphClient) Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Node, error) {
out := new(Node)
func (c *dGraphClient) Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := grpc.Invoke(ctx, "/graph.DGraph/Query", in, out, c.cc, opts...)
if err != nil {
return nil, err
......@@ -118,7 +158,7 @@ func (c *dGraphClient) Query(ctx context.Context, in *Request, opts ...grpc.Call
// Server API for DGraph service
type DGraphServer interface {
Query(context.Context, *Request) (*Node, error)
Query(context.Context, *Request) (*Response, error)
}
func RegisterDGraphServer(s *grpc.Server, srv DGraphServer) {
......@@ -156,22 +196,25 @@ var _DGraph_serviceDesc = grpc.ServiceDesc{
}
var fileDescriptor0 = []byte{
// 268 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x90, 0x41, 0x4f, 0x83, 0x40,
0x10, 0x85, 0xa5, 0xb0, 0xd5, 0x0e, 0x46, 0xcd, 0xea, 0x01, 0xab, 0x89, 0xcd, 0x1e, 0xb4, 0x27,
0x62, 0xf0, 0x62, 0xf4, 0xaa, 0xf1, 0x60, 0x62, 0x74, 0x0f, 0xde, 0xa9, 0x4c, 0x2c, 0xb1, 0x01,
0xdc, 0x5d, 0x8c, 0xfd, 0xed, 0x5e, 0x64, 0x06, 0x44, 0xd2, 0xdb, 0xe3, 0x7d, 0xb3, 0xc3, 0x9b,
0x07, 0x87, 0xef, 0x26, 0xad, 0x96, 0x06, 0x6d, 0x55, 0x16, 0x16, 0xe3, 0xca, 0x94, 0xae, 0x94,
0x82, 0x4d, 0x75, 0x06, 0xdb, 0x1a, 0x3f, 0x6b, 0xb4, 0x4e, 0x1e, 0x81, 0x68, 0x84, 0x59, 0x47,
0xde, 0xcc, 0x9b, 0x4f, 0x74, 0xfb, 0xa1, 0x8e, 0x41, 0xbc, 0xa6, 0xab, 0x1a, 0xe5, 0x01, 0xf8,
0xd6, 0x99, 0x0e, 0x92, 0x54, 0x3f, 0x1e, 0x04, 0x4f, 0x65, 0xc6, 0xa8, 0xce, 0x33, 0x46, 0x81,
0x26, 0x49, 0xce, 0x77, 0xe3, 0x8c, 0xda, 0xe1, 0x46, 0xca, 0x53, 0x98, 0xa4, 0xce, 0x99, 0x7c,
0x51, 0x3b, 0x8c, 0x7c, 0xf6, 0xff, 0x0d, 0x79, 0x0b, 0xd0, 0xc4, 0xaa, 0xd0, 0xb8, 0x1c, 0x6d,
0x14, 0xcc, 0xfc, 0x79, 0x98, 0x9c, 0xc4, 0x1c, 0x31, 0xa6, 0x5f, 0xc4, 0xcf, 0x3d, 0xbd, 0x2f,
0x9c, 0x59, 0xeb, 0xc1, 0xb8, 0xbc, 0x80, 0x9d, 0xb7, 0x65, 0xbe, 0xca, 0x0c, 0x16, 0x91, 0xe0,
0xa7, 0xe1, 0xe0, 0xa9, 0xee, 0xe1, 0xf4, 0x11, 0xf6, 0x37, 0xf6, 0x50, 0xd0, 0x0f, 0xfc, 0x3b,
0x99, 0xa4, 0x54, 0x20, 0xbe, 0xe8, 0x60, 0x0e, 0x1f, 0x26, 0xbb, 0xdd, 0x2a, 0x2e, 0x41, 0xb7,
0xe8, 0x66, 0x74, 0xed, 0x25, 0x97, 0x30, 0xbe, 0x7b, 0x20, 0x24, 0xcf, 0x41, 0xbc, 0x50, 0x57,
0x72, 0xaf, 0x9b, 0xed, 0x1a, 0x9d, 0x0e, 0x63, 0xa8, 0xad, 0xc5, 0x98, 0x9b, 0xbf, 0xfa, 0x0d,
0x00, 0x00, 0xff, 0xff, 0xe1, 0x8a, 0xe7, 0x89, 0x90, 0x01, 0x00, 0x00,
// 310 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x51, 0xcd, 0x4e, 0xf3, 0x30,
0x10, 0xfc, 0xdc, 0x26, 0xfd, 0xd9, 0x7e, 0x6a, 0xd1, 0xc2, 0x21, 0x20, 0x04, 0x95, 0x2f, 0x54,
0x1c, 0x0a, 0x2a, 0xbc, 0x01, 0x48, 0x5c, 0x10, 0x02, 0xf3, 0x04, 0x69, 0x6b, 0xb5, 0x91, 0x2a,
0xc7, 0xd8, 0x0e, 0x22, 0xaf, 0xc3, 0x93, 0x62, 0x6f, 0x9c, 0x52, 0x71, 0x1b, 0xcf, 0x8c, 0x76,
0xc6, 0xbb, 0x70, 0xbc, 0x31, 0xb9, 0xde, 0x1a, 0x69, 0x75, 0xa9, 0xac, 0x9c, 0x6b, 0x53, 0xba,
0x12, 0x53, 0x22, 0xf9, 0x25, 0xf4, 0x85, 0xfc, 0xa8, 0xa4, 0x75, 0x78, 0x02, 0xa9, 0x07, 0xa6,
0xce, 0xd8, 0x94, 0xcd, 0x86, 0xa2, 0x79, 0xf0, 0x77, 0xe8, 0x3f, 0xe7, 0x4e, 0xaa, 0x55, 0x8d,
0x19, 0xf4, 0x75, 0x6e, 0x6c, 0xa1, 0x36, 0xd1, 0xd2, 0x3e, 0xf1, 0x02, 0xc0, 0x4f, 0x5d, 0x49,
0x4b, 0x62, 0x87, 0xc4, 0x03, 0x06, 0xc7, 0xd0, 0xd1, 0xcb, 0xac, 0x4b, 0xbc, 0x47, 0xfc, 0x16,
0x06, 0xaf, 0xa6, 0xd4, 0xd2, 0xb8, 0x1a, 0x11, 0x12, 0xef, 0xd4, 0x71, 0x24, 0x61, 0x3c, 0x82,
0xee, 0x67, 0xbe, 0xa3, 0x41, 0xff, 0x45, 0x80, 0xfc, 0x9b, 0x41, 0xf2, 0x52, 0xae, 0x65, 0x90,
0xaa, 0x62, 0x4d, 0xee, 0x44, 0x04, 0x18, 0x98, 0x2f, 0xcf, 0x34, 0xa9, 0x01, 0xe2, 0x39, 0x0c,
0x73, 0xe7, 0x4c, 0xb1, 0xac, 0x9c, 0x8c, 0xa9, 0xbf, 0x04, 0xde, 0x50, 0xd9, 0x10, 0x5e, 0x48,
0x9b, 0x25, 0xd3, 0xee, 0x6c, 0xb4, 0x98, 0xcc, 0x69, 0x1d, 0xf3, 0xb6, 0x95, 0x38, 0xb0, 0xe0,
0x15, 0x0c, 0x56, 0xdb, 0x62, 0xb7, 0x36, 0x52, 0x65, 0x29, 0xd9, 0x47, 0xd1, 0x1e, 0x1a, 0x89,
0xbd, 0xc8, 0x1f, 0x60, 0x20, 0xe2, 0x96, 0xf1, 0x14, 0x98, 0xa2, 0x96, 0x7f, 0xdc, 0x4c, 0xf9,
0x7a, 0xac, 0xf9, 0xdb, 0x68, 0x31, 0x8e, 0x52, 0x5c, 0xb1, 0x60, 0xbb, 0xc5, 0x3d, 0xf4, 0x1e,
0x9f, 0x02, 0x89, 0xd7, 0x90, 0xbe, 0x85, 0x1b, 0x60, 0xeb, 0x8a, 0x97, 0x3a, 0x9b, 0xec, 0xdf,
0x4d, 0x18, 0xff, 0xb7, 0xec, 0xd1, 0x55, 0xef, 0x7e, 0x02, 0x00, 0x00, 0xff, 0xff, 0x62, 0xcc,
0xa3, 0x13, 0xec, 0x01, 0x00, 0x00,
}
......@@ -5,21 +5,33 @@ syntax="proto3";
package graph;
service DGraph {
rpc Query (Request) returns (Node) {}
rpc Query (Request) returns (Response) {}
}
message Request {
string query = 1;
}
message Value {
string str = 1;
message Latency {
string parsing = 1;
string processing = 2;
string pb = 3;
}
message Property {
string prop = 1;
bytes val = 2;
}
message Node {
uint64 uid = 1;
string xid = 2;
string attribute = 3;
map<string, Value> properties = 4;
repeated Property properties = 4;
repeated Node children = 5; // Each node can have multiple children
}
message Response {
Node n = 1;
Latency l = 2;
}
......@@ -115,8 +115,8 @@ type SubGraph struct {
Offset int
Children []*SubGraph
query []byte
result []byte
Query []byte
Result []byte
}
func mergeInterfaces(i1 interface{}, i2 interface{}) interface{} {
......@@ -138,7 +138,7 @@ func mergeInterfaces(i1 interface{}, i2 interface{}) interface{} {
}
func postTraverse(g *SubGraph) (result map[uint64]interface{}, rerr error) {
if len(g.query) == 0 {
if len(g.Query) == 0 {
return result, nil
}
......@@ -163,13 +163,13 @@ func postTraverse(g *SubGraph) (result map[uint64]interface{}, rerr error) {
}
// Now read the query and results at current node.
uo := flatbuffers.GetUOffsetT(g.query)
uo := flatbuffers.GetUOffsetT(g.Query)
q := new(task.Query)
q.Init(g.query, uo)
q.Init(g.Query, uo)
ro := flatbuffers.GetUOffsetT(g.result)
ro := flatbuffers.GetUOffsetT(g.Result)
r := new(task.Result)
r.Init(g.result, ro)
r.Init(g.Result, ro)
if q.UidsLength() != r.UidmatrixLength() {
glog.Fatalf("Result uidmatrixlength: %v. Query uidslength: %v",
......@@ -277,18 +277,18 @@ func indexOf(uid uint64, q *task.Query) int {
// This method gets the values and children for a subgraph.
func (g *SubGraph) preTraverse(uid uint64, dst *graph.Node) error {
properties := make(map[string]*graph.Value)
var properties []*graph.Property
var children []*graph.Node
// We go through all predicate children of the subgraph.
for _, pc := range g.Children {
ro := flatbuffers.GetUOffsetT(pc.result)
ro := flatbuffers.GetUOffsetT(pc.Result)
r := new(task.Result)
r.Init(pc.result, ro)
r.Init(pc.Result, ro)
uo := flatbuffers.GetUOffsetT(pc.query)
uo := flatbuffers.GetUOffsetT(pc.Query)
q := new(task.Query)
q.Init(pc.query, uo)
q.Init(pc.Query, uo)
idx := indexOf(uid, q)
......@@ -323,28 +323,21 @@ func (g *SubGraph) preTraverse(uid uint64, dst *graph.Node) error {
children = append(children, uc)
}
} else {
v := new(graph.Value)
if ok := r.Values(&tv, idx); !ok {
return fmt.Errorf("While parsing value")
}
var ival interface{}
if err := posting.ParseValue(&ival, tv.ValBytes()); err != nil {
return err
}
v := tv.ValBytes()
if ival == nil {
ival = ""
if pc.Attr == "_xid_" {
dst.Xid = string(v)
} else {
p := &graph.Property{Prop: pc.Attr, Val: v}
properties = append(properties, p)
}
v.Str = ival.(string)
properties[pc.Attr] = v
}
}
if val, ok := properties["_xid_"]; ok {
dst.Xid = val.Str
delete(properties, "_xid_")
}
dst.Properties, dst.Children = properties, children
return nil
}
......@@ -354,13 +347,13 @@ func (g *SubGraph) preTraverse(uid uint64, dst *graph.Node) error {
func (g *SubGraph) ToProtocolBuffer(l *Latency) (n *graph.Node, rerr error) {
n = &graph.Node{}
n.Attribute = g.Attr
if len(g.query) == 0 {
if len(g.Query) == 0 {
return n, nil
}
ro := flatbuffers.GetUOffsetT(g.result)
ro := flatbuffers.GetUOffsetT(g.Result)
r := new(task.Result)
r.Init(g.result, ro)
r.Init(g.Result, ro)
var ul task.UidList
r.Uidmatrix(&ul, 0)
......@@ -448,9 +441,9 @@ func newGraph(euid uint64, exid string) (*SubGraph, error) {
sg := new(SubGraph)
sg.Attr = "_root_"
sg.result = b.Bytes[b.Head():]
sg.Result = b.Bytes[b.Head():]
// Also add query for consistency and to allow for ToJson() later.
sg.query = createTaskQuery(sg, []uint64{euid})
sg.Query = createTaskQuery(sg, []uint64{euid})
return sg, nil
}
......@@ -535,8 +528,8 @@ func ProcessGraph(sg *SubGraph, rch chan error, td time.Duration) {
timeout := time.Now().Add(td)
var err error
if len(sg.query) > 0 && sg.Attr != "_root_" {
sg.result, err = worker.ProcessTaskOverNetwork(sg.query)
if len(sg.Query) > 0 && sg.Attr != "_root_" {
sg.Result, err = worker.ProcessTaskOverNetwork(sg.Query)
if err != nil {
x.Err(glog, err).Error("While processing task.")
rch <- err
......@@ -544,9 +537,9 @@ func ProcessGraph(sg *SubGraph, rch chan error, td time.Duration) {
}
}
uo := flatbuffers.GetUOffsetT(sg.result)
uo := flatbuffers.GetUOffsetT(sg.Result)
r := new(task.Result)
r.Init(sg.result, uo)
r.Init(sg.Result, uo)
if r.ValuesLength() > 0 {
var v task.Value
......@@ -589,7 +582,7 @@ func ProcessGraph(sg *SubGraph, rch chan error, td time.Duration) {
childchan := make(chan error, len(sg.Children))
for i := 0; i < len(sg.Children); i++ {
child := sg.Children[i]
child.query = createTaskQuery(child, sorted)
child.Query = createTaskQuery(child, sorted)
go ProcessGraph(child, childchan, timeleft)
}
......
......@@ -17,6 +17,8 @@
package query
import (
"bytes"
"encoding/gob"
"fmt"
"io/ioutil"
"os"
......@@ -26,6 +28,7 @@ import (
"github.com/dgraph-io/dgraph/commit"
"github.com/dgraph-io/dgraph/gql"
"github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/query/graph"
"github.com/dgraph-io/dgraph/store"
"github.com/dgraph-io/dgraph/task"
"github.com/dgraph-io/dgraph/worker"
......@@ -63,12 +66,12 @@ func checkName(t *testing.T, r *task.Result, idx int, expected string) {
func checkSingleValue(t *testing.T, child *SubGraph,
attr string, value string) {
if child.Attr != attr || len(child.result) == 0 {
t.Error("Expected attr name with some result")
if child.Attr != attr || len(child.Result) == 0 {
t.Error("Expected attr name with some.Result")
}
uo := flatbuffers.GetUOffsetT(child.result)
uo := flatbuffers.GetUOffsetT(child.Result)
r := new(task.Result)
r.Init(child.result, uo)
r.Init(child.Result, uo)
if r.ValuesLength() != 1 {
t.Errorf("Expected value length 1. Got: %v", r.ValuesLength())
}
......@@ -105,9 +108,9 @@ func TestNewGraph(t *testing.T) {
worker.Init(ps, nil, 0, 1)
uo := flatbuffers.GetUOffsetT(sg.result)
uo := flatbuffers.GetUOffsetT(sg.Result)
r := new(task.Result)
r.Init(sg.result, uo)
r.Init(sg.Result, uo)
if r.UidmatrixLength() != 1 {
t.Errorf("Expected length 1. Got: %v", r.UidmatrixLength())
}
......@@ -230,13 +233,13 @@ func TestProcessGraph(t *testing.T) {
if child.Attr != "friend" {
t.Errorf("Expected attr friend. Got: %v", child.Attr)
}
if len(child.result) == 0 {
t.Errorf("Expected some result.")
if len(child.Result) == 0 {
t.Errorf("Expected some.Result.")
return
}
uo := flatbuffers.GetUOffsetT(child.result)
uo := flatbuffers.GetUOffsetT(child.Result)
r := new(task.Result)
r.Init(child.result, uo)
r.Init(child.Result, uo)
if r.UidmatrixLength() != 1 {
t.Errorf("Expected 1 matrix. Got: %v", r.UidmatrixLength())
......@@ -257,8 +260,8 @@ func TestProcessGraph(t *testing.T) {
t.Errorf("Expected attr name")
}
child = child.Children[0]
uo = flatbuffers.GetUOffsetT(child.result)
r.Init(child.result, uo)
uo = flatbuffers.GetUOffsetT(child.Result)
r.Init(child.Result, uo)
if r.ValuesLength() != 5 {
t.Errorf("Expected 5 names of 5 friends")
}
......@@ -323,7 +326,16 @@ func TestToJson(t *testing.T) {
fmt.Printf(string(js))
}
func TestToProtocolBuffer(t *testing.T) {
func getProperty(properties []*graph.Property, prop string) []byte {
for _, p := range properties {
if p.Prop == prop {
return p.Val
}
}
return nil
}
func TestToPB(t *testing.T) {
dir, _ := populateGraph(t)
defer os.RemoveAll(dir)
......@@ -371,16 +383,17 @@ func TestToProtocolBuffer(t *testing.T) {
if gr.Uid != 1 {
t.Errorf("Expected uid 1, Got: %v", gr.Uid)
}
if gr.Xid != "mich" {
// TODO(pawan) - Fix "" being stored in the the flatbuffer val.
if gr.Xid != `"mich"` {
t.Errorf("Expected xid mich, Got: %v", gr.Xid)
}
if len(gr.Properties) != 3 {
t.Errorf("Expected values map to contain 3 properties, Got: %v",
len(gr.Properties))
}
if gr.Properties["name"].Str != "Michonne" {
if string(getProperty(gr.Properties, "name")) != `"Michonne"` {
t.Errorf("Expected property name to have value Michonne, Got: %v",
gr.Properties["name"].Str)
string(getProperty(gr.Properties, "name")))
}
if len(gr.Children) != 10 {
t.Errorf("Expected 10 children, Got: %v", len(gr.Children))
......@@ -397,9 +410,9 @@ func TestToProtocolBuffer(t *testing.T) {
t.Errorf("Expected values map to contain 1 property, Got: %v",
len(child.Properties))
}
if child.Properties["name"].Str != "Rick Grimes" {
if string(getProperty(child.Properties, "name")) != `"Rick Grimes"` {
t.Errorf("Expected property name to have value Rick Grimes, Got: %v",
child.Properties["name"].Str)
string(getProperty(child.Properties, "name")))
}
if len(child.Children) != 0 {
t.Errorf("Expected 0 children, Got: %v", len(child.Children))
......@@ -420,3 +433,67 @@ func TestToProtocolBuffer(t *testing.T) {
t.Errorf("Expected 0 children, Got: %v", len(child.Children))
}
}
func benchmarkToJson(file string, b *testing.B) {
b.ReportAllocs()
var sg SubGraph
var l Latency
f, err := ioutil.ReadFile(file)
if err != nil {
b.Error(err)
}
buf := bytes.NewBuffer(f)
dec := gob.NewDecoder(buf)
err = dec.Decode(&sg)
if err != nil {
b.Error(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := sg.ToJson(&l); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkToJSON_10_Actor(b *testing.B) { benchmarkToJson("benchmark/actors10.bin", b) }
func BenchmarkToJSON_10_Director(b *testing.B) { benchmarkToJson("benchmark/directors10.bin", b) }
func BenchmarkToJSON_100_Actor(b *testing.B) { benchmarkToJson("benchmark/actors100.bin", b) }
func BenchmarkToJSON_100_Director(b *testing.B) { benchmarkToJson("benchmark/directors100.bin", b) }
func BenchmarkToJSON_1000_Actor(b *testing.B) { benchmarkToJson("benchmark/actors1000.bin", b) }
func BenchmarkToJSON_1000_Director(b *testing.B) { benchmarkToJson("benchmark/directors1000.bin", b) }
func benchmarkToPB(file string, b *testing.B) {
b.ReportAllocs()
var sg SubGraph
var l Latency
f, err := ioutil.ReadFile(file)
if err != nil {
b.Error(err)
}
buf := bytes.NewBuffer(f)
dec := gob.NewDecoder(buf)
err = dec.Decode(&sg)
if err != nil {
b.Error(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := sg.ToProtocolBuffer(&l); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkToPB_10_Actor(b *testing.B) { benchmarkToPB("benchmark/actors10.bin", b) }
func BenchmarkToPB_10_Director(b *testing.B) { benchmarkToPB("benchmark/directors10.bin", b) }
func BenchmarkToPB_100_Actor(b *testing.B) { benchmarkToPB("benchmark/actors100.bin", b) }
func BenchmarkToPB_100_Director(b *testing.B) { benchmarkToPB("benchmark/directors100.bin", b) }
func BenchmarkToPB_1000_Actor(b *testing.B) { benchmarkToPB("benchmark/actors1000.bin", b) }
func BenchmarkToPB_1000_Director(b *testing.B) { benchmarkToPB("benchmark/directors1000.bin", b) }
......@@ -209,8 +209,8 @@ type server struct{}
// This method is used to execute the query and return the response to the
// client as a protocol buffer message.
func (s *server) Query(ctx context.Context,
req *graph.Request) (*graph.Node, error) {
resp := new(graph.Node)
req *graph.Request) (*graph.Response, error) {
resp := new(graph.Response)
if len(req.Query) == 0 {
glog.Error("While reading query")
return resp, fmt.Errorf("Empty query")
......@@ -245,11 +245,17 @@ func (s *server) Query(ctx context.Context,
l.Processing = time.Since(l.Start) - l.Parsing
glog.WithField("q", req.Query).Debug("Graph processed.")
resp, err = sg.ToProtocolBuffer(&l)
node, err := sg.ToProtocolBuffer(&l)
if err != nil {
x.Err(glog, err).Error("While converting to protocol buffer.")
return resp, err
}
resp.N = node
gl := new(graph.Latency)
gl.Parsing, gl.Processing, gl.Pb = l.Parsing.String(), l.Processing.String(),
l.ProtocolBuffer.String()
resp.L = gl
return resp, err
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment