Skip to content
Snippets Groups Projects
Commit 5a62b48a authored by Pawan Rawal's avatar Pawan Rawal
Browse files

Refactored

Removed the unnecessary extract function and result struct. Now preTraverse
directly acceses flatbuffers to get values and uidmatrix.
Renamed struct fields in the protocol buffer schema file.
parent 87e81038
No related branches found
No related tags found
No related merge requests found
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"github.com/dgraph-io/dgraph/query/pb" "github.com/dgraph-io/dgraph/query/graph"
"github.com/dgraph-io/dgraph/x" "github.com/dgraph-io/dgraph/x"
) )
...@@ -40,9 +40,9 @@ func main() { ...@@ -40,9 +40,9 @@ func main() {
} }
defer conn.Close() defer conn.Close()
c := pb.NewDGraphClient(conn) c := graph.NewDGraphClient(conn)
r, err := c.Query(context.Background(), &pb.GraphRequest{Query: *q}) r, err := c.Query(context.Background(), &graph.Request{Query: *q})
if err != nil { if err != nil {
x.Err(glog, err).Fatal("Error in getting response from server") x.Err(glog, err).Fatal("Error in getting response from server")
} }
......
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
// DO NOT EDIT! // DO NOT EDIT!
/* /*
Package pb is a generated protocol buffer package. Package graph is a generated protocol buffer package.
It is generated from these files: It is generated from these files:
graphresponse.proto graphresponse.proto
It has these top-level messages: It has these top-level messages:
GraphRequest Request
Value Value
GraphResponse Node
*/ */
package pb package graph
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
...@@ -33,17 +33,17 @@ var _ = math.Inf ...@@ -33,17 +33,17 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1 const _ = proto.ProtoPackageIsVersion1
type GraphRequest struct { type Request struct {
Query string `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"` Query string `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"`
} }
func (m *GraphRequest) Reset() { *m = GraphRequest{} } func (m *Request) Reset() { *m = Request{} }
func (m *GraphRequest) String() string { return proto.CompactTextString(m) } func (m *Request) String() string { return proto.CompactTextString(m) }
func (*GraphRequest) ProtoMessage() {} func (*Request) ProtoMessage() {}
func (*GraphRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type Value struct { type Value struct {
Byte []byte `protobuf:"bytes,1,opt,name=byte,proto3" json:"byte,omitempty"` Binary []byte `protobuf:"bytes,1,opt,name=binary,proto3" json:"binary,omitempty"`
} }
func (m *Value) Reset() { *m = Value{} } func (m *Value) Reset() { *m = Value{} }
...@@ -51,25 +51,26 @@ func (m *Value) String() string { return proto.CompactTextString(m) } ...@@ -51,25 +51,26 @@ func (m *Value) String() string { return proto.CompactTextString(m) }
func (*Value) ProtoMessage() {} func (*Value) ProtoMessage() {}
func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type GraphResponse struct { type Node struct {
Attribute string `protobuf:"bytes,1,opt,name=attribute" json:"attribute,omitempty"` Uid uint64 `protobuf:"varint,1,opt,name=uid" json:"uid,omitempty"`
Values map[string]*Value `protobuf:"bytes,2,rep,name=values" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Attribute string `protobuf:"bytes,2,opt,name=attribute" json:"attribute,omitempty"`
Children []*GraphResponse `protobuf:"bytes,3,rep,name=children" json:"children,omitempty"` Properties map[string]*Value `protobuf:"bytes,3,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Children []*Node `protobuf:"bytes,4,rep,name=children" json:"children,omitempty"`
} }
func (m *GraphResponse) Reset() { *m = GraphResponse{} } func (m *Node) Reset() { *m = Node{} }
func (m *GraphResponse) String() string { return proto.CompactTextString(m) } func (m *Node) String() string { return proto.CompactTextString(m) }
func (*GraphResponse) ProtoMessage() {} func (*Node) ProtoMessage() {}
func (*GraphResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (*Node) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *GraphResponse) GetValues() map[string]*Value { func (m *Node) GetProperties() map[string]*Value {
if m != nil { if m != nil {
return m.Values return m.Properties
} }
return nil return nil
} }
func (m *GraphResponse) GetChildren() []*GraphResponse { func (m *Node) GetChildren() []*Node {
if m != nil { if m != nil {
return m.Children return m.Children
} }
...@@ -77,9 +78,9 @@ func (m *GraphResponse) GetChildren() []*GraphResponse { ...@@ -77,9 +78,9 @@ func (m *GraphResponse) GetChildren() []*GraphResponse {
} }
func init() { func init() {
proto.RegisterType((*GraphRequest)(nil), "pb.GraphRequest") proto.RegisterType((*Request)(nil), "graph.Request")
proto.RegisterType((*Value)(nil), "pb.Value") proto.RegisterType((*Value)(nil), "graph.Value")
proto.RegisterType((*GraphResponse)(nil), "pb.GraphResponse") proto.RegisterType((*Node)(nil), "graph.Node")
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
...@@ -93,7 +94,7 @@ const _ = grpc.SupportPackageIsVersion2 ...@@ -93,7 +94,7 @@ const _ = grpc.SupportPackageIsVersion2
// Client API for DGraph service // Client API for DGraph service
type DGraphClient interface { type DGraphClient interface {
Query(ctx context.Context, in *GraphRequest, opts ...grpc.CallOption) (*GraphResponse, error) Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Node, error)
} }
type dGraphClient struct { type dGraphClient struct {
...@@ -104,9 +105,9 @@ func NewDGraphClient(cc *grpc.ClientConn) DGraphClient { ...@@ -104,9 +105,9 @@ func NewDGraphClient(cc *grpc.ClientConn) DGraphClient {
return &dGraphClient{cc} return &dGraphClient{cc}
} }
func (c *dGraphClient) Query(ctx context.Context, in *GraphRequest, opts ...grpc.CallOption) (*GraphResponse, error) { func (c *dGraphClient) Query(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Node, error) {
out := new(GraphResponse) out := new(Node)
err := grpc.Invoke(ctx, "/pb.DGraph/Query", in, out, c.cc, opts...) err := grpc.Invoke(ctx, "/graph.DGraph/Query", in, out, c.cc, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -116,7 +117,7 @@ func (c *dGraphClient) Query(ctx context.Context, in *GraphRequest, opts ...grpc ...@@ -116,7 +117,7 @@ func (c *dGraphClient) Query(ctx context.Context, in *GraphRequest, opts ...grpc
// Server API for DGraph service // Server API for DGraph service
type DGraphServer interface { type DGraphServer interface {
Query(context.Context, *GraphRequest) (*GraphResponse, error) Query(context.Context, *Request) (*Node, error)
} }
func RegisterDGraphServer(s *grpc.Server, srv DGraphServer) { func RegisterDGraphServer(s *grpc.Server, srv DGraphServer) {
...@@ -124,7 +125,7 @@ func RegisterDGraphServer(s *grpc.Server, srv DGraphServer) { ...@@ -124,7 +125,7 @@ func RegisterDGraphServer(s *grpc.Server, srv DGraphServer) {
} }
func _DGraph_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _DGraph_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GraphRequest) in := new(Request)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
...@@ -133,16 +134,16 @@ func _DGraph_Query_Handler(srv interface{}, ctx context.Context, dec func(interf ...@@ -133,16 +134,16 @@ func _DGraph_Query_Handler(srv interface{}, ctx context.Context, dec func(interf
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/pb.DGraph/Query", FullMethod: "/graph.DGraph/Query",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DGraphServer).Query(ctx, req.(*GraphRequest)) return srv.(DGraphServer).Query(ctx, req.(*Request))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
var _DGraph_serviceDesc = grpc.ServiceDesc{ var _DGraph_serviceDesc = grpc.ServiceDesc{
ServiceName: "pb.DGraph", ServiceName: "graph.DGraph",
HandlerType: (*DGraphServer)(nil), HandlerType: (*DGraphServer)(nil),
Methods: []grpc.MethodDesc{ Methods: []grpc.MethodDesc{
{ {
...@@ -154,21 +155,22 @@ var _DGraph_serviceDesc = grpc.ServiceDesc{ ...@@ -154,21 +155,22 @@ var _DGraph_serviceDesc = grpc.ServiceDesc{
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 253 bytes of a gzipped FileDescriptorProto // 266 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x90, 0x31, 0x4f, 0xc3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x90, 0x41, 0x4b, 0xc3, 0x40,
0x10, 0x85, 0x71, 0x42, 0x22, 0x72, 0x2d, 0x52, 0x39, 0x18, 0xa2, 0x02, 0xa2, 0x8a, 0x18, 0xba, 0x10, 0x85, 0x4d, 0x93, 0x8d, 0x76, 0x52, 0x54, 0x46, 0x91, 0x50, 0x05, 0x4b, 0x0e, 0xda, 0x53,
0xe0, 0xa1, 0x08, 0xa9, 0x62, 0x2e, 0x62, 0xc6, 0x03, 0x7b, 0x0c, 0x27, 0x5a, 0x51, 0x25, 0xc6, 0x90, 0x78, 0x11, 0xbd, 0x2a, 0x1e, 0x04, 0xd1, 0x3d, 0x78, 0x4f, 0xcc, 0x60, 0x17, 0x4b, 0x12,
0x76, 0x90, 0xf2, 0x53, 0xf9, 0x37, 0xc4, 0x97, 0x00, 0x45, 0xdd, 0xce, 0x77, 0xf7, 0xbe, 0x77, 0x37, 0x1b, 0xa1, 0x3f, 0xd9, 0x7f, 0x61, 0x76, 0xba, 0xd6, 0xd0, 0xdb, 0xcc, 0x7c, 0x33, 0x8f,
0x7e, 0x70, 0xfa, 0x66, 0x4b, 0xb3, 0xb6, 0xe4, 0x4c, 0x5d, 0x39, 0x92, 0xc6, 0xd6, 0xbe, 0xc6, 0x37, 0x0f, 0x8e, 0x3e, 0x74, 0xde, 0x2c, 0x34, 0xb5, 0x4d, 0x5d, 0xb5, 0x94, 0x36, 0xba, 0x36,
0xc8, 0xe8, 0xe2, 0x1a, 0xc6, 0x8f, 0x61, 0xa4, 0xe8, 0xa3, 0x21, 0xe7, 0xf1, 0x0c, 0x92, 0xae, 0x35, 0x0a, 0x1e, 0x26, 0xe7, 0xb0, 0x2b, 0xe9, 0xab, 0xa3, 0xd6, 0xe0, 0x31, 0x88, 0xbe, 0xd0,
0xb0, 0x6d, 0x2e, 0x66, 0x62, 0x9e, 0xa9, 0xfe, 0x51, 0x9c, 0x43, 0xf2, 0x5c, 0x6e, 0x1b, 0x42, 0xab, 0xd8, 0x9b, 0x79, 0xf3, 0xb1, 0x5c, 0x37, 0xfd, 0x82, 0x78, 0xcb, 0x97, 0x1d, 0xe1, 0x09,
0x84, 0x43, 0xdd, 0x7a, 0xe2, 0xe9, 0x58, 0x71, 0x5d, 0x7c, 0x09, 0x38, 0x1e, 0x18, 0x3d, 0x1e, 0x84, 0x85, 0xaa, 0x72, 0xc7, 0x27, 0xd2, 0x75, 0xc9, 0x8f, 0x07, 0xc1, 0x73, 0x5d, 0x12, 0x1e,
0x2f, 0x20, 0x2b, 0xbd, 0xb7, 0x1b, 0xdd, 0x0c, 0xab, 0x99, 0xfa, 0x6b, 0xe0, 0x1d, 0xa4, 0x9f, 0x82, 0xdf, 0xa9, 0x92, 0x69, 0x20, 0x6d, 0x89, 0x67, 0x30, 0xce, 0x8d, 0xd1, 0xaa, 0xe8, 0x0c,
0x01, 0xe6, 0xf2, 0x68, 0x16, 0xcf, 0x47, 0x8b, 0x4b, 0x69, 0xb4, 0xfc, 0x07, 0x90, 0x6c, 0xe6, 0xc5, 0x23, 0x56, 0xfd, 0x1f, 0xe0, 0x1d, 0x40, 0x6f, 0xa5, 0x21, 0x6d, 0x14, 0xb5, 0xb1, 0x3f,
0x1e, 0x2a, 0x6f, 0x5b, 0x35, 0x2c, 0xe3, 0x0d, 0x1c, 0xbd, 0xac, 0x37, 0xdb, 0x57, 0x4b, 0x55, 0xf3, 0xe7, 0x51, 0x76, 0x9a, 0xb2, 0xad, 0xd4, 0x0a, 0xa6, 0x2f, 0x1b, 0xfa, 0x50, 0x19, 0xbd,
0x1e, 0xb3, 0xf0, 0x64, 0x4f, 0xa8, 0x7e, 0x57, 0xa6, 0x2b, 0x18, 0xed, 0x50, 0x70, 0x02, 0xf1, 0x92, 0x83, 0x75, 0xbc, 0x84, 0xbd, 0xf7, 0x85, 0x5a, 0x96, 0x9a, 0xaa, 0x38, 0xe0, 0xd3, 0x68,
0x3b, 0xfd, 0xfc, 0x2a, 0x94, 0x78, 0x05, 0x09, 0x93, 0xbb, 0x2b, 0x44, 0x07, 0xcb, 0x02, 0x8c, 0x70, 0x2a, 0x37, 0x70, 0xfa, 0x04, 0x07, 0x5b, 0x3a, 0xd6, 0xe8, 0x27, 0xfd, 0xbd, 0x69, 0x4b,
0x15, 0xaa, 0xef, 0xdf, 0x47, 0x4b, 0xb1, 0x58, 0x42, 0xba, 0x62, 0x07, 0x94, 0x90, 0x3c, 0x85, 0x4c, 0x40, 0x7c, 0xdb, 0x27, 0xd9, 0x64, 0x94, 0x4d, 0x9c, 0x14, 0x3f, 0x2e, 0xd7, 0xe8, 0x76,
0x2c, 0x70, 0xb2, 0xe3, 0xca, 0x99, 0x4d, 0xf7, 0xef, 0x28, 0x0e, 0x74, 0xca, 0x19, 0xdf, 0x7e, 0x74, 0xe3, 0x65, 0x57, 0x10, 0xde, 0x3f, 0x5a, 0x84, 0x17, 0x20, 0x5e, 0x6d, 0x3e, 0xb8, 0xef,
0x07, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x05, 0xc8, 0x3f, 0x7a, 0x01, 0x00, 0x00, 0x76, 0x5d, 0x8a, 0xd3, 0xa1, 0x8d, 0x64, 0xa7, 0x08, 0x39, 0xed, 0xeb, 0xdf, 0x00, 0x00, 0x00,
0xff, 0xff, 0x2c, 0xc9, 0x79, 0xe9, 0x84, 0x01, 0x00, 0x00,
} }
// To compile this file run the command below from inside the graph directory
// protoc --go_out=plugins=grpc:. *.proto
syntax="proto3";
package graph;
service DGraph {
rpc Query (Request) returns (Node) {}
}
message Request {
string query = 1;
}
message Value {
bytes binary = 1;
}
message Node {
uint64 uid = 1;
string attribute = 2;
map<string, Value> properties = 3;
repeated Node children = 4; // Each node can have multiple children
}
// To compile this file run the command below from inside the pb directory
// protoc --go_out=plugins=grpc:. *.proto
syntax="proto3";
package pb;
service DGraph {
rpc Query (GraphRequest) returns (GraphResponse) {}
}
message GraphRequest {
string query = 1;
}
message Value {
bytes byte = 1;
}
message GraphResponse {
string attribute = 1;
map<string, Value> values = 2;
repeated GraphResponse children = 3; // Each node can have multiple children
}
...@@ -26,7 +26,7 @@ import ( ...@@ -26,7 +26,7 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/dgraph-io/dgraph/gql" "github.com/dgraph-io/dgraph/gql"
"github.com/dgraph-io/dgraph/posting" "github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/query/pb" "github.com/dgraph-io/dgraph/query/graph"
"github.com/dgraph-io/dgraph/task" "github.com/dgraph-io/dgraph/task"
"github.com/dgraph-io/dgraph/worker" "github.com/dgraph-io/dgraph/worker"
"github.com/dgraph-io/dgraph/x" "github.com/dgraph-io/dgraph/x"
...@@ -253,111 +253,15 @@ func (g *SubGraph) ToJson(l *Latency) (js []byte, rerr error) { ...@@ -253,111 +253,15 @@ func (g *SubGraph) ToJson(l *Latency) (js []byte, rerr error) {
return json.Marshal(r) return json.Marshal(r)
} }
// Struct to retrieve values from flatbuffers, so that they can later be used
// to control the entity based protocol buffer subgraph.
type result struct {
values [][]byte
uidmatrix [][]uint64
}
// This method takes in a flatbuffer query and result extracts values.
func extract(q *task.Query, r *task.Result) ([]uint64, *result, error) {
re := new(result)
var qu []uint64
var ul task.UidList
for i := 0; i < q.UidsLength(); i++ {
uid := q.Uids(i)
qu = append(qu, uid)
}
for i := 0; i < r.UidmatrixLength(); i++ {
if ok := r.Uidmatrix(&ul, i); !ok {
return qu, re, fmt.Errorf("While parsing UidList")
}
var uidList []uint64
for j := 0; j < ul.UidsLength(); j++ {
uid := ul.Uids(j)
uidList = append(uidList, uid)
}
re.uidmatrix = append(re.uidmatrix, uidList)
}
var tv task.Value
for i := 0; i < r.ValuesLength(); i++ {
if ok := r.Values(&tv, i); !ok {
return qu, re, fmt.Errorf("While parsing value")
}
var ival interface{}
if err := posting.ParseValue(&ival, tv.ValBytes()); err != nil {
return qu, re, err
}
if ival == nil {
ival = ""
}
re.values = append(re.values, []byte(ival.(string)))
}
return qu, re, nil
}
// Struct to store reference to the subgraph associated with a protocol buffer
// graph response
type sgReference struct {
uid uint64
sg *SubGraph
}
// This method converts a subgraph to a protocol buffer response. It transforms
// the predicate based subgraph to an entity based protocol buffer subgraph.
func (g *SubGraph) ToProtocolBuffer(l *Latency) (gr *pb.GraphResponse,
rerr error) {
gr = &pb.GraphResponse{}
gr.Attribute = g.Attr
if len(g.query) == 0 {
return gr, nil
}
ro := flatbuffers.GetUOffsetT(g.result)
r := new(task.Result)
r.Init(g.result, ro)
uo := flatbuffers.GetUOffsetT(g.query)
q := new(task.Query)
q.Init(g.query, uo)
_, result, err := extract(q, r)
if err != nil {
x.Err(glog, err).Error("Error while extracting query, result")
return gr, err
}
re := &sgReference{}
// Storing reference to root node.
re.sg = g
// Stores the uid for the root node in the reference struct.
re.uid = result.uidmatrix[0][0]
gr.Values, gr.Children, rerr = re.preTraverse()
if rerr != nil {
x.Err(glog, rerr).Error("Error while traversal")
return gr, rerr
}
l.ProtocolBuffer = time.Since(l.Start) - l.Parsing - l.Processing
return gr, nil
}
// This function performs a binary search on the uids slice and returns the // This function performs a binary search on the uids slice and returns the
// index at which it finds the uid, else returns -1 // index at which it finds the uid, else returns -1
func indexOf(uid uint64, uids []uint64) int { func indexOf(uid uint64, q *task.Query) int {
low, mid, high := 0, 0, len(uids)-1 low, mid, high := 0, 0, q.UidsLength()-1
for low <= high { for low <= high {
mid = (low + high) / 2 mid = (low + high) / 2
if uids[mid] == uid { if q.Uids(mid) == uid {
return mid return mid
} else if uids[mid] > uid { } else if q.Uids(mid) > uid {
high = mid - 1 high = mid - 1
} else { } else {
low = mid + 1 low = mid + 1
...@@ -366,67 +270,104 @@ func indexOf(uid uint64, uids []uint64) int { ...@@ -366,67 +270,104 @@ func indexOf(uid uint64, uids []uint64) int {
return -1 return -1
} }
// This method gets the values and children for a GraphResponse. // This method gets the values and children for a subgraph.
func (re *sgReference) preTraverse() (map[string]*pb.Value, func preTraverse(uid uint64, g *SubGraph) (map[string]*graph.Value, []*graph.Node, error) {
[]*pb.GraphResponse, error) { values := make(map[string]*graph.Value)
values := make(map[string]*pb.Value) var children []*graph.Node
var children []*pb.GraphResponse
for _, child := range re.sg.Children { for _, predChild := range g.Children {
ro := flatbuffers.GetUOffsetT(child.result) ro := flatbuffers.GetUOffsetT(predChild.result)
r := new(task.Result) r := new(task.Result)
r.Init(child.result, ro) r.Init(predChild.result, ro)
uo := flatbuffers.GetUOffsetT(child.query) uo := flatbuffers.GetUOffsetT(predChild.query)
q := new(task.Query) q := new(task.Query)
q.Init(child.query, uo) q.Init(predChild.query, uo)
query, result, err := extract(q, r) idx := indexOf(uid, q)
if err != nil {
x.Err(glog, err).Error("Error while extracting query, result")
return values, children, fmt.Errorf("While extracting query, result")
}
idx := indexOf(re.uid, query)
if idx == -1 { if idx == -1 {
glog.WithFields(logrus.Fields{ glog.WithFields(logrus.Fields{
"uid": re.uid, "uid": uid,
"attribute": re.sg.Attr, "attribute": g.Attr,
"childAttribute": child.Attr, "childAttribute": predChild.Attr,
}).Fatal("Attribute with uid not found in child Query uids") }).Fatal("Attribute with uid not found in child Query uids")
return values, children, fmt.Errorf("Attribute with uid not found") return values, children, fmt.Errorf("Attribute with uid not found")
} }
// This means the child is a leaf node hence we just extract its value. var ul task.UidList
if len(child.Children) == 0 { var tv task.Value
v := new(pb.Value) if ok := r.Uidmatrix(&ul, idx); !ok {
v.Byte = result.values[idx] return values, children, fmt.Errorf("While parsing UidList")
values[child.Attr] = v }
} else {
uids := result.uidmatrix[idx]
// We create as many predicate children as the number of uids.
for _, uid := range uids {
predChild := new(pb.GraphResponse)
predChild.Attribute = child.Attr
ref := new(sgReference) if ul.UidsLength() > 0 {
ref.sg = child // We create as many predicate entity children as the length of uids for
ref.uid = uid // this predicate.
for i := 0; i < ul.UidsLength(); i++ {
uid := ul.Uids(i)
uidChild := new(graph.Node)
uidChild.Attribute = predChild.Attr
uidChild.Uid = uid
vals, ch, rerr := ref.preTraverse() vals, ch, rerr := preTraverse(uid, predChild)
if rerr != nil { if rerr != nil {
x.Err(glog, rerr).Error("Error while traversal") x.Err(glog, rerr).Error("Error while traversal")
return values, children, rerr return values, children, rerr
} }
predChild.Values, predChild.Children = vals, ch uidChild.Properties, uidChild.Children = vals, ch
children = append(children, predChild) children = append(children, uidChild)
}
} else {
v := new(graph.Value)
if ok := r.Values(&tv, idx); !ok {
return values, children, fmt.Errorf("While parsing value")
}
var ival interface{}
if err := posting.ParseValue(&ival, tv.ValBytes()); err != nil {
return values, children, err
} }
if ival == nil {
ival = ""
}
v.Binary = []byte(ival.(string))
values[predChild.Attr] = v
} }
} }
return values, children, nil return values, children, nil
} }
// This method transforms the predicate based subgraph to an
// predicate-entity based protocol buffer subgraph.
func (g *SubGraph) ToProtocolBuffer(l *Latency) (n *graph.Node, rerr error) {
n = &graph.Node{}
n.Attribute = g.Attr
if len(g.query) == 0 {
return n, nil
}
ro := flatbuffers.GetUOffsetT(g.result)
r := new(task.Result)
r.Init(g.result, ro)
var ul task.UidList
r.Uidmatrix(&ul, 0)
n.Uid = ul.Uids(0)
n.Properties, n.Children, rerr = preTraverse(n.Uid, g)
if rerr != nil {
x.Err(glog, rerr).Error("Error while traversal")
return n, rerr
}
l.ProtocolBuffer = time.Since(l.Start) - l.Parsing - l.Processing
return n, nil
}
func treeCopy(gq *gql.GraphQuery, sg *SubGraph) { func treeCopy(gq *gql.GraphQuery, sg *SubGraph) {
for _, gchild := range gq.Children { for _, gchild := range gq.Children {
dst := new(SubGraph) dst := new(SubGraph)
......
...@@ -333,6 +333,8 @@ func TestToProtocolBuffer(t *testing.T) { ...@@ -333,6 +333,8 @@ func TestToProtocolBuffer(t *testing.T) {
friend { friend {
name name
} }
friend {
}
} }
} }
` `
...@@ -362,29 +364,50 @@ func TestToProtocolBuffer(t *testing.T) { ...@@ -362,29 +364,50 @@ func TestToProtocolBuffer(t *testing.T) {
if gr.Attribute != "_root_" { if gr.Attribute != "_root_" {
t.Errorf("Expected attribute _root_, Got: %v", gr.Attribute) t.Errorf("Expected attribute _root_, Got: %v", gr.Attribute)
} }
if len(gr.Values) != 3 { if gr.Uid != 1 {
t.Errorf("Expected uid 1, Got: %v", gr.Uid)
}
if len(gr.Properties) != 3 {
t.Errorf("Expected values map to contain 3 properties, Got: %v", t.Errorf("Expected values map to contain 3 properties, Got: %v",
len(gr.Values)) len(gr.Properties))
} }
if string(gr.Values["name"].Byte) != "Michonne" { if string(gr.Properties["name"].Binary) != "Michonne" {
t.Errorf("Expected property name to have value Michonne, Got: %v", t.Errorf("Expected property name to have value Michonne, Got: %v",
string(gr.Values["name"].Byte)) string(gr.Properties["name"].Binary))
} }
if len(gr.Children) != 5 { if len(gr.Children) != 10 {
t.Errorf("Expected 5 children, Got: %v", len(gr.Children)) t.Errorf("Expected 10 children, Got: %v", len(gr.Children))
} }
child := gr.Children[0] child := gr.Children[0]
if child.Uid != 23 {
t.Errorf("Expected uid 23, Got: %v", gr.Uid)
}
if child.Attribute != "friend" { if child.Attribute != "friend" {
t.Errorf("Expected attribute friend, Got: %v", child.Attribute) t.Errorf("Expected attribute friend, Got: %v", child.Attribute)
} }
if len(child.Values) != 1 { if len(child.Properties) != 1 {
t.Errorf("Expected values map to contain 1 property, Got: %v", t.Errorf("Expected values map to contain 1 property, Got: %v",
len(child.Values)) len(child.Properties))
} }
if string(child.Values["name"].Byte) != "Rick Grimes" { if string(child.Properties["name"].Binary) != "Rick Grimes" {
t.Errorf("Expected property name to have value Rick Grimes, Got: %v", t.Errorf("Expected property name to have value Rick Grimes, Got: %v",
string(child.Values["name"].Byte)) string(child.Properties["name"].Binary))
}
if len(child.Children) != 0 {
t.Errorf("Expected 0 children, Got: %v", len(child.Children))
}
child = gr.Children[5]
if child.Uid != 23 {
t.Errorf("Expected uid 23, Got: %v", gr.Uid)
}
if child.Attribute != "friend" {
t.Errorf("Expected attribute friend, Got: %v", child.Attribute)
}
if len(child.Properties) != 0 {
t.Errorf("Expected values map to contain 0 properties, Got: %v",
len(child.Properties))
} }
if len(child.Children) != 0 { if len(child.Children) != 0 {
t.Errorf("Expected 0 children, Got: %v", len(child.Children)) t.Errorf("Expected 0 children, Got: %v", len(child.Children))
......
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
"github.com/dgraph-io/dgraph/gql" "github.com/dgraph-io/dgraph/gql"
"github.com/dgraph-io/dgraph/posting" "github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/query" "github.com/dgraph-io/dgraph/query"
"github.com/dgraph-io/dgraph/query/pb" "github.com/dgraph-io/dgraph/query/graph"
"github.com/dgraph-io/dgraph/rdf" "github.com/dgraph-io/dgraph/rdf"
"github.com/dgraph-io/dgraph/store" "github.com/dgraph-io/dgraph/store"
"github.com/dgraph-io/dgraph/uid" "github.com/dgraph-io/dgraph/uid"
...@@ -203,14 +203,14 @@ func queryHandler(w http.ResponseWriter, r *http.Request) { ...@@ -203,14 +203,14 @@ func queryHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, string(js)) fmt.Fprint(w, string(js))
} }
// server is used to implement pb.DGraphServer // server is used to implement graph.DGraphServer
type server struct{} type server struct{}
// This method is used to execute the query and return the response to the // This method is used to execute the query and return the response to the
// client as a protocol buffer message. // client as a protocol buffer message.
func (s *server) Query(ctx context.Context, func (s *server) Query(ctx context.Context,
req *pb.GraphRequest) (*pb.GraphResponse, error) { req *graph.Request) (*graph.Node, error) {
resp := new(pb.GraphResponse) resp := new(graph.Node)
if len(req.Query) == 0 { if len(req.Query) == 0 {
glog.Error("While reading query") glog.Error("While reading query")
return resp, fmt.Errorf("Empty query") return resp, fmt.Errorf("Empty query")
...@@ -265,7 +265,7 @@ func runGrpcServer(address string) error { ...@@ -265,7 +265,7 @@ func runGrpcServer(address string) error {
glog.WithField("address", ln.Addr()).Info("Client Worker listening") glog.WithField("address", ln.Addr()).Info("Client Worker listening")
s := grpc.NewServer() s := grpc.NewServer()
pb.RegisterDGraphServer(s, &server{}) graph.RegisterDGraphServer(s, &server{})
if err = s.Serve(ln); err != nil { if err = s.Serve(ln); err != nil {
glog.Fatalf("While serving gRpc requests", err) glog.Fatalf("While serving gRpc requests", err)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment