MCPcopy
hub / github.com/cubefs/cubefs / recursiveScan

Method recursiveScan

objectnode/fs_volume.go:2268–2418  ·  view source on GitHub ↗

Recursive scan of the directory starting from the given parentID. Match files and directories that match the prefix and delimiter criteria. Stop when the number of matches reaches a threshold or all files and directories are scanned.

(fileInfos []*FSFileInfo, prefixMap PrefixMap, parentId, maxKeys, readLimit, rc uint64, dirs []string,
	prefix, marker, delimiter string, onlyObject, firstEnter bool,
)

Source from the content-addressed store, hash-verified

2266// that match the prefix and delimiter criteria. Stop when the number of matches reaches a threshold
2267// or all files and directories are scanned.
2268func (v *Volume) recursiveScan(fileInfos []*FSFileInfo, prefixMap PrefixMap, parentId, maxKeys, readLimit, rc uint64, dirs []string,
2269 prefix, marker, delimiter string, onlyObject, firstEnter bool,
2270) ([]*FSFileInfo, PrefixMap, string, uint64, error) {
2271 var err error
2272 var nextMarker string
2273 var lastKey string
2274
2275 currentPath := strings.Join(dirs, pathSep) + pathSep
2276 currentPath = strings.TrimPrefix(currentPath, pathSep)
2277 log.LogDebugf("recursiveScan enter: currentPath(/%v) fileInfos(%v) parentId(%v) prefix(%v) marker(%v) rc(%v)",
2278 currentPath, fileInfos, parentId, prefix, marker, rc)
2279 defer func() {
2280 log.LogDebugf("recursiveScan exit: currentPath(/%v) fileInfos(%v) parentId(%v) prefix(%v) nextMarker(%v) rc(%v)",
2281 currentPath, fileInfos, parentId, prefix, nextMarker, rc)
2282 }()
2283
2284 // The "prefix" needs to be extracted as marker when it is larger than "marker".
2285 // So extract prefixMarker in this layer.
2286 prefixMarker := ""
2287 if prefix != "" {
2288 if len(dirs) == 0 {
2289 prefixMarker = prefix
2290 } else if strings.HasPrefix(prefix, currentPath) {
2291 prefixMarker = strings.TrimPrefix(prefix, currentPath)
2292 }
2293 }
2294
2295 // To be sent in the readdirlimit request as a search start point.
2296 fromName := ""
2297 // Marker in this layer, shall be compared with prefixMarker to
2298 // determine which one should be used as the search start point.
2299 currentMarker := ""
2300 if marker != "" {
2301 markerNames := strings.Split(marker, pathSep)
2302 if len(markerNames) > len(dirs) {
2303 currentMarker = markerNames[len(dirs)]
2304 }
2305 if prefixMarker > currentMarker {
2306 fromName = prefixMarker
2307 } else {
2308 fromName = currentMarker
2309 }
2310 } else if prefixMarker != "" {
2311 fromName = prefixMarker
2312 }
2313
2314 // During the process of scanning the child nodes of the current directory, there may be other
2315 // parallel operations that may delete the current directory.
2316 // If got the syscall.ENOENT error when invoke readdir, it means that the above situation has occurred.
2317 // At this time, stops process and returns success.
2318 var children []proto.Dentry
2319
2320readDir:
2321 children, err = v.mw.ReadDirLimit_ll(parentId, fromName, readLimit+1) // one more for nextMarker
2322 if err != nil && err != syscall.ENOENT {
2323 return fileInfos, prefixMap, "", 0, err
2324 }
2325 if err == syscall.ENOENT {

Callers 2

listFilesV1Method · 0.95
listFilesV2Method · 0.95

Calls 11

LogDebugfFunction · 0.92
SubStringFunction · 0.92
containMethod · 0.80
AddPrefixMethod · 0.80
IsRegularMethod · 0.80
JoinMethod · 0.65
SplitMethod · 0.65
ReadDirLimit_llMethod · 0.65
IndexMethod · 0.65
IsDirMethod · 0.45
ReplaceMethod · 0.45

Tested by

no test coverage detected