1package graphlog 2 3import ( 4 "bytes" 5 "sort" 6 7 "github.com/cayleygraph/cayley/graph" 8 "github.com/cayleygraph/cayley/quad" 9) 10 11type Op interface { 12 isOp() 13} 14 15var ( 16 _ Op = NodeUpdate{} 17 _ Op = QuadUpdate{} 18) 19 20type NodeUpdate struct { 21 Hash graph.ValueHash 22 Val quad.Value 23 RefInc int 24} 25 26func (NodeUpdate) isOp() {} 27 28type QuadUpdate struct { 29 Ind int 30 Quad graph.QuadHash 31 Del bool 32} 33 34func (QuadUpdate) isOp() {} 35 36type Deltas struct { 37 IncNode []NodeUpdate 38 DecNode []NodeUpdate 39 QuadAdd []QuadUpdate 40 QuadDel []QuadUpdate 41} 42 43func SplitDeltas(in []graph.Delta) *Deltas { 44 hnodes := make(map[graph.ValueHash]*NodeUpdate, len(in)*2) 45 quadAdd := make([]QuadUpdate, 0, len(in)) 46 quadDel := make([]QuadUpdate, 0, len(in)/2) 47 var nadd, ndel int 48 for i, d := range in { 49 dn := 0 50 switch d.Action { 51 case graph.Add: 52 dn = +1 53 nadd++ 54 case graph.Delete: 55 dn = -1 56 ndel++ 57 default: 58 panic("unknown action") 59 } 60 var q graph.QuadHash 61 for _, dir := range quad.Directions { 62 v := d.Quad.Get(dir) 63 if v == nil { 64 continue 65 } 66 h := graph.HashOf(v) 67 q.Set(dir, h) 68 n := hnodes[h] 69 if n == nil { 70 n = &NodeUpdate{Hash: h, Val: v} 71 hnodes[h] = n 72 } 73 n.RefInc += dn 74 } 75 u := QuadUpdate{Ind: i, Quad: q, Del: d.Action == graph.Delete} 76 if !u.Del { 77 quadAdd = append(quadAdd, u) 78 } else { 79 quadDel = append(quadDel, u) 80 } 81 } 82 incNodes := make([]NodeUpdate, 0, nadd) 83 decNodes := make([]NodeUpdate, 0, ndel) 84 for _, n := range hnodes { 85 if n.RefInc >= 0 { 86 incNodes = append(incNodes, *n) 87 } else { 88 decNodes = append(decNodes, *n) 89 } 90 } 91 sort.Slice(incNodes, func(i, j int) bool { 92 return bytes.Compare(incNodes[i].Hash[:], incNodes[j].Hash[:]) < 0 93 }) 94 sort.Slice(decNodes, func(i, j int) bool { 95 return bytes.Compare(decNodes[i].Hash[:], decNodes[j].Hash[:]) < 0 96 }) 97 hnodes = nil 98 return &Deltas{ 99 IncNode: incNodes, DecNode: decNodes, 100 QuadAdd: quadAdd, QuadDel: quadDel, 101 } 102} 103