@@ -40,8 +40,41 @@ type Diff struct {
40
40
Text string
41
41
}
42
42
43
+ // splice removes amount elements from slice at index index, replacing them with elements.
43
44
func splice (slice []Diff , index int , amount int , elements ... Diff ) []Diff {
44
- return append (slice [:index ], append (elements , slice [index + amount :]... )... )
45
+ if len (elements ) == amount {
46
+ // Easy case: overwrite the relevant items.
47
+ copy (slice [index :], elements )
48
+ return slice
49
+ }
50
+ if len (elements ) < amount {
51
+ // Fewer new items than old.
52
+ // Copy in the new items.
53
+ copy (slice [index :], elements )
54
+ // Shift the remaining items left.
55
+ copy (slice [index + len (elements ):], slice [index + amount :])
56
+ // Calculate the new end of the slice.
57
+ end := len (slice ) - amount + len (elements )
58
+ // Zero stranded elements at end so that they can be garbage collected.
59
+ tail := slice [end :]
60
+ for i := range tail {
61
+ tail [i ] = Diff {}
62
+ }
63
+ return slice [:end ]
64
+ }
65
+ // More new items than old.
66
+ // Make room in slice for new elements.
67
+ // There's probably an even more efficient way to do this,
68
+ // but this is simple and clear.
69
+ need := len (slice ) - amount + len (elements )
70
+ for len (slice ) < need {
71
+ slice = append (slice , Diff {})
72
+ }
73
+ // Shift slice elements right to make room for new elements.
74
+ copy (slice [index + len (elements ):], slice [index + amount :])
75
+ // Copy in new elements.
76
+ copy (slice [index :], elements )
77
+ return slice
45
78
}
46
79
47
80
// DiffMain finds the differences between two texts.
0 commit comments