From 98b9e15502aa831bee45b648ef9009ba9a76299e Mon Sep 17 00:00:00 2001 From: Wu Tingfeng Date: Sun, 29 Oct 2023 11:18:39 +0800 Subject: [PATCH 1/2] Optimise select() for long subdomains --- lib/public_suffix/list.rb | 7 ++++++- test/unit/public_suffix_test.rb | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/public_suffix/list.rb b/lib/public_suffix/list.rb index 4bb4f1bd..48840dad 100644 --- a/lib/public_suffix/list.rb +++ b/lib/public_suffix/list.rb @@ -105,6 +105,7 @@ def self.parse(input, private_domains: true) # @yieldparam [PublicSuffix::List] self The newly created instance. def initialize @rules = {} + @max_rule_size = 0 yield(self) if block_given? end @@ -140,6 +141,7 @@ def each(&block) # @return [self] def add(rule) @rules[rule.value] = rule_to_entry(rule) + @max_rule_size = [@max_rule_size, (rule.value.count DOT) + 1].max self end alias << add @@ -163,6 +165,7 @@ def empty? # @return [self] def clear @rules.clear + @max_rule_size = 0 self end @@ -204,12 +207,14 @@ def select(name, ignore_private: false) query = parts[index] rules = [] + limit = [parts.size, @max_rule_size].min + loop do match = @rules[query] rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false) index += 1 - break if index >= parts.size + break if index >= limit query = parts[index] + DOT + query end diff --git a/test/unit/public_suffix_test.rb b/test/unit/public_suffix_test.rb index ba51e138..bbd1c87a 100644 --- a/test/unit/public_suffix_test.rb +++ b/test/unit/public_suffix_test.rb @@ -7,6 +7,9 @@ class PublicSuffixTest < Minitest::Test def test_private_domains_enabled_by_default domain = PublicSuffix.parse("www.example.blogspot.com") assert_equal "blogspot.com", domain.tld + + domain = PublicSuffix.parse("example.s3.cn-north-1.amazonaws.com.cn") + assert_equal "s3.cn-north-1.amazonaws.com.cn", domain.tld end def test_private_domains_disable From 2e38c475932afd9d61c4a889e697adb310ab378e Mon Sep 17 00:00:00 2001 From: Wu Tingfeng Date: Sun, 29 Oct 2023 15:59:05 +0800 Subject: [PATCH 2/2] Use faster bounded while loop instead of kernel loop --- lib/public_suffix/list.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/public_suffix/list.rb b/lib/public_suffix/list.rb index 48840dad..cc33a887 100644 --- a/lib/public_suffix/list.rb +++ b/lib/public_suffix/list.rb @@ -209,14 +209,12 @@ def select(name, ignore_private: false) limit = [parts.size, @max_rule_size].min - loop do + while index < limit match = @rules[query] rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false) index += 1 - break if index >= limit - - query = parts[index] + DOT + query + query = parts[index] + DOT + query if index < limit end rules