Repository: rclone/rclone
File: fs/sync/sync.go (Go)

Code before:
	toBeUploaded           *pipe                  // copiers channel
	errorMu                sync.Mutex             // Mutex covering the errors variables
	err                    error                  // normal error from copy process
	noRetryErr             error                  // error with NoRetry set
	fatalErr               error                  // fatal error
	commonHash             hash.Type              // common hash type between src and dst
	modifyWindow           time.Duration          // modify window between fsrc, fdst
	renameMapMu            sync.Mutex             // mutex to protect the below
	renameMap              map[string][]fs.Object // dst files by hash - only used by trackRenames
	renamerWg              sync.WaitGroup         // wait for renamers
	toBeRenamed            *pipe                  // renamers channel
	trackRenamesWg         sync.WaitGroup         // wg for background track renames
	trackRenamesCh         chan fs.Object         // objects are pumped in here
	renameCheck            []fs.Object            // accumulate files to check for rename here
	compareCopyDest        []fs.Fs                // place to check for files to server side copy
	backupDir              fs.Fs                  // place to store overwrites/deletes
	checkFirst             bool                   // if set run all the checkers before starting transfers
	maxDurationEndTime     time.Time              // end time if --max-duration is set
	logger                 operations.LoggerFn    // LoggerFn used to report the results of a sync (or bisync) to an io.Writer
	usingLogger            bool                   // whether we are using logger
	setDirMetadata         bool                   // if set we set the directory metadata
	setDirModTime          bool                   // if set we set the directory modtimes
	setDirModTimeAfter     bool                   // if set we set the directory modtimes at the end of the sync
	setDirModTimeMu        sync.Mutex             // protect setDirModTimeMu
	setDirModTimes         []setDirModTime        // directories that need their modtime set
	setDirModTimesMaxLevel int                    // max level of the directories to set
	modifiedDirs           map[string]struct{}    // dirs with changed contents (if s.setDirModTimeAfter)
}

// For keeping track of delayed modtime sets
type setDirModTime struct {
	dst     fs.Directory
	dir     string
	modTime time.Time
	level   int // the level of the directory, 0 is root
}

type trackRenamesStrategy byte

const (
	trackRenamesStrategyHash trackRenamesStrategy = 1 << iota
	trackRenamesStrategyModtime
	trackRenamesStrategyLeaf
)

func (strategy trackRenamesStrategy) hash() bool {
	return (strategy & trackRenamesStrategyHash) != 0
}

func (strategy trackRenamesStrategy) modTime() bool {
	return (strategy & trackRenamesStrategyModtime) != 0

Review comment (suggestion):
~~This needs a mutex to protect it `modifiedDirsMu` - it will be accessed concurrently~~

Edit: I see you are using the `setDirModTimeMu` which is fine - either annotate the help with that info, or rename the variable `setDirModTimeDirs` or something like that to group it with `setDirModTimeMu`

Code after:
	errorMu                sync.Mutex             // Mutex covering the errors variables
	err                    error                  // normal error from copy process
	noRetryErr             error                  // error with NoRetry set
	fatalErr               error                  // fatal error
	commonHash             hash.Type              // common hash type between src and dst
	modifyWindow           time.Duration          // modify window between fsrc, fdst
	renameMapMu            sync.Mutex             // mutex to protect the below
	renameMap              map[string][]fs.Object // dst files by hash - only used by trackRenames
	renamerWg              sync.WaitGroup         // wait for renamers
	toBeRenamed            *pipe                  // renamers channel
	trackRenamesWg         sync.WaitGroup         // wg for background track renames
	trackRenamesCh         chan fs.Object         // objects are pumped in here
	renameCheck            []fs.Object            // accumulate files to check for rename here
	compareCopyDest        []fs.Fs                // place to check for files to server side copy
	backupDir              fs.Fs                  // place to store overwrites/deletes
	checkFirst             bool                   // if set run all the checkers before starting transfers
	maxDurationEndTime     time.Time              // end time if --max-duration is set
	logger                 operations.LoggerFn    // LoggerFn used to report the results of a sync (or bisync) to an io.Writer
	usingLogger            bool                   // whether we are using logger
	setDirMetadata         bool                   // if set we set the directory metadata
	setDirModTime          bool                   // if set we set the directory modtimes
	setDirModTimeAfter     bool                   // if set we set the directory modtimes at the end of the sync
	setDirModTimeMu        sync.Mutex             // protect setDirModTimes and modifiedDirs
	setDirModTimes         []setDirModTime        // directories that need their modtime set
	setDirModTimesMaxLevel int                    // max level of the directories to set
	modifiedDirs           map[string]struct{}    // dirs with changed contents (if s.setDirModTimeAfter)
}

// For keeping track of delayed modtime sets
type setDirModTime struct {
	dst     fs.Directory
	dir     string
	modTime time.Time
	level   int // the level of the directory, 0 is root
}

type trackRenamesStrategy byte

const (
	trackRenamesStrategyHash trackRenamesStrategy = 1 << iota
	trackRenamesStrategyModtime
	trackRenamesStrategyLeaf
)

func (strategy trackRenamesStrategy) hash() bool {
	return (strategy & trackRenamesStrategyHash) != 0
}

func (strategy trackRenamesStrategy) modTime() bool {
	return (strategy & trackRenamesStrategyModtime) != 0
}