Procházet zdrojové kódy

Optimize map { ... }.compact calls (#15513)

* Optimize map { ... }.compact

using Enumerable#filter_map, supported since Ruby 2.7

* Add poyfill for Enumerable#filter_map
luigi před 3 roky
rodič
revize
087ed84367

+ 1 - 1
app/controllers/api/v1/crypto/keys/claims_controller.rb

@@ -12,7 +12,7 @@ class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
   private
 
   def set_claim_results
-    @claim_results = devices.map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }.compact
+    @claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }
   end
 
   def resource_params

+ 1 - 1
app/controllers/api/v1/crypto/keys/queries_controller.rb

@@ -17,7 +17,7 @@ class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
   end
 
   def set_query_results
-    @query_results = @accounts.map { |account| ::Keys::QueryService.new.call(account) }.compact
+    @query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) }
   end
 
   def account_ids

+ 1 - 1
app/controllers/concerns/cache_concern.rb

@@ -45,7 +45,7 @@ module CacheConcern
       end
     end
 
-    raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
+    raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] }
   end
 
   def cache_collection_paginated_by_id(raw, klass, limit, options)

+ 2 - 2
app/lib/activitypub/activity/flag.rb

@@ -4,8 +4,8 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
   def perform
     return if skip_reports?
 
-    target_accounts            = object_uris.map { |uri| account_from_uri(uri) }.compact.select(&:local?)
-    target_statuses_by_account = object_uris.map { |uri| status_from_uri(uri) }.compact.select(&:local?).group_by(&:account_id)
+    target_accounts            = object_uris.filter_map { |uri| account_from_uri(uri) }.select(&:local?)
+    target_statuses_by_account = object_uris.filter_map { |uri| status_from_uri(uri) }.select(&:local?).group_by(&:account_id)
 
     target_accounts.each do |target_account|
       target_statuses = target_statuses_by_account[target_account.id]

+ 1 - 1
app/lib/entity_cache.rb

@@ -29,7 +29,7 @@ class EntityCache
       uncached.each_value { |item| Rails.cache.write(to_key(:emoji, item.shortcode, domain), item, expires_in: MAX_EXPIRATION) }
     end
 
-    shortcodes.map { |shortcode| cached[to_key(:emoji, shortcode, domain)] || uncached[shortcode] }.compact
+    shortcodes.filter_map { |shortcode| cached[to_key(:emoji, shortcode, domain)] || uncached[shortcode] }
   end
 
   def to_key(type, *ids)

+ 2 - 2
app/lib/spam_check.rb

@@ -186,9 +186,9 @@ class SpamCheck
 
   def matching_status_ids
     if nilsimsa?
-      other_digests.select { |record| record.start_with?('nilsimsa') && nilsimsa_compare_value(digest, record.split(':')[1]) >= NILSIMSA_COMPARE_THRESHOLD }.map { |record| record.split(':')[2] }.compact
+      other_digests.select { |record| record.start_with?('nilsimsa') && nilsimsa_compare_value(digest, record.split(':')[1]) >= NILSIMSA_COMPARE_THRESHOLD }.filter_map { |record| record.split(':')[2] }
     else
-      other_digests.select { |record| record.start_with?('md5') && record.split(':')[1] == digest }.map { |record| record.split(':')[2] }.compact
+      other_digests.select { |record| record.start_with?('md5') && record.split(':')[1] == digest }.filter_map { |record| record.split(':')[2] }
     end
   end
 

+ 2 - 2
app/models/account.rb

@@ -508,7 +508,7 @@ class Account < ApplicationRecord
     def from_text(text)
       return [] if text.blank?
 
-      text.scan(MENTION_RE).map { |match| match.first.split('@', 2) }.uniq.map do |(username, domain)|
+      text.scan(MENTION_RE).map { |match| match.first.split('@', 2) }.uniq.filter_map do |(username, domain)|
         domain = begin
           if TagManager.instance.local_domain?(domain)
             nil
@@ -517,7 +517,7 @@ class Account < ApplicationRecord
           end
         end
         EntityCache.instance.mention(username, domain)
-      end.compact
+      end
     end
 
     private

+ 1 - 1
app/models/concerns/status_threading_concern.rb

@@ -83,7 +83,7 @@ module StatusThreadingConcern
   def find_statuses_from_tree_path(ids, account, promote: false)
     statuses    = Status.with_accounts(ids).to_a
     account_ids = statuses.map(&:account_id).uniq
-    domains     = statuses.map(&:account_domain).compact.uniq
+    domains     = statuses.filter_map(&:account_domain).uniq
     relations   = relations_map_for_account(account, account_ids, domains)
 
     statuses.reject! { |status| StatusFilter.new(status, account, relations).filtered? }

+ 1 - 1
app/models/custom_filter.rb

@@ -46,7 +46,7 @@ class CustomFilter < ApplicationRecord
   private
 
   def clean_up_contexts
-    self.context = Array(context).map(&:strip).map(&:presence).compact
+    self.context = Array(context).map(&:strip).filter_map(&:presence)
   end
 
   def remove_cache

+ 1 - 1
app/models/notification.rb

@@ -92,7 +92,7 @@ class Notification < ApplicationRecord
     end
 
     def reload_stale_associations!(cached_items)
-      account_ids = (cached_items.map(&:from_account_id) + cached_items.map { |item| item.target_status&.account_id }.compact).uniq
+      account_ids = (cached_items.map(&:from_account_id) + cached_items.filter_map { |item| item.target_status&.account_id }).uniq
 
       return if account_ids.empty?
 

