<commit_before>class Tag < ActiveRecord::Base
  include MissionBased

  belongs_to :mission
  has_many :taggings, dependent: :destroy
  has_many :questions, through: :taggings
  attr_accessible :is_standard, :name, :standard_id

  before_save { |tag| tag.name.downcase! }
  after_save(:invalidate_cache)
  after_destroy(:invalidate_cache)

  MAX_SUGGESTIONS = 5 # The max number of suggestion matches to return
  MAX_NAME_LENGTH = 64

  # Returns an array of Tags matching the given mission and textual query.
  def self.suggestions(mission, query)
    # fetch all mission tags from the cache
    mission_id = mission ? mission.id : 'std'
    tags = Rails.cache.fetch("mission_tags/#{mission_id}", :expires_in => 2.minutes) do
      Tag.unscoped.for_mission(mission)
    end

    # Trim query to maximum length.
    query = query[0...MAX_NAME_LENGTH]

    # where("name like ?", "%#{params[:q]}%").select([:id, :name])

    # scan for tags matching query
    matches = []; exact_match = false
    for i in 0...tags.size
      # if we have a a partial match
      if tags[i].name && tags[i].name =~ /#{Regexp.escape(query)}/i
        # if also an exact match, set a flag and put it at the top
        if tags[i].name == query
          matches.unshift tags[i]
          exact_match = true
          # otherwise just insert at the end
        else
          matches << tags[i]
        end
      end
    end

    # trim results to max size (couldn't do this earlier b/c had to search whole list for exact match)
    matches = matches[0...MAX_SUGGESTIONS]

    # if there was no exact match, we append a 'new tag' placeholder
    unless exact_match
      matches << Tag.new(:name => query)
    end

    matches
  end

  private

    # invalidate the mission tag cache after save, destroy
    def invalidate_cache
      Rails.cache.delete("mission_tags/#{mission_id}")
    end
end<commit_msg>refactor suggestions method<commit_after>class Tag < ActiveRecord::Base
  include MissionBased

  belongs_to :mission
  has_many :taggings, dependent: :destroy
  has_many :questions, through: :taggings
  attr_accessible :is_standard, :name, :standard_id

  before_save { |tag| tag.name.downcase! }
  after_save(:invalidate_cache)
  after_destroy(:invalidate_cache)

  MAX_SUGGESTIONS = 5 # The max number of suggestion matches to return
  MAX_NAME_LENGTH = 64

  # Returns an array of Tags matching the given mission and textual query.
  def self.suggestions(mission, query)
    # fetch all mission tags from the cache
    mission_id = mission ? mission.id : 'std'
    tags = Rails.cache.fetch("mission_tags/#{mission_id}", :expires_in => 2.minutes) do
      Tag.unscoped.for_mission(mission)
    end

    # Trim query to maximum length.
    query = query[0...MAX_NAME_LENGTH]

    # where("name like ?", "%#{params[:q]}%").select([:id, :name])

    # scan for tags matching query
    matches = []; exact_match = false
    for i in 0...tags.size
      # if an exact match, set a flag and put it at the top
      if tags[i].name == query
        matches.unshift tags[i]
        exact_match = true
        # otherwise if partial match just insert at the end
      elsif tags[i].name && tags[i].name =~ /#{Regexp.escape(query)}/i
        matches << tags[i]
      end
    end

    # trim results to max size (couldn't do this earlier b/c had to search whole list for exact match)
    matches = matches[0...MAX_SUGGESTIONS]

    # if there was no exact match, we append a 'new tag' placeholder
    unless exact_match
      matches << Tag.new(:name => query)
    end

    matches
  end

  private

    # invalidate the mission tag cache after save, destroy
    def invalidate_cache
      Rails.cache.delete("mission_tags/#{mission_id}")
    end
end
{'fraction_non_alphanumeric': 0.09734513274336283, 'fraction_numerical': 0.0037543577366586215, 'mean_word_length': 2.9893048128342246, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, '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': '1020820', 'n_tokens_mistral': 1169, 'n_tokens_neox': 1120, 'n_words': 374}