ソースを参照

Perf: domainset class w/o build domain map

SukkaW 1 年間 前
コミット
a42d28195d
3 ファイル変更31 行追加25 行削除
  1. 14 10
      Build/lib/rules/domainset.ts
  2. 4 2
      Build/lib/stable-sort-domain.ts
  3. 13 13
      Build/lib/trie.ts

+ 14 - 10
Build/lib/rules/domainset.ts

@@ -1,9 +1,12 @@
 import { invariant } from 'foxact/invariant';
 import createKeywordFilter from '../aho-corasick';
-import { buildParseDomainMap, sortDomains } from '../stable-sort-domain';
+import { sortDomains } from '../stable-sort-domain';
 import { RuleOutput } from './base';
 import type { SingboxSourceFormat } from '../singbox';
 
+import * as tldts from 'tldts-experimental';
+import { looseTldtsOpt } from '../../constants/loose-tldts-opt';
+
 type Preprocessed = string[];
 
 export class DomainsetOutput extends RuleOutput<Preprocessed> {
@@ -58,18 +61,19 @@ export class DomainsetOutput extends RuleOutput<Preprocessed> {
   }
 
   protected apexDomainMap: Map<string, string> | null = null;
-  protected subDomainMap: Map<string, string> | null = null;
-  withDomainMap(apexDomainMap: Map<string, string>, subDomainMap: Map<string, string>) {
-    this.apexDomainMap = apexDomainMap;
-    this.subDomainMap = subDomainMap;
-    return this;
-  }
-
   getStatMap() {
     invariant(this.$preprocessed, 'Non dumped yet');
 
-    if (!this.apexDomainMap || !this.subDomainMap) {
-      const { domainMap } = buildParseDomainMap(this.$preprocessed);
+    if (!this.apexDomainMap) {
+      const domainMap = new Map<string, string>();
+
+      for (let i = 0, len = this.$preprocessed.length; i < len; i++) {
+        const cur = this.$preprocessed[i];
+        if (!domainMap.has(cur)) {
+          const domain = tldts.getDomain(cur, looseTldtsOpt);
+          domainMap.set(cur, domain ?? cur);
+        }
+      }
       this.apexDomainMap = domainMap;
     }
 

+ 4 - 2
Build/lib/stable-sort-domain.ts

@@ -26,9 +26,11 @@ export function buildParseDomainMap(inputs: string[]) {
   return { domainMap, subdomainMap };
 }
 
-export function sortDomains(inputs: string[],
+export function sortDomains(
+  inputs: string[],
   domainMap?: Map<string, string> | null,
-  subdomainMap?: Map<string, string> | null) {
+  subdomainMap?: Map<string, string> | null
+) {
   if (!domainMap || !subdomainMap) {
     const { domainMap: dm, subdomainMap: sm } = buildParseDomainMap(inputs);
     domainMap = dm;

+ 13 - 13
Build/lib/trie.ts

@@ -9,7 +9,7 @@ import FIFO from './fifo';
 
 type TrieNode<Meta = any> = [
   boolean, /** end */
-  boolean, /** includeAllSubdoain (.example.org, ||example.com) */
+  boolean, /** includeAllSubdomain (.example.org, ||example.com) */
   TrieNode | null, /** parent */
   Map<string, TrieNode>, /** children */
   Meta /** meta */
@@ -103,7 +103,7 @@ abstract class Triebase<Meta = any> {
     }
   }
 
-  public abstract add(suffix: string, includeAllSubdoain?: boolean, meta?: Meta): void;
+  public abstract add(suffix: string, includeAllSubdomain?: boolean, meta?: Meta): void;
 
   protected walkIntoLeafWithTokens(
     tokens: string[],
@@ -167,13 +167,13 @@ abstract class Triebase<Meta = any> {
     return { node, parent };
   };
 
-  public contains(suffix: string, includeAllSubdoain = suffix[0] === '.'): boolean {
+  public contains(suffix: string, includeAllSubdomain = suffix[0] === '.'): boolean {
     if (suffix[0] === '.') {
       suffix = suffix.slice(1);
     }
     const res = this.walkIntoLeafWithSuffix(suffix);
     if (!res) return false;
-    if (includeAllSubdoain) return res.node[1];
+    if (includeAllSubdomain) return res.node[1];
     return true;
   };
 
@@ -390,7 +390,7 @@ abstract class Triebase<Meta = any> {
   /**
    * Method used to assert whether the given prefix exists in the Trie.
    */
-  public has(suffix: string, includeAllSubdoain = suffix[0] === '.'): boolean {
+  public has(suffix: string, includeAllSubdomain = suffix[0] === '.'): boolean {
     if (suffix[0] === '.') {
       suffix = suffix.slice(1);
     }
@@ -399,7 +399,7 @@ abstract class Triebase<Meta = any> {
 
     if (res === null) return false;
     if (!res.node[0]) return false;
-    if (includeAllSubdoain) return res.node[1];
+    if (includeAllSubdomain) return res.node[1];
     return true;
   };
 
@@ -484,7 +484,7 @@ abstract class Triebase<Meta = any> {
 export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
   public smolTree = true;
 
-  add(suffix: string, includeAllSubdoain = suffix[0] === '.', meta?: Meta): void {
+  add(suffix: string, includeAllSubdomain = suffix[0] === '.', meta?: Meta): void {
     let node: TrieNode<Meta> = this.$root;
     let curNodeChildren: Map<string, TrieNode<Meta>> = node[3];
 
@@ -516,7 +516,7 @@ export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
     }
 
     // If we are in smolTree mode, we need to do something at the end of the loop
-    if (includeAllSubdoain) {
+    if (includeAllSubdomain) {
       // Trying to add `[.]sub.example.com` where there is already a `blog.sub.example.com` in the trie
 
       // Make sure parent `[start]sub.example.com` (without dot) is removed (SETINEL to false)
@@ -534,11 +534,11 @@ export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
     }
 
     node[0] = true;
-    node[1] = includeAllSubdoain;
+    node[1] = includeAllSubdomain;
     node[4] = meta!;
   }
 
-  public whitelist(suffix: string, includeAllSubdoain = suffix[0] === '.') {
+  public whitelist(suffix: string, includeAllSubdomain = suffix[0] === '.') {
     if (suffix[0] === '.') {
       suffix = suffix.slice(1);
     }
@@ -551,7 +551,7 @@ export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
     const { node, toPrune, tokenToPrune } = res;
 
     // Trying to whitelist `[start].sub.example.com` where there might already be a `[start]blog.sub.example.com` in the trie
-    if (includeAllSubdoain) {
+    if (includeAllSubdomain) {
       // If there is a `[start]sub.example.com` here, remove it
       node[0] = false;
       node[1] = false;
@@ -578,7 +578,7 @@ export class HostnameTrie<Meta = any> extends Triebase<Meta> {
     return this.$size;
   }
 
-  add(suffix: string, includeAllSubdoain = suffix[0] === '.', meta?: Meta): void {
+  add(suffix: string, includeAllSubdomain = suffix[0] === '.', meta?: Meta): void {
     let node: TrieNode<Meta> = this.$root;
 
     const onToken = (token: string) => {
@@ -609,7 +609,7 @@ export class HostnameTrie<Meta = any> extends Triebase<Meta> {
 
     this.$size++;
     node[0] = true;
-    node[1] = includeAllSubdoain;
+    node[1] = includeAllSubdomain;
     node[4] = meta!;
   }
 }