github.com/artpar/rclone@v1.67.3/backend/union/policy/eplus.go (about) 1 package policy 2 3 import ( 4 "context" 5 "math" 6 7 "github.com/artpar/rclone/backend/union/upstream" 8 "github.com/artpar/rclone/fs" 9 ) 10 11 func init() { 12 registerPolicy("eplus", &EpLus{}) 13 } 14 15 // EpLus stands for existing path, least used space 16 // Of all the candidates on which the path exists choose the one with the least used space. 17 type EpLus struct { 18 EpAll 19 } 20 21 func (p *EpLus) lus(upstreams []*upstream.Fs) (*upstream.Fs, error) { 22 var minUsedSpace int64 = math.MaxInt64 23 var lusupstream *upstream.Fs 24 for _, u := range upstreams { 25 space, err := u.GetUsedSpace() 26 if err != nil { 27 fs.LogPrintf(fs.LogLevelNotice, nil, 28 "Used Space is not supported for upstream %s, treating as 0", u.Name()) 29 } 30 if space < minUsedSpace { 31 minUsedSpace = space 32 lusupstream = u 33 } 34 } 35 if lusupstream == nil { 36 return nil, fs.ErrorObjectNotFound 37 } 38 return lusupstream, nil 39 } 40 41 func (p *EpLus) lusEntries(entries []upstream.Entry) (upstream.Entry, error) { 42 var minUsedSpace int64 = math.MaxInt64 43 var lusEntry upstream.Entry 44 for _, e := range entries { 45 space, err := e.UpstreamFs().GetUsedSpace() 46 if err != nil { 47 fs.LogPrintf(fs.LogLevelNotice, nil, 48 "Used Space is not supported for upstream %s, treating as 0", e.UpstreamFs().Name()) 49 } 50 if space < minUsedSpace { 51 minUsedSpace = space 52 lusEntry = e 53 } 54 } 55 return lusEntry, nil 56 } 57 58 // Action category policy, governing the modification of files and directories 59 func (p *EpLus) Action(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 60 upstreams, err := p.EpAll.Action(ctx, upstreams, path) 61 if err != nil { 62 return nil, err 63 } 64 u, err := p.lus(upstreams) 65 return []*upstream.Fs{u}, err 66 } 67 68 // ActionEntries is ACTION category policy but receiving a set of candidate entries 69 func (p *EpLus) ActionEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 70 entries, err := p.EpAll.ActionEntries(entries...) 71 if err != nil { 72 return nil, err 73 } 74 e, err := p.lusEntries(entries) 75 return []upstream.Entry{e}, err 76 } 77 78 // Create category policy, governing the creation of files and directories 79 func (p *EpLus) Create(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 80 upstreams, err := p.EpAll.Create(ctx, upstreams, path) 81 if err != nil { 82 return nil, err 83 } 84 u, err := p.lus(upstreams) 85 return []*upstream.Fs{u}, err 86 } 87 88 // CreateEntries is CREATE category policy but receiving a set of candidate entries 89 func (p *EpLus) CreateEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 90 entries, err := p.EpAll.CreateEntries(entries...) 91 if err != nil { 92 return nil, err 93 } 94 e, err := p.lusEntries(entries) 95 return []upstream.Entry{e}, err 96 } 97 98 // Search category policy, governing the access to files and directories 99 func (p *EpLus) Search(ctx context.Context, upstreams []*upstream.Fs, path string) (*upstream.Fs, error) { 100 if len(upstreams) == 0 { 101 return nil, fs.ErrorObjectNotFound 102 } 103 upstreams, err := p.epall(ctx, upstreams, path) 104 if err != nil { 105 return nil, err 106 } 107 return p.lus(upstreams) 108 } 109 110 // SearchEntries is SEARCH category policy but receiving a set of candidate entries 111 func (p *EpLus) SearchEntries(entries ...upstream.Entry) (upstream.Entry, error) { 112 if len(entries) == 0 { 113 return nil, fs.ErrorObjectNotFound 114 } 115 return p.lusEntries(entries) 116 }