// doubleWalkDiff walks both directories to create a diff
14030
func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (err error) {
	g, ctx := errgroup.WithContext(ctx)

	var (
		c1 = make(chan *currentPath, 128)
		c2 = make(chan *currentPath, 128)

		f1, f2 *currentPath
		rmdir  string
	)
	g.Go(func() error {
		defer close(c1)
		return a(ctx, c1)
	})
	g.Go(func() error {
		defer close(c2)
		return b(ctx, c2)
	})
	g.Go(func() error {
	loop0:
		for c1 != nil || c2 != nil {
			if f1 == nil && c1 != nil {
				f1, err = nextPath(ctx, c1)
				if err != nil {
					return err
				}
				if f1 == nil {
					c1 = nil
				}
			}

			if f2 == nil && c2 != nil {
				f2, err = nextPath(ctx, c2)
				if err != nil {
					return err
				}
				if f2 == nil {
					c2 = nil
				}
			}
			if f1 == nil && f2 == nil {
				continue
			}

			var f os.FileInfo
			k, p := pathChange(f1, f2)
			switch k {
			case ChangeKindAdd:
				if rmdir != "" {
					rmdir = ""
				}
				f = f2.f
				f2 = nil
			case ChangeKindDelete:
				// Check if this file is already removed by being
				// under of a removed directory
				if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
					f1 = nil
					continue
				} else if rmdir == "" && f1.f.IsDir() {
					rmdir = f1.path + string(os.PathSeparator)
				} else if rmdir != "" {
					rmdir = ""
				}
				f1 = nil
			case ChangeKindModify:
				same, err := sameFile(f1, f2)
				if err != nil {
					return err
				}
				if f1.f.IsDir() && !f2.f.IsDir() {
					rmdir = f1.path + string(os.PathSeparator)
				} else if rmdir != "" {
					rmdir = ""
				}
				f = f2.f
				f1 = nil
				f2 = nil
				if same {
					continue loop0
				}
			}
			if err := changeFn(k, p, f, nil); err != nil {
				return err
			}
		}
		return nil
	})

	return g.Wait()
}
1169589
func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
	if useNaiveDiff(d.home) || !d.isParent(id, parent) {
		return d.naiveDiff.Diff(id, parent)
	}

	diffPath := d.getDiffPath(id)
	logger.Debugf("Tar with options on %s", diffPath)
	return archive.TarWithOptions(diffPath, &archive.TarOptions{
		Compression:    archive.Uncompressed,
		UIDMaps:        d.uidMaps,
		GIDMaps:        d.gidMaps,
		WhiteoutFormat: archive.OverlayWhiteoutFormat,
	})
}
867993
func Diff(config, live *unstructured.Unstructured, normalizer Normalizer) *DiffResult {
	if config != nil {
		config = stripTypeInformation(config)
		Normalize(config, normalizer)
	}
	if live != nil {
		live = stripTypeInformation(live)
		Normalize(live, normalizer)
	}
	orig := GetLastAppliedConfigAnnotation(live)
	if orig != nil && config != nil {
		Normalize(orig, normalizer)
		dr, err := ThreeWayDiff(orig, config, live)
		if err == nil {
			return dr
		}
		log.Debugf("three-way diff calculation failed: %v. Falling back to two-way diff", err)
	}
	return TwoWayDiff(config, live)
}
1113119
func WalkDirs(name string, includeDirsInList bool, files ...string) ([]string, error) {
	f, err := FS.OpenFile(CTX, name, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}

	fileInfos, err := f.Readdir(0)
	f.Close()
	if err != nil {
		return nil, err
	}

	for _, info := range fileInfos {
		filename := path.Join(name, info.Name())

		if includeDirsInList || !info.IsDir() {
			files = append(files, filename)
		}

		if info.IsDir() {
			files, err = WalkDirs(filename, includeDirsInList, files...)
			if err != nil {
				return nil, err
			}
		}
	}

	return files, nil
}
558233
func (msdw *MultiSplitDiffWorker) diff(ctx context.Context) error {
	msdw.SetState(WorkerStateDiff)

	destinationSchemaDefinitions, sourceSchemaDefinition, err := msdw.gatherSchemaInfo(ctx)
	if err != nil {
		return err
	}
	err = msdw.diffSchemaInformation(ctx, destinationSchemaDefinitions, sourceSchemaDefinition)
	if err != nil {
		return err
	}

	// read the vschema if needed
	var keyspaceSchema *vindexes.KeyspaceSchema
	if *useV3ReshardingMode {
		keyspaceSchema, err = msdw.loadVSchema(ctx)
		if err != nil {
			return err
		}
	}

	msdw.wr.Logger().Infof("running the diffs...")
	tableDefinitions := sourceSchemaDefinition.TableDefinitions
	rec := &concurrency.AllErrorRecorder{}

	// sort tables by size
	// if there are large deltas between table sizes then it's more efficient to start working on the large tables first
	sort.Slice(tableDefinitions, func(i, j int) bool { return tableDefinitions[i].DataLength > tableDefinitions[j].DataLength })
	tableChan := make(chan *tabletmanagerdatapb.TableDefinition, len(tableDefinitions))
	for _, tableDefinition := range tableDefinitions {
		tableChan <- tableDefinition
	}
	close(tableChan)

	consumers := sync.WaitGroup{}
	// start as many goroutines we want parallel diffs running
	for i := 0; i < msdw.parallelDiffsCount; i++ {
		scanners := msdw.scanners[i]
		if scanners.sourceScanner == nil || scanners.destinationScanner == nil {
			return vterrors.Errorf(vtrpc.Code_INTERNAL, "should not be nil [%v] OR [%v]", scanners.sourceScanner, scanners.destinationScanner)
		}

		consumers.Add(1)
		go msdw.tableDiffingConsumer(ctx, &consumers, tableChan, rec, keyspaceSchema, scanners.sourceScanner, scanners.destinationScanner)
	}

	// wait for all consumers to wrap up their work
	consumers.Wait()

	return rec.Error()
}
270977
func (b *BinaryTree) Walk() []Comparable {
	walked := make([]Comparable, 0, b.size)
	return walkInOrder(b.root, walked)
}
1196109
func walk(c *dhCreator, path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
	err := walkFn(path, info, nil)
	if err != nil {
		if info.IsDir() && err == filepath.SkipDir {
			return nil
		}
		return err
	}

	if !info.IsDir() {
		return nil
	}

	names, err := readOrderedDirNames(c, path)
	if err != nil {
		return walkFn(path, info, err)
	}

	for _, name := range names {
		filename := filepath.Join(path, name)
		fileInfo, err := c.fs.Lstat(filename)
		if err != nil {
			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
				return err
			}
		} else {
			err = walk(c, filename, fileInfo, walkFn)
			if err != nil {
				if !fileInfo.IsDir() || err != filepath.SkipDir {
					return err
				}
			}
		}
	}
	c.DH.Entries = append(c.DH.Entries, Entry{
		Name: "..",
		Type: DotDotType,
		Pos:  len(c.DH.Entries),
	})
	if c.curDir != nil {
		c.curDir = c.curDir.Parent
	}
	return nil
}
1122885
func WalkFS(root string, fs FileSystem) *Walker {
	info, err := fs.Lstat(root)
	return &Walker{
		fs:    fs,
		stack: []item{{root, info, err}},
	}
}
886489
func dedupePaths(in []string) []string {
	out := make([]string, 0, len(in))
	var last string
	for _, s := range in {
		// if one of the paths is root there is no filter
		if s == "." {
			return nil
		}
		if strings.HasPrefix(s, last+string(filepath.Separator)) {
			continue
		}
		out = append(out, s)
		last = s
	}
	return out
}
962343
func (w *Writer) Diff(src, dst Object) error {
	// TODO: This can be optimized by skipping diff'ing during renames, mode changes, etc.
	if err := w.WriteHeader(src, dst); err != nil {
		return err
	}
	return w.WriteDiff(src, dst)
}
1075645
func walkDirectories(path string, walkFunc func(path string, info os.FileInfo) error) error {
	seen := make(map[string]bool)

	var walkHelper func(path string) error
	walkHelper = func(path string) error {
		qualifiedPath, err := realpath.Realpath(path)
		if err != nil {
			return err
		}

		// Prevent circular links.
		if seen[qualifiedPath] {
			return nil
		}
		seen[qualifiedPath] = true

		// Skip anything that isn't a directory.
		file, err := os.Stat(path)
		if err != nil {
			return err
		}
		if !file.IsDir() {
			return nil
		}

		err = walkFunc(path, file)
		if err != nil {
			if err == filepath.SkipDir {
				return nil
			}
			return err
		}

		files, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}

		for _, file := range files {
			err = walkHelper(filepath.Join(path, file.Name()))
			if err != nil {
				return err
			}
		}
		return nil
	}
	return walkHelper(path)
}
606862
func (l *lcowfs) Walk(root string, walkFn filepath.WalkFunc) error {
	info, err := l.Lstat(root)
	if err != nil {
		err = walkFn(root, nil, err)
	} else {
		err = l.walk(root, info, walkFn)
	}
	if err == filepath.SkipDir {
		return nil
	}
	return err
}
421771
func (d *Driver) Diff(id, parent string) (archive.Archive, error) {
	return archive.TarWithOptions(path.Join(virtPath, id), &archive.TarOptions{
		Compression:     archive.Uncompressed,
		ExcludePatterns: []string{archive.WhiteoutMetaPrefix + "*", "!" + archive.WhiteoutOpaqueDir},
	})
}
921367
func (g *AcyclicGraph) Walk(cb WalkFunc) tfdiags.Diagnostics {
	defer g.debug.BeginOperation(typeWalk, "").End("")

	w := &Walker{Callback: cb, Reverse: true}
	w.Update(g)
	return w.Wait()
}
228197
func ObjectDiff(a, b interface{}) string {
	ab, err := json.Marshal(a)
	if err != nil {
		panic(fmt.Sprintf("a: %v", err))
	}
	bb, err := json.Marshal(b)
	if err != nil {
		panic(fmt.Sprintf("b: %v", err))
	}
	return StringDiff(string(ab), string(bb))
}
1285463
func (d *Dir) Walk(path string) error {
	// If the directory exists, create a list of its contents.
	if path == "" {
		return nil
	}

	// See if the path exists
	exists, err := PathExists(path)
	if err != nil {
		return err
	}

	if !exists {
		err = fmt.Errorf("%s does not exist", path)
		return err
	}

	fullPath, err := filepath.Abs(path)
	if err != nil {
		return err
	}

	// Set up the callback function.
	callback := func(p string, fi os.FileInfo, err error) error {
		return d.addFile(fullPath, p, fi, err)
	}

	// Walk the tree.
	return filepath.Walk(fullPath, callback)
}
905872
func (fs *fakeFs) Walk(root string, walkFn filepath.WalkFunc) error {
	return fs.a.Walk(root, walkFn)
}