Optimize map { ... }.compact calls (#15513)
* Optimize map { ... }.compact
using Enumerable#filter_map, supported since Ruby 2.7
* Add poyfill for Enumerable#filter_map
	
	
This commit is contained in:
		
					parent
					
						
							
								9395143126
							
						
					
				
			
			
				commit
				
					
						087ed84367
					
				
			
		
					 22 changed files with 52 additions and 26 deletions
				
			
		|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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] | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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? } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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? | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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] || {}) | ||||
|  |  | |||
|  | @ -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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -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? | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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! | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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@/, '')) | ||||
|  |  | |||
|  | @ -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
									
								
								lib/enumerable.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								lib/enumerable.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
|  | @ -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? | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue