<commit_before>require 'memcached'

class ActiveSupport::Cache::Entry
  # In 3.0 all values returned from Rails.cache.read are frozen.
  # This makes sense for an in-memory store storing object references,
  # but for a marshalled store we should be able to modify things.
  # Starting with 3.2, values are not frozen anymore.
  def value_with_dup
    result = value_without_dup
    result.frozen? && result.duplicable? ? result.dup : result
  end
  alias_method_chain :value, :dup
end

module ActiveSupport
  module Cache
    class LibmemcachedStore < Store
      attr_reader :addresses

      DEFAULT_OPTIONS = {
        :distribution => :consistent_ketama,
        :binary_protocol => true
      }

      def initialize(*addresses)
        addresses.flatten!
        @options = addresses.extract_options!
        @addresses = addresses
        @cache = Memcached.new(@addresses, @options.reverse_merge(DEFAULT_OPTIONS))
      end

      def increment(key, amount = 1, options = nil)
        instrument(:increment, key, amount: amount) do
          @cache.incr(key, amount)
        end
      rescue Memcached::Error
        nil
      end

      def decrement(key, amount = 1, options = nil)
        instrument(:decrement, key, amount: amount) do
          @cache.decr(key, amount)
        end
      rescue Memcached::Error
        nil
      end

      def clear
        @cache.flush
      end

      def stats
        @cache.stats
      end

      protected

      def read_entry(key, options = nil)
        deserialize_entry(@cache.get(key, false))
      rescue Memcached::NotFound
        nil
      rescue Memcached::Error => e
        log_error(e)
        nil
      end
<commit_msg>Optimize read_multi to avoir multiple calls to Memcached server<commit_after>require 'memcached'

class ActiveSupport::Cache::Entry
  # In 3.0 all values returned from Rails.cache.read are frozen.
  # This makes sense for an in-memory store storing object references,
  # but for a marshalled store we should be able to modify things.
  # Starting with 3.2, values are not frozen anymore.
  def value_with_dup
    result = value_without_dup
    result.frozen? && result.duplicable? ? result.dup : result
  end
  alias_method_chain :value, :dup
end

module ActiveSupport
  module Cache
    class LibmemcachedStore < Store
      attr_reader :addresses

      DEFAULT_OPTIONS = {
        :distribution => :consistent_ketama,
        :binary_protocol => true
      }

      def initialize(*addresses)
        addresses.flatten!
        @options = addresses.extract_options!
        @addresses = addresses
        @cache = Memcached.new(@addresses, @options.reverse_merge(DEFAULT_OPTIONS))
      end

      def increment(key, amount = 1, options = nil)
        instrument(:increment, key, amount: amount) do
          @cache.incr(key, amount)
        end
      rescue Memcached::Error
        nil
      end

      def decrement(key, amount = 1, options = nil)
        instrument(:decrement, key, amount: amount) do
          @cache.decr(key, amount)
        end
      rescue Memcached::Error
        nil
      end

      #
      # Optimize read_multi to only make one call to memcached
      # server.
      #
      def read_multi(*names)
        options = names.extract_options!
        options = merged_options(options)

        return {} if names.empty?

        keys_to_names = Hash[names.map {|name| [namespaced_key(name, options), name] }]
        raw_values = @cache.get(keys_to_names.keys, false)

        values = {}
        raw_values.each do |key, value|
          entry = deserialize_entry(value)
          values[keys_to_names[key]] = entry.value unless entry.expired?
        end
        values
      end

      def clear
        @cache.flush
      end

      def stats
        @cache.stats
      end

      protected

      def read_entry(key, options = nil)
        deserialize_entry(@cache.get(key, false))
      rescue Memcached::NotFound
        nil
      rescue Memcached::Error => e
        log_error(e)
        nil
      end

{'fraction_non_alphanumeric': 0.07967237527922562, 'fraction_numerical': 0.0029784065524944155, 'mean_word_length': 2.308702791461412, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '5146160', 'n_tokens_mistral': 1164, 'n_tokens_neox': 1135, 'n_words': 332}