<commit_before>module Listen
  class Record
    include Celluloid

    attr_accessor :paths, :listener

    def initialize(listener)
      @listener = listener
      @paths    = _init_paths
    end

    def set_path(type, path, data = {})
      new_data = file_data(path).merge(data).merge(type: type)
      @paths[::File.dirname(path)][::File.basename(path)] = new_data
    end

    def unset_path(path)
      @paths[::File.dirname(path)].delete(::File.basename(path))
    end

    def file_data(path)
      @paths[::File.dirname(path)][::File.basename(path)] || {}
    end

    def dir_entries(path)
      @paths[path.to_s]
    end

    def build
      @paths = _init_paths
      listener.directories.each do |path|
        options = { recursive: true, silence: true }
        listener.registry[:change_pool].change(:dir, path, options)
      end
    rescue
      Celluloid.logger.warn "build crashed: #{$!.inspect}"
      raise
    end

    private

    def _init_paths
      Hash.new { |h, k| h[k] = Hash.new }
    end
  end
end
<commit_msg>avoid modifying hash during traversal<commit_after>module Listen
  class Record
    include Celluloid

    attr_accessor :paths, :listener

    def initialize(listener)
      @listener = listener
      @paths    = _init_paths
    end

    def set_path(type, path, data = {})
      new_data = file_data(path).merge(data).merge(type: type)
      @paths[::File.dirname(path)][::File.basename(path)] = new_data
    end

    def unset_path(path)
      @paths[::File.dirname(path)].delete(::File.basename(path))
    end

    def file_data(path)
      @paths[::File.dirname(path)][::File.basename(path)] || {}
    end

    def dir_entries(path)
      @paths[path.to_s].dup
    end

    def build
      @paths = _init_paths
      listener.directories.each do |path|
        options = { recursive: true, silence: true }
        listener.registry[:change_pool].change(:dir, path, options)
      end
    rescue
      Celluloid.logger.warn "build crashed: #{$!.inspect}"
      raise
    end

    private

    def _init_paths
      Hash.new { |h, k| h[k] = Hash.new }
    end
  end
end

{'fraction_non_alphanumeric': 0.12606232294617564, 'fraction_numerical': 0.0, 'mean_word_length': 2.640893470790378, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '617665', 'n_tokens_mistral': 711, 'n_tokens_neox': 690, 'n_words': 148}