<commit_before>class Merb::Cache::MemcacheStore
  # Provides the memcache cache store for merb-cache

  def initialize
    @config = Merb::Controller._cache.config
    prepare
  end

  class NotReady < Exception
    def initialize
      super("Memcache server is not ready")
    end
  end

  class NotDefined < Exception
    def initialize
      super("Memcache is not defined (require it in init.rb)")
    end
  end

  # This method is there to ensure minimal requirements are met
  # (directories are accessible, table exists, connected to server, ...)
  def prepare
    namespace = @config[:namespace] || 'merb-cache'
    host = @config[:host] || '127.0.0.1:11211'
    @memcache = MemCache.new(host, {:namespace => namespace})
    @tracking_key = "_#{namespace}_keys" unless @config[:no_tracking] == true
    raise NotReady unless @memcache.active?
    true
  rescue NameError
    raise NotDefined
  end

  # Checks whether a cache entry exists
  #
  # ==== Parameter
  # key<String>:: The key identifying the cache entry
  #
  # ==== Returns
  # true if the cache entry exists, false otherwise
  def cached?(key)
    not cache_get(key).nil?
  end

  # Capture or restore the data in cache.
  # If the cache entry expired or does not exist, the data are taken
  # from the execution of the block, marshalled and stored in cache.
  # Otherwise, the data are loaded from the cache and returned unmarshalled
  #
  # ==== Parameters
  # _controller<Merb::Controller>:: The instance of the current controller
  # key<String>:: The key identifying the cache entry
  # from_now<~minutes>::
  #   The number of minutes (from now) the cache should persist
  # &block:: The template to be used or not
  #
  # ==== Additional information
  # When fetching data (the cache entry exists and has not expired)
  # The data are loaded from the cache and returned unmarshalled.
  # Otherwise:
  # The controller is used to capture the rendered template (from the block).
  # It uses the capture_#{engine} and concat_#{engine} methods to do so.
  # The captured data are then marshalled and stored.
  def cache(_controller, key, from_now = nil, &block)
    _data = cache_get(key)
    if _data.nil?
      _data = _controller.send(:capture, &block)
      cache_set(key, _data, from_now)
    end
    _controller.send(:concat, _data, block.binding)
    true
  end

  # Store data to memcache using the specified key
  #
  # ==== Parameters
  # key<Sting>:: The key identifying the cache entry
  # data<String>:: The data to be put in cache
  # from_now<~minutes>::
  #   The number of minutes (from now) the cache should persist
  def cache_set(key, data, from_now = nil)
    _expire = from_now ? from_now.minutes.from_now.to_i : 0
    @memcache.set(key, data, _expire)
    cache_start_tracking(key)
    Merb.logger.info!("cache: set (#{key})")
    true
  end

  # Fetch data from memcache using the specified key
  # The entry is deleted if it has expired
  #
  # ==== Parameter
  # key<Sting>:: The key identifying the cache entry
  #
  # ==== Returns
  # data<String, NilClass>::
  #   nil is returned whether the entry expired or was not found
  def cache_get(key)
    data = @memcache.get(key)
    Merb.logger.info!("cache: #{data.nil? ? "miss" : "hit"} (#{key})")
    data
  end

  # Expire the cache entry identified by the given key
  #
  # ==== Parameter
  # key<Sting>:: The key identifying the cache entry
  def expire(key)
    @memcache.delete(key)
    cache_stop_tracking(key)
    Merb.logger.info!("cache: expired (#{key})")
    true
  end

  # Expire the cache entries matching the given key
  #
  # ==== Parameter
  # key<Sting>:: The key matching the cache entries
  #
  # ==== Additional info
  #   In memcache this requires to keep track of all keys (on by default).
  #   If you don't need this, set :no_tracking => true in the config.
  def expire_match(key)
    Merb.logger.debug!("cache: attempting to expire #{key}")
    if @tracking_key
      for _key in get_tracked_keys
        expire(_key) if /#{key}/ =~ _key
      end<commit_msg>less noise for cache hits, only get them in debug mode<commit_after>class Merb::Cache::MemcacheStore
  # Provides the memcache cache store for merb-cache

  def initialize
    @config = Merb::Controller._cache.config
    prepare
  end

  class NotReady < Exception
    def initialize
      super("Memcache server is not ready")
    end
  end

  class NotDefined < Exception
    def initialize
      super("Memcache is not defined (require it in init.rb)")
    end
  end

  # This method is there to ensure minimal requirements are met
  # (directories are accessible, table exists, connected to server, ...)
  def prepare
    namespace = @config[:namespace] || 'merb-cache'
    host = @config[:host] || '127.0.0.1:11211'
    @memcache = MemCache.new(host, {:namespace => namespace})
    @tracking_key = "_#{namespace}_keys" unless @config[:no_tracking] == true
    raise NotReady unless @memcache.active?
    true
  rescue NameError
    raise NotDefined
  end

  # Checks whether a cache entry exists
  #
  # ==== Parameter
  # key<String>:: The key identifying the cache entry
  #
  # ==== Returns
  # true if the cache entry exists, false otherwise
  def cached?(key)
    not cache_get(key).nil?
  end

  # Capture or restore the data in cache.
  # If the cache entry expired or does not exist, the data are taken
  # from the execution of the block, marshalled and stored in cache.
  # Otherwise, the data are loaded from the cache and returned unmarshalled
  #
  # ==== Parameters
  # _controller<Merb::Controller>:: The instance of the current controller
  # key<String>:: The key identifying the cache entry
  # from_now<~minutes>::
  #   The number of minutes (from now) the cache should persist
  # &block:: The template to be used or not
  #
  # ==== Additional information
  # When fetching data (the cache entry exists and has not expired)
  # The data are loaded from the cache and returned unmarshalled.
  # Otherwise:
  # The controller is used to capture the rendered template (from the block).
  # It uses the capture_#{engine} and concat_#{engine} methods to do so.
  # The captured data are then marshalled and stored.
  def cache(_controller, key, from_now = nil, &block)
    _data = cache_get(key)
    if _data.nil?
      _data = _controller.send(:capture, &block)
      cache_set(key, _data, from_now)
    end
    _controller.send(:concat, _data, block.binding)
    true
  end

  # Store data to memcache using the specified key
  #
  # ==== Parameters
  # key<Sting>:: The key identifying the cache entry
  # data<String>:: The data to be put in cache
  # from_now<~minutes>::
  #   The number of minutes (from now) the cache should persist
  def cache_set(key, data, from_now = nil)
    _expire = from_now ? from_now.minutes.from_now.to_i : 0
    @memcache.set(key, data, _expire)
    cache_start_tracking(key)
    Merb.logger.info!("cache: set (#{key})")
    true
  end

  # Fetch data from memcache using the specified key
  # The entry is deleted if it has expired
  #
  # ==== Parameter
  # key<Sting>:: The key identifying the cache entry
  #
  # ==== Returns
  # data<String, NilClass>::
  #   nil is returned whether the entry expired or was not found
  def cache_get(key)
    data = @memcache.get(key)
    if data.nil?
      Merb.logger.info!("cache: miss (#{key})")
    else
      Merb.logger.debug!("cache: hit (#{key})")
    end
    data
  end

  # Expire the cache entry identified by the given key
  #
  # ==== Parameter
  # key<Sting>:: The key identifying the cache entry
  def expire(key)
    @memcache.delete(key)
    cache_stop_tracking(key)
    Merb.logger.info!("cache: expired (#{key})")
    true
  end

  # Expire the cache entries matching the given key
  #
  # ==== Parameter
  # key<Sting>:: The key matching the cache entries
  #
  # ==== Additional info
  #   In memcache this requires to keep track of all keys (on by default).
  #   If you don't need this, set :no_tracking => true in the config.
  def expire_match(key)
    Merb.logger.debug!("cache: attempting to expire #{key}")
    if @tracking_key
      for _key in get_tracked_keys
        expire(_key) if /#{key}/ =~ _key
      end
{'fraction_non_alphanumeric': 0.10134474327628362, 'fraction_numerical': 0.00293398533007335, 'mean_word_length': 3.278765690376569, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '3826978', 'n_tokens_mistral': 2534, 'n_tokens_neox': 2470, 'n_words': 924}