Repository: rclone/rclone
File: backend/box/box.go (Go)

Code before:
		remote := path.Join(dir, info.Name)
		if info.Type == api.ItemTypeFolder {
			// cache the directory ID for later lookups
			f.dirCache.Put(remote, info.ID)
			d := fs.NewDir(remote, info.ModTime()).SetID(info.ID)
			// FIXME more info from dir?
			entries = append(entries, d)
		} else if info.Type == api.ItemTypeFile {
			o, err := f.newObjectWithInfo(ctx, remote, info)
			if err != nil {
				iErr = err
				return true
			}
			entries = append(entries, o)
		}

		f.itemMetaCacheMu.Lock()
		if f.itemMetaCache != nil {
			// If polling is enabled, cache some metadata for this Item
			// to help us process events later on. In particular, the box
			// event API does not provide the old path of the Item when it
			// is renamed/deleted/moved/etc.
			newSequenceID, err := strconv.ParseInt(info.SequenceID, 10, 64)
			if err != nil {
				iErr = fmt.Errorf("failed to parse `sequence_id` (%q) while listing directory: %w", info.SequenceID, err)
				return true
			}

			cachedItemMeta, found := f.itemMetaCache[info.ID]
			if !found || cachedItemMeta.SequenceID < newSequenceID {
				f.itemMetaCache[info.ID] = ItemMeta{SequenceID: newSequenceID, ParentID: directoryID, Name: info.Name}
			}
		}
		f.itemMetaCacheMu.Unlock()

		return false
	})
	if err != nil {
		return nil, err
	}
	if iErr != nil {
		return nil, iErr
	}
	return entries, nil
}

// Creates from the parameters passed in a half finished Object which
// must have setMetaData called on it
//
// Returns the object, leaf, directoryID and error.
//

Review comment (performance):
This exits the function with the `f.itemMetaCacheMu` locked - the suggestion above to get the JSON parser to `int` the number will fix this though.

Code after:
	_, err = f.listAll(ctx, directoryID, false, false, true, func(info *api.Item) bool {
		remote := path.Join(dir, info.Name)
		if info.Type == api.ItemTypeFolder {
			// cache the directory ID for later lookups
			f.dirCache.Put(remote, info.ID)
			d := fs.NewDir(remote, info.ModTime()).SetID(info.ID)
			// FIXME more info from dir?
			entries = append(entries, d)
		} else if info.Type == api.ItemTypeFile {
			o, err := f.newObjectWithInfo(ctx, remote, info)
			if err != nil {
				iErr = err
				return true
			}
			entries = append(entries, o)
		}

		// Cache some metadata for this Item to help us process events later
		// on. In particular, the box event API does not provide the old path
		// of the Item when it is renamed/deleted/moved/etc.
		f.itemMetaCacheMu.Lock()
		cachedItemMeta, found := f.itemMetaCache[info.ID]
		if !found || cachedItemMeta.SequenceID < info.SequenceID {
			f.itemMetaCache[info.ID] = ItemMeta{SequenceID: info.SequenceID, ParentID: directoryID, Name: info.Name}
		}
		f.itemMetaCacheMu.Unlock()

		return false
	})
	if err != nil {
		return nil, err
	}
	if iErr != nil {
		return nil, iErr
	}
	return entries, nil
}

// Creates from the parameters passed in a half finished Object which
// must have setMetaData called on it
//
// Returns the object, leaf, directoryID and error.
//
// Used to create new objects
func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) {
	// Create the directory for the object if it doesn't exist
	leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true)
	if err != nil {
		return
	}
	// Temporary Object under construction