<commit_before>module Concurrent

  class CopyOnWriteObserverSet

    def initialize
      @mutex = Mutex.new
      @observers = {}
    end

    def add_observer(observer, func=:update)
      @mutex.synchronize do
        new_observers = @observers.dup
        new_observers[observer] = func
        @observers = new_observers
      end
      func
    end

    def delete_observer(observer)
      @mutex.synchronize do
        new_observers = @observers.dup
        new_observers.delete(observer)
        @observers = new_observers
      end
      observer
    end

    def delete_observers
      self.observers = {}
      self
    end

    def count_observers
      observers.count
    end

    def notify_observers(*args)
      notify_to(observers, *args)
      self
    end

    def notify_and_delete_observers(*args)
      old = clear_observers_and_return_old
      notify_to(old, *args)
      self
    end

    private

      def notify_to(observers, *args)
        observers.each do |observer, function|
          observer.send function, *args
        end
      end

      def observers
        @mutex.synchronize { @observers }
      end

      def observers=(new_set)
        @mutex.synchronize { @observers = new_set}
      end

      def clear_observers_and_return_old
        @mutex.synchronize do
          old_observers = @observers
          @observers = {}<commit_msg>added YARD to copy on write observer set<commit_after>module Concurrent

  # A thread safe observer set implemented using copy-on-write approach:
  # every time an observer is added or removed the whole internal data structure is
  # duplicated and replaced with a new one.
  class CopyOnWriteObserverSet

    def initialize
      @mutex = Mutex.new
      @observers = {}
    end

    # Adds an observer to this set
    # @param [Object] observer the observer to add
    # @param [Symbol] func the function to call on the observer during notification. Default is :update
    # @return [Symbol] the added function
    def add_observer(observer, func=:update)
      @mutex.synchronize do
        new_observers = @observers.dup
        new_observers[observer] = func
        @observers = new_observers
      end
      func
    end

    # @param [Object] observer the observer to remove
    # @return [Object] the deleted observer
    def delete_observer(observer)
      @mutex.synchronize do
        new_observers = @observers.dup
        new_observers.delete(observer)
        @observers = new_observers
      end
      observer
    end

    # Deletes all observers
    # @return [CopyOnWriteObserverSet] self
    def delete_observers
      self.observers = {}
      self
    end


    # @return [Integer] the observers count
    def count_observers
      observers.count
    end

    # Notifies all registered observers with optional args
    # @param [Object] args arguments to be passed to each observer
    # @return [CopyOnWriteObserverSet] self
    def notify_observers(*args)
      notify_to(observers, *args)
      self
    end

    # Notifies all registered observers with optional args and deletes them.
    #
    # @param [Object] args arguments to be passed to each observer
    # @return [CopyOnWriteObserverSet] self
    def notify_and_delete_observers(*args)
      old = clear_observers_and_return_old
      notify_to(old, *args)
      self
    end

    private

      def notify_to(observers, *args)
        observers.each do |observer, function|
          observer.send function, *args
        end
      end

      def observers
        @mutex.synchronize { @observers }
      end

      def observers=(new_set)
        @mutex.synchronize { @observers = new_set}
      end

      def clear_observers_and_return_old
        @mutex.synchronize do
          old_observers = @observers
          @observers = {}
{'fraction_non_alphanumeric': 0.06281208935611038, 'fraction_numerical': 0.0, 'mean_word_length': 2.3562610229276895, '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': '3007638', 'n_tokens_mistral': 1121, 'n_tokens_neox': 1123, 'n_words': 316}