diff --git a/pruning/keep_grid.go b/pruning/keep_grid.go index a62c9c9..2dffc07 100644 --- a/pruning/keep_grid.go +++ b/pruning/keep_grid.go @@ -99,17 +99,21 @@ func (a retentionGridAdaptor) LessThan(b retentiongrid.Entry) bool { // Prune filters snapshots with the retention grid. func (p *KeepGrid) KeepRule(snaps []Snapshot) (destroyList []Snapshot) { - snaps = filterSnapList(snaps, func(snapshot Snapshot) bool { + matching, notMatching := partitionSnapList(snaps, func(snapshot Snapshot) bool { return p.re.MatchString(snapshot.Name()) }) - if len(snaps) == 0 { - return nil + + // snaps that don't match the regex are not kept by this rule + destroyList = append(destroyList, notMatching...) + + if len(matching) == 0 { + return destroyList } // Build adaptors for retention grid adaptors := make([]retentiongrid.Entry, 0) - for i := range snaps { - adaptors = append(adaptors, retentionGridAdaptor{snaps[i]}) + for i := range matching { + adaptors = append(adaptors, retentionGridAdaptor{matching[i]}) } // determine 'now' edge @@ -122,9 +126,8 @@ func (p *KeepGrid) KeepRule(snaps []Snapshot) (destroyList []Snapshot) { _, removea := p.retentionGrid.FitEntries(now, adaptors) // Revert adaptors - destroyList = make([]Snapshot, len(removea)) for i := range removea { - destroyList[i] = removea[i].(retentionGridAdaptor).Snapshot + destroyList = append(destroyList, removea[i].(retentionGridAdaptor).Snapshot) } return destroyList } diff --git a/pruning/keep_helpers.go b/pruning/keep_helpers.go index a756ce7..7c31d68 100644 --- a/pruning/keep_helpers.go +++ b/pruning/keep_helpers.go @@ -10,6 +10,17 @@ func filterSnapList(snaps []Snapshot, predicate func(Snapshot) bool) []Snapshot return r } +func partitionSnapList(snaps []Snapshot, predicate func(Snapshot) bool) (sTrue, sFalse []Snapshot) { + for i := range snaps { + if predicate(snaps[i]) { + sTrue = append(sTrue, snaps[i]) + } else { + sFalse = append(sFalse, snaps[i]) + } + } + return +} + func shallowCopySnapList(snaps []Snapshot) []Snapshot { c := make([]Snapshot, len(snaps)) copy(c, snaps) diff --git a/pruning/pruning_test.go b/pruning/pruning_test.go index 0927333..9a33e7a 100644 --- a/pruning/pruning_test.go +++ b/pruning/pruning_test.go @@ -75,6 +75,10 @@ func TestPruneSnapshots(t *testing.T) { }, } + reltime := func(secs int64) time.Time { + return time.Unix(secs, 0) + } + tcs := map[string]testCase{ "simple": { inputs: inputs["s1"], @@ -121,6 +125,24 @@ func TestPruneSnapshots(t *testing.T) { }, expDestroy: map[string]bool{}, }, + "multiple_grids_with_disjoint_regexes": { + inputs: []Snapshot{ + stubSnap{"p1_a", false, reltime(4)}, + stubSnap{"p2_a", false, reltime(5)}, + stubSnap{"p1_b", false, reltime(14)}, + stubSnap{"p2_b", false, reltime(15)}, + stubSnap{"p1_c", false, reltime(29)}, + stubSnap{"p2_c", false, reltime(30)}, + }, + rules: []KeepRule{ + MustNewKeepGrid("^p1_", `1x10s | 1x10s`), + MustNewKeepGrid("^p2_", `1x10s | 1x10s`), + }, + expDestroy: map[string]bool{ + "p1_a": true, + "p2_a": true, + }, + }, } testTable(tcs, t)