march: factor calling parameters into a structure

This commit is contained in:
Nick Craig-Wood 2018-11-25 17:26:58 +00:00
parent d99ffde7c0
commit e3c4ebd59a
3 changed files with 40 additions and 31 deletions

View File

@ -16,14 +16,16 @@ import (
) )
// March holds the data used to traverse two Fs simultaneously, // March holds the data used to traverse two Fs simultaneously,
// calling callback for each match // calling Callback for each match
type March struct { type March struct {
// parameters // parameters
ctx context.Context Ctx context.Context // context for background goroutines
fdst fs.Fs Fdst fs.Fs // source Fs
fsrc fs.Fs Fsrc fs.Fs // dest Fs
dir string Dir string // directory
callback Marcher SrcIncludeAll bool // don't include all files in the src
DstIncludeAll bool // don't include all files in the destination
Callback Marcher // object to call with results
// internal state // internal state
srcListDir listDirFn // function to call to list a directory in the src srcListDir listDirFn // function to call to list a directory in the src
dstListDir listDirFn // function to call to list a directory in the dst dstListDir listDirFn // function to call to list a directory in the dst
@ -40,17 +42,10 @@ type Marcher interface {
Match(dst, src fs.DirEntry) (recurse bool) Match(dst, src fs.DirEntry) (recurse bool)
} }
// New sets up a march over fsrc, and fdst calling back callback for each match // init sets up a march over opt.Fsrc, and opt.Fdst calling back callback for each match
func New(ctx context.Context, fdst, fsrc fs.Fs, dir string, callback Marcher) *March { func (m *March) init() {
m := &March{ m.srcListDir = m.makeListDir(m.Fsrc, m.SrcIncludeAll)
ctx: ctx, m.dstListDir = m.makeListDir(m.Fdst, m.DstIncludeAll)
fdst: fdst,
fsrc: fsrc,
dir: dir,
callback: callback,
}
m.srcListDir = m.makeListDir(fsrc, false)
m.dstListDir = m.makeListDir(fdst, filter.Active.Opt.DeleteExcluded)
// Now create the matching transform // Now create the matching transform
// ..normalise the UTF8 first // ..normalise the UTF8 first
m.transforms = append(m.transforms, norm.NFC.String) m.transforms = append(m.transforms, norm.NFC.String)
@ -60,10 +55,9 @@ func New(ctx context.Context, fdst, fsrc fs.Fs, dir string, callback Marcher) *M
// | Yes | No | No | // | Yes | No | No |
// | No | Yes | Yes | // | No | Yes | Yes |
// | Yes | Yes | Yes | // | Yes | Yes | Yes |
if fdst.Features().CaseInsensitive { if m.Fdst.Features().CaseInsensitive {
m.transforms = append(m.transforms, strings.ToLower) m.transforms = append(m.transforms, strings.ToLower)
} }
return m
} }
// list a directory into entries, err // list a directory into entries, err
@ -86,7 +80,7 @@ func (m *March) makeListDir(f fs.Fs, includeAll bool) listDirFn {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
if !started { if !started {
dirs, dirsErr = walk.NewDirTree(f, m.dir, includeAll, fs.Config.MaxDepth) dirs, dirsErr = walk.NewDirTree(f, m.Dir, includeAll, fs.Config.MaxDepth)
started = true started = true
} }
if dirsErr != nil { if dirsErr != nil {
@ -114,6 +108,8 @@ type listDirJob struct {
// Run starts the matching process off // Run starts the matching process off
func (m *March) Run() { func (m *March) Run() {
m.init()
srcDepth := fs.Config.MaxDepth srcDepth := fs.Config.MaxDepth
if srcDepth < 0 { if srcDepth < 0 {
srcDepth = fs.MaxLevel srcDepth = fs.MaxLevel
@ -133,7 +129,7 @@ func (m *March) Run() {
defer wg.Done() defer wg.Done()
for { for {
select { select {
case <-m.ctx.Done(): case <-m.Ctx.Done():
return return
case job, ok := <-in: case job, ok := <-in:
if !ok { if !ok {
@ -147,7 +143,7 @@ func (m *March) Run() {
// jobs off for traversal in the background // jobs off for traversal in the background
for _, newJob := range jobs { for _, newJob := range jobs {
select { select {
case <-m.ctx.Done(): case <-m.Ctx.Done():
// discard job if finishing // discard job if finishing
traversing.Done() traversing.Done()
case in <- newJob: case in <- newJob:
@ -164,14 +160,14 @@ func (m *March) Run() {
// Start the process // Start the process
traversing.Add(1) traversing.Add(1)
in <- listDirJob{ in <- listDirJob{
srcRemote: m.dir, srcRemote: m.Dir,
srcDepth: srcDepth - 1, srcDepth: srcDepth - 1,
dstRemote: m.dir, dstRemote: m.Dir,
dstDepth: dstDepth - 1, dstDepth: dstDepth - 1,
} }
go func() { go func() {
// when the context is cancelled discard the remaining jobs // when the context is cancelled discard the remaining jobs
<-m.ctx.Done() <-m.Ctx.Done()
for range in { for range in {
traversing.Done() traversing.Done()
} }
@ -184,7 +180,7 @@ func (m *March) Run() {
// Check to see if the context has been cancelled // Check to see if the context has been cancelled
func (m *March) aborting() bool { func (m *March) aborting() bool {
select { select {
case <-m.ctx.Done(): case <-m.Ctx.Done():
return true return true
default: default:
} }
@ -377,7 +373,7 @@ func (m *March) processJob(job listDirJob) (jobs []listDirJob) {
if m.aborting() { if m.aborting() {
return nil return nil
} }
recurse := m.callback.SrcOnly(src) recurse := m.Callback.SrcOnly(src)
if recurse && job.srcDepth > 0 { if recurse && job.srcDepth > 0 {
jobs = append(jobs, listDirJob{ jobs = append(jobs, listDirJob{
srcRemote: src.Remote(), srcRemote: src.Remote(),
@ -391,7 +387,7 @@ func (m *March) processJob(job listDirJob) (jobs []listDirJob) {
if m.aborting() { if m.aborting() {
return nil return nil
} }
recurse := m.callback.DstOnly(dst) recurse := m.Callback.DstOnly(dst)
if recurse && job.dstDepth > 0 { if recurse && job.dstDepth > 0 {
jobs = append(jobs, listDirJob{ jobs = append(jobs, listDirJob{
dstRemote: dst.Remote(), dstRemote: dst.Remote(),
@ -404,7 +400,7 @@ func (m *March) processJob(job listDirJob) (jobs []listDirJob) {
if m.aborting() { if m.aborting() {
return nil return nil
} }
recurse := m.callback.Match(match.dst, match.src) recurse := m.Callback.Match(match.dst, match.src)
if recurse && job.srcDepth > 0 && job.dstDepth > 0 { if recurse && job.srcDepth > 0 && job.dstDepth > 0 {
jobs = append(jobs, listDirJob{ jobs = append(jobs, listDirJob{
srcRemote: match.src.Remote(), srcRemote: match.src.Remote(),

View File

@ -685,7 +685,13 @@ func CheckFn(fdst, fsrc fs.Fs, check checkFn, oneway bool) error {
} }
// set up a march over fdst and fsrc // set up a march over fdst and fsrc
m := march.New(context.Background(), fdst, fsrc, "", c) m := &march.March{
Ctx: context.Background(),
Fdst: fdst,
Fsrc: fsrc,
Dir: "",
Callback: c,
}
fs.Infof(fdst, "Waiting for checks to finish") fs.Infof(fdst, "Waiting for checks to finish")
m.Run() m.Run()

View File

@ -646,7 +646,14 @@ func (s *syncCopyMove) run() error {
s.startTrackRenames() s.startTrackRenames()
// set up a march over fdst and fsrc // set up a march over fdst and fsrc
m := march.New(s.ctx, s.fdst, s.fsrc, s.dir, s) m := &march.March{
Ctx: s.ctx,
Fdst: s.fdst,
Fsrc: s.fsrc,
Dir: s.dir,
Callback: s,
DstIncludeAll: filter.Active.Opt.DeleteExcluded,
}
m.Run() m.Run()
s.stopTrackRenames() s.stopTrackRenames()