MCPcopy Create free account
hub / github.com/dgraph-io/dgraph / runMutation

Function runMutation

worker/mutation.go:59–120  ·  view source on GitHub ↗

runMutation goes through all the edges and applies them.

(ctx context.Context, edge *pb.DirectedEdge, txn *posting.Txn)

Source from the content-addressed store, hash-verified

57
58// runMutation goes through all the edges and applies them.
59func runMutation(ctx context.Context, edge *pb.DirectedEdge, txn *posting.Txn) error {
60 ctx = schema.GetWriteContext(ctx)
61
62 // We shouldn't check whether this Alpha serves this predicate or not. Membership information
63 // isn't consistent across the entire cluster. We should just apply whatever is given to us.
64 su, ok := schema.State().Get(ctx, edge.Attr)
65 if edge.Op != pb.DirectedEdge_DEL {
66 if !ok {
67 return errors.Errorf("runMutation: Unable to find schema for %s", edge.Attr)
68 }
69 }
70
71 if isDeletePredicateEdge(edge) {
72 return errors.New("We should never reach here")
73 }
74
75 // Once mutation comes via raft we do best effort conversion
76 // Type check is done before proposing mutation, in case schema is not
77 // present, some invalid entries might be written initially
78 if err := ValidateAndConvert(edge, &su); err != nil {
79 return err
80 }
81
82 key := x.DataKey(edge.Attr, edge.Entity)
83 // The following is a performance optimization which allows us to not read a posting list from
84 // disk. We calculate this based on how AddMutationWithIndex works. The general idea is that if
85 // we're not using the read posting list, we don't need to retrieve it. We need the posting list
86 // if we're doing count index or delete operation. For scalar predicates, we just get the last item merged.
87 // In other cases, we can just create a posting list facade in memory and use it to store the delta in Badger.
88 // Later, the rollup operation would consolidate all these deltas into a posting list.
89 isList := su.GetList()
90 var getFn func(key []byte) (*posting.List, error)
91 switch {
92 case len(edge.Lang) == 0 && !isList:
93 // Scalar Predicates, without lang
94 getFn = txn.GetScalarList
95 case len(edge.Lang) > 0 || su.GetCount():
96 // Language or Count Index
97 getFn = txn.Get
98 case edge.Op == pb.DirectedEdge_DEL:
99 // Covers various delete cases to keep things simple.
100 getFn = txn.Get
101 default:
102 // Only count index needs to be read. For other indexes on list, we don't need to read any data.
103 // For indexes on scalar prediactes, only the last element needs to be left.
104 // Delete cases covered above.
105 getFn = txn.GetFromDelta
106 }
107
108 t := time.Now()
109 plist, err := getFn(key)
110 if dur := time.Since(t); dur > time.Millisecond {
111 span := trace.SpanFromContext(ctx)
112 span.AddEvent("Slow GetLru", trace.WithAttributes(
113 attribute.Bool("slow-get", true),
114 attribute.String("duration", dur.String())))
115 }
116 if err != nil {

Callers 13

TestGetScalarListFunction · 0.70
TestMultipleTxnListCountFunction · 0.70
TestScalarPredicateCountFunction · 0.70
TestSingleUidReplacementFunction · 0.70
TestSingleStringFunction · 0.70
TestLangExactFunction · 0.70
TestReverseEdgeFunction · 0.70
TestReverseEdgeSetDelFunction · 0.70

Calls 11

GetWriteContextFunction · 0.92
StateFunction · 0.92
DataKeyFunction · 0.92
isDeletePredicateEdgeFunction · 0.85
ValidateAndConvertFunction · 0.85
AddMutationWithIndexMethod · 0.80
GetMethod · 0.65
ErrorfMethod · 0.45
GetListMethod · 0.45
GetCountMethod · 0.45
StringMethod · 0.45

Tested by 12

TestGetScalarListFunction · 0.56
TestMultipleTxnListCountFunction · 0.56
TestScalarPredicateCountFunction · 0.56
TestSingleUidReplacementFunction · 0.56
TestSingleStringFunction · 0.56
TestLangExactFunction · 0.56
TestReverseEdgeFunction · 0.56
TestReverseEdgeSetDelFunction · 0.56

Used in the wild real call sites across dependent graphs

searching dependent graphs…