package buckets import ( "errors" "fmt" "idun/pkg/storage" "sort" "time" ) type Bucket interface { AddFile(storage.File) error Execute() error ToString() string GetFilesToDelete() ([]storage.File, error) } type UnlimitBucket struct { start time.Time end time.Time } func (u UnlimitBucket) AddFile(f storage.File) error { t, err := f.GetTime() if err != nil { return err } if t.Before(u.start) || t.After(u.end) { return storage.ErrFileNotInBucketTime } return nil } func (u UnlimitBucket) Execute() error { return nil } func (b UnlimitBucket) GetFilesToDelete() ([]storage.File, error) { return []storage.File{}, nil } func (u UnlimitBucket) ToString() string { return fmt.Sprintf("%v to %v (Unlimit)", u.start, u.end) } type DeleteBucket struct { start time.Time end time.Time files []storage.File } func (d *DeleteBucket) AddFile(f storage.File) error { t, err := f.GetTime() if err != nil { return err } if t.Before(d.start) || t.After(d.end) { return storage.ErrFileNotInBucketTime } d.files = append(d.files, f) return nil } func (d DeleteBucket) Execute() error { return nil } func (d DeleteBucket) ToString() string { return fmt.Sprintf("%v to %v (Delete)", d.start, d.end) } func (b DeleteBucket) GetFilesToDelete() ([]storage.File, error) { return b.files, nil } type TimeBucket struct { files []storage.File start time.Time end time.Time } func (b TimeBucket) ToString() string { return fmt.Sprintf("%v to %v", b.start, b.end) } func (b *TimeBucket) AddFile(f storage.File) error { t, err := f.GetTime() if err != nil { return err } if t.Before(b.start) || t.After(b.end) { return storage.ErrFileNotInBucketTime } b.files = append(b.files, f) return nil } func (b TimeBucket) Execute() error { if len(b.files) <= 1 { return nil } return nil } func (b TimeBucket) GetFilesToDelete() ([]storage.File, error) { toDelete := []storage.File{} sort.SliceStable(b.files, func(i, j int) bool { t1, _ := b.files[i].GetTime() t2, _ := b.files[j].GetTime() return t1.After(t2) }) for i, f := range b.files { if i == 0 { continue } toDelete = append(toDelete, f) } return toDelete, nil } func NewTimeBucket(start time.Time, end time.Time) (TimeBucket, error) { if start.After(end) { return TimeBucket{}, errors.New("start time must be before end time") } t := TimeBucket{ start: start, end: end, } return t, nil }