+ 2 - 2
app/models/status.rb

@@ -334,7 +334,7 @@ class Status < ApplicationRecord
     def from_text(text)
       return [] if text.blank?
 
-      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.map do |url|
+      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.filter_map do |url|
         status = begin
           if TagManager.instance.local_url?(url)
             ActivityPub::TagManager.instance.uri_to_resource(url, Status)
@@ -343,7 +343,7 @@ class Status < ApplicationRecord
           end
         end
         status&.distributable? ? status : nil
-      end.compact
+      end
     end
   end
 

+ 1 - 1
app/presenters/status_relationships_presenter.rb

@@ -14,7 +14,7 @@ class StatusRelationshipsPresenter
     else
       statuses            = statuses.compact
       status_ids          = statuses.flat_map { |s| [s.id, s.reblog_of_id] }.uniq.compact
-      conversation_ids    = statuses.map(&:conversation_id).compact.uniq
+      conversation_ids    = statuses.filter_map(&:conversation_id).uniq
       pinnable_status_ids = statuses.map(&:proper).select { |s| s.account_id == current_account_id && %w(public unlisted).include?(s.visibility) }.map(&:id)
 
       @reblogs_map     = Status.reblogs_map(status_ids, current_account_id).merge(options[:reblogs_map] || {})

+ 1 - 2
app/services/activitypub/fetch_featured_collection_service.rb

@@ -24,8 +24,7 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService
   def process_items(items)
     status_ids = items.map { |item| value_or_id(item) }
                       .reject { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
-                      .map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
-                      .compact
+                      .filter_map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
                       .select { |status| status.account_id == @account.id }
                       .map(&:id)
 

+ 1 - 1
app/services/activitypub/process_collection_service.rb

@@ -37,7 +37,7 @@ class ActivityPub::ProcessCollectionService < BaseService
   end
 
   def process_items(items)
-    items.reverse_each.map { |item| process_item(item) }.compact
+    items.reverse_each.filter_map { |item| process_item(item) }
   end
 
   def supported_context?

+ 1 - 1
app/services/activitypub/process_poll_service.rb

@@ -30,7 +30,7 @@ class ActivityPub::ProcessPollService < BaseService
 
     voters_count = @json['votersCount']
 
-    latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
+    latest_options = items.filter_map { |item| item['name'].presence || item['content'] }
 
     # If for some reasons the options were changed, it invalidates all previous
     # votes, so we need to remove them

+ 1 - 1
app/services/activitypub/synchronize_followers_service.rb

@@ -14,7 +14,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
     # should never happen in practice, since in almost all cases we keep an
     # Account record, and should we not do that, we should have sent a Delete.
     # In any case there is not much we can do if that occurs.
-    @expected_followers = items.map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }.compact
+    @expected_followers = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }
 
     remove_unexpected_local_followers!
     handle_unexpected_outgoing_follows!

+ 1 - 1
app/services/fetch_link_card_service.rb

@@ -67,7 +67,7 @@ class FetchLinkCardService < BaseService
     else
       html  = Nokogiri::HTML(@status.text)
       links = html.css('a')
-      urls  = links.map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.compact.map(&:normalize).compact
+      urls  = links.filter_map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.filter_map(&:normalize)
     end
 
     urls.reject { |uri| bad_url?(uri) }.first

+ 2 - 2
app/services/import_service.rb

@@ -107,12 +107,12 @@ class ImportService < BaseService
       end
     end
 
-    statuses = items.map do |uri|
+    statuses = items.filter_map do |uri|
       status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
       next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri)
 
       status || ActivityPub::FetchRemoteStatusService.new.call(uri)
-    end.compact
+    end
 
     account_ids         = statuses.map(&:account_id)
     preloaded_relations = relations_map_for_account(@account, account_ids)

+ 1 - 1
app/validators/existing_username_validator.rb

@@ -5,7 +5,7 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
     return if value.blank?
 
     if options[:multiple]
-      missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.map { |username| username unless Account.find_local(username) }.compact
+      missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.filter_map { |username| username unless Account.find_local(username) }
       record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: missing_usernames.join(', '))) if missing_usernames.any?
     else
       record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) unless Account.find_local(value.strip.gsub(/\A@/, ''))

+ 1 - 0
config/application.rb

@@ -7,6 +7,7 @@ require 'rails/all'
 Bundler.require(*Rails.groups)
 
 require_relative '../app/lib/exceptions'
+require_relative '../lib/enumerable'
 require_relative '../lib/redis/namespace_extensions'
 require_relative '../lib/paperclip/url_generator_extensions'
 require_relative '../lib/paperclip/attachment_extensions'

+ 26 - 0
lib/enumerable.rb

@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Enumerable
+  # TODO: Remove this once stop to support Ruby 2.6
+  if RUBY_VERSION < '2.7.0'
+    def filter_map
+      if block_given?
+        result = []
+        each do |element|
+          res = yield element
+          result << res if res
+        end
+        result
+      else
+        Enumerator.new do |yielder|
+          result = []
+          each do |element|
+            res = yielder.yield element
+            result << res if res
+          end
+          result
+        end
+      end
+    end
+  end
+end

+ 1 - 1
lib/paperclip/attachment_extensions.rb

@@ -27,7 +27,7 @@ module Paperclip
       return true  if original_filename == other_filename
       return false if original_filename.nil?
 
-      formats = styles.values.map(&:format).compact
+      formats = styles.values.filter_map(&:format)
 
       return false if formats.empty?