func sortInfos(infos []*xpb.NodeInfo) []*xpb.NodeInfo { sort.Sort(sortedNodeInfos(infos)) for _, info := range infos { sort.Sort(xrefs.ByName(info.Fact)) } return infos }
func nodeInfo(n *srvpb.Node) *xpb.NodeInfo { ni := &xpb.NodeInfo{Ticket: n.Ticket} for _, f := range n.Fact { ni.Fact = append(ni.Fact, &cpb.Fact{Name: f.Name, Value: f.Value}) } sort.Sort(xrefs.ByName(ni.Fact)) return ni }
func nodeToInfo(patterns []*regexp.Regexp, n *srvpb.Node) *xpb.NodeInfo { ni := &xpb.NodeInfo{Ticket: n.Ticket} for _, f := range n.Fact { if xrefs.MatchesAny(f.Name, patterns) { ni.Fact = append(ni.Fact, &xpb.Fact{Name: f.Name, Value: f.Value}) } } sort.Sort(xrefs.ByName(ni.Fact)) return ni }
// Node returns the Source as a srvpb.Node. func (s *Source) Node() *srvpb.Node { facts := make([]*cpb.Fact, 0, len(s.Facts)) for name, value := range s.Facts { facts = append(facts, &cpb.Fact{Name: name, Value: value}) } sort.Sort(xrefs.ByName(facts)) return &srvpb.Node{ Ticket: s.Ticket, Fact: facts, } }
// OriginalNode returns the given node's original serving node, synthesizing one // if necessary. func OriginalNode(n *ipb.Path_Node) (g *srvpb.Node) { defer func() { // Ensure serving data is consistent sort.Sort(xrefs.ByName(g.Fact)) }() if n.Original != nil { return n.Original } // Synthesize node without original log.Printf("WARNING: synthesizing node for %q", n.Ticket) sn := &srvpb.Node{ Ticket: n.Ticket, Fact: []*cpb.Fact{ {Name: facts.NodeKind, Value: []byte(n.NodeKind)}, }, } if a := n.GetRawAnchor(); a != nil { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.AnchorStart, Value: []byte(strconv.FormatInt(int64(a.StartOffset), 10))}, &cpb.Fact{Name: facts.AnchorEnd, Value: []byte(strconv.FormatInt(int64(a.EndOffset), 10))}, ) if a.SnippetStart != 0 || a.SnippetEnd != 0 { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.SnippetStart, Value: []byte(strconv.FormatInt(int64(a.SnippetStart), 10))}, &cpb.Fact{Name: facts.SnippetEnd, Value: []byte(strconv.FormatInt(int64(a.SnippetEnd), 10))}, ) } } else if a := n.GetExpandedAnchor(); a != nil { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.AnchorStart, Value: []byte(strconv.FormatInt(int64(a.Span.Start.ByteOffset), 10))}, &cpb.Fact{Name: facts.AnchorEnd, Value: []byte(strconv.FormatInt(int64(a.Span.End.ByteOffset), 10))}, ) if a.SnippetSpan.Start.ByteOffset != 0 || a.SnippetSpan.End.ByteOffset != 0 { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.SnippetStart, Value: []byte(strconv.FormatInt(int64(a.SnippetSpan.Start.ByteOffset), 10))}, &cpb.Fact{Name: facts.SnippetEnd, Value: []byte(strconv.FormatInt(int64(a.SnippetSpan.End.ByteOffset), 10))}, ) } } else if f := n.GetFile(); f != nil { if len(f.Text) > 0 { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.Text, Value: f.Text}) } if f.Encoding != "" { sn.Fact = append(sn.Fact, &cpb.Fact{Name: facts.TextEncoding, Value: []byte(f.Encoding)}) } } return sn }
// Nodes implements part of the xrefs Service interface. func (t *tableImpl) Nodes(ctx context.Context, req *xpb.NodesRequest) (*xpb.NodesReply, error) { tickets, err := fixTickets(req.Ticket) if err != nil { return nil, err } rs, err := t.pagedEdgeSets(ctx, tickets) if err != nil { return nil, err } defer func() { // drain channel in case of errors for _ = range rs { } }() reply := &xpb.NodesReply{} patterns := xrefs.ConvertFilters(req.Filter) for r := range rs { if r.Err == table.ErrNoSuchKey { continue } else if r.Err != nil { return nil, r.Err } node := r.PagedEdgeSet.EdgeSet.Source ni := &xpb.NodeInfo{Ticket: node.Ticket} for _, f := range node.Fact { if len(patterns) == 0 || xrefs.MatchesAny(f.Name, patterns) { ni.Fact = append(ni.Fact, &xpb.Fact{Name: f.Name, Value: f.Value}) } } if len(ni.Fact) > 0 { sort.Sort(xrefs.ByName(ni.Fact)) reply.Node = append(reply.Node, ni) } } return reply, nil }