Class: Dotsync::DirectoryDiffer

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
PathUtils
Defined in:
lib/dotsync/utils/directory_differ.rb

Overview

DirectoryDiffer computes the difference between source and destination directories.

It identifies files that need to be added, modified, or removed to sync the destination with the source. When force mode is enabled, it also detects files in the destination that don't exist in the source (removals).

Performance Optimizations

This class implements several optimizations to handle large directory trees efficiently:

  1. Source index built during first walk (see #diff_mapping_directories) The source tree walk that finds additions/modifications also builds a Set of all source paths. In force mode, this Set enables O(1) lookups during the destination walk — replacing per-file File.exist? calls (disk I/O) with hash lookups (memory). Impact: ~100x faster for directories with thousands of files, single source traversal.

  2. Early directory pruning with Find.prune (see #diff_mapping_directories) When an only filter is configured, we prune entire directory subtrees that fall outside the inclusion list. This avoids walking thousands of irrelevant files. Impact: Reduced ~/.config scan from 8,686 files to ~100 files (the included ones).

  3. Size-based file comparison (see #files_differ?) Before comparing file contents byte-by-byte, we first compare file sizes. If sizes differ, the files are definitely different (no need to read contents). Impact: Avoids expensive content reads for most changed files.

Constant Summary

Constants included from PathUtils

PathUtils::ENV_VARS_COLOR

Instance Method Summary collapse

Methods included from PathUtils

#colorize_env_vars, #expand_env_vars, #extract_env_vars, #path_is_parent_or_same?, #relative_to_absolute, #sanitize_path, #translate_tmp_path

Constructor Details

#initialize(mapping) ⇒ DirectoryDiffer

Returns a new instance of DirectoryDiffer.



42
43
44
# File 'lib/dotsync/utils/directory_differ.rb', line 42

def initialize(mapping)
  @mapping = mapping
end

Instance Method Details

#diffObject



46
47
48
49
50
51
52
# File 'lib/dotsync/utils/directory_differ.rb', line 46

def diff
  if @mapping.directories?
    diff_mapping_directories
  elsif @mapping.files?
    diff_mapping_files
  end
end