/
delta.go
95 lines (79 loc) · 1.7 KB
/
delta.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package render
import (
"reflect"
)
// DeltaRow represents a collection of row deltas between old and new row.
type DeltaRow []string
// NewDeltaRow computes the delta between 2 rows.
func NewDeltaRow(o, n Row, h Header) DeltaRow {
deltas := make(DeltaRow, len(o.Fields))
for i, old := range o.Fields {
if old != "" && old != n.Fields[i] && !h.IsTimeCol(i) {
deltas[i] = old
}
}
return deltas
}
// Labelize returns a new deltaRow based on labels.
func (d DeltaRow) Labelize(cols []int, labelCol int) DeltaRow {
if len(d) == 0 {
return d
}
_, vals := sortLabels(labelize(d[labelCol]))
out := make(DeltaRow, 0, len(cols)+len(vals))
for _, i := range cols {
out = append(out, d[i])
}
for _, v := range vals {
out = append(out, v)
}
return out
}
// Diff returns true if deltas differ or false otherwise.
func (d DeltaRow) Diff(r DeltaRow, ageCol int) bool {
if len(d) != len(r) {
return true
}
if ageCol < 0 || ageCol >= len(d) {
return !reflect.DeepEqual(d, r)
}
if !reflect.DeepEqual(d[:ageCol], r[:ageCol]) {
return true
}
if ageCol+1 >= len(d) {
return false
}
return !reflect.DeepEqual(d[ageCol+1:], r[ageCol+1:])
}
// Customize returns a subset of deltas.
func (d DeltaRow) Customize(cols []int, out DeltaRow) {
if d.IsBlank() {
return
}
for i, c := range cols {
if c < 0 {
continue
}
if c < len(d) && i < len(out) {
out[i] = d[c]
}
}
}
// IsBlank asserts a row has no values in it.
func (d DeltaRow) IsBlank() bool {
if len(d) == 0 {
return true
}
for _, v := range d {
if v != "" {
return false
}
}
return true
}
// Clone returns a delta copy.
func (d DeltaRow) Clone() DeltaRow {
res := make(DeltaRow, len(d))
copy(res, d)
return res
}