mirror of
https://github.com/SukkaW/Surge.git
synced 2025-12-12 17:20:35 +08:00
Perf: domainset class w/o build domain map
This commit is contained in:
parent
70a38fddcc
commit
a42d28195d
@ -1,9 +1,12 @@
|
|||||||
import { invariant } from 'foxact/invariant';
|
import { invariant } from 'foxact/invariant';
|
||||||
import createKeywordFilter from '../aho-corasick';
|
import createKeywordFilter from '../aho-corasick';
|
||||||
import { buildParseDomainMap, sortDomains } from '../stable-sort-domain';
|
import { sortDomains } from '../stable-sort-domain';
|
||||||
import { RuleOutput } from './base';
|
import { RuleOutput } from './base';
|
||||||
import type { SingboxSourceFormat } from '../singbox';
|
import type { SingboxSourceFormat } from '../singbox';
|
||||||
|
|
||||||
|
import * as tldts from 'tldts-experimental';
|
||||||
|
import { looseTldtsOpt } from '../../constants/loose-tldts-opt';
|
||||||
|
|
||||||
type Preprocessed = string[];
|
type Preprocessed = string[];
|
||||||
|
|
||||||
export class DomainsetOutput extends RuleOutput<Preprocessed> {
|
export class DomainsetOutput extends RuleOutput<Preprocessed> {
|
||||||
@ -58,18 +61,19 @@ export class DomainsetOutput extends RuleOutput<Preprocessed> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected apexDomainMap: Map<string, string> | null = null;
|
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() {
|
getStatMap() {
|
||||||
invariant(this.$preprocessed, 'Non dumped yet');
|
invariant(this.$preprocessed, 'Non dumped yet');
|
||||||
|
|
||||||
if (!this.apexDomainMap || !this.subDomainMap) {
|
if (!this.apexDomainMap) {
|
||||||
const { domainMap } = buildParseDomainMap(this.$preprocessed);
|
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;
|
this.apexDomainMap = domainMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,9 +26,11 @@ export function buildParseDomainMap(inputs: string[]) {
|
|||||||
return { domainMap, subdomainMap };
|
return { domainMap, subdomainMap };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sortDomains(inputs: string[],
|
export function sortDomains(
|
||||||
|
inputs: string[],
|
||||||
domainMap?: Map<string, string> | null,
|
domainMap?: Map<string, string> | null,
|
||||||
subdomainMap?: Map<string, string> | null) {
|
subdomainMap?: Map<string, string> | null
|
||||||
|
) {
|
||||||
if (!domainMap || !subdomainMap) {
|
if (!domainMap || !subdomainMap) {
|
||||||
const { domainMap: dm, subdomainMap: sm } = buildParseDomainMap(inputs);
|
const { domainMap: dm, subdomainMap: sm } = buildParseDomainMap(inputs);
|
||||||
domainMap = dm;
|
domainMap = dm;
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import FIFO from './fifo';
|
|||||||
|
|
||||||
type TrieNode<Meta = any> = [
|
type TrieNode<Meta = any> = [
|
||||||
boolean, /** end */
|
boolean, /** end */
|
||||||
boolean, /** includeAllSubdoain (.example.org, ||example.com) */
|
boolean, /** includeAllSubdomain (.example.org, ||example.com) */
|
||||||
TrieNode | null, /** parent */
|
TrieNode | null, /** parent */
|
||||||
Map<string, TrieNode>, /** children */
|
Map<string, TrieNode>, /** children */
|
||||||
Meta /** meta */
|
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(
|
protected walkIntoLeafWithTokens(
|
||||||
tokens: string[],
|
tokens: string[],
|
||||||
@ -167,13 +167,13 @@ abstract class Triebase<Meta = any> {
|
|||||||
return { node, parent };
|
return { node, parent };
|
||||||
};
|
};
|
||||||
|
|
||||||
public contains(suffix: string, includeAllSubdoain = suffix[0] === '.'): boolean {
|
public contains(suffix: string, includeAllSubdomain = suffix[0] === '.'): boolean {
|
||||||
if (suffix[0] === '.') {
|
if (suffix[0] === '.') {
|
||||||
suffix = suffix.slice(1);
|
suffix = suffix.slice(1);
|
||||||
}
|
}
|
||||||
const res = this.walkIntoLeafWithSuffix(suffix);
|
const res = this.walkIntoLeafWithSuffix(suffix);
|
||||||
if (!res) return false;
|
if (!res) return false;
|
||||||
if (includeAllSubdoain) return res.node[1];
|
if (includeAllSubdomain) return res.node[1];
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ abstract class Triebase<Meta = any> {
|
|||||||
/**
|
/**
|
||||||
* Method used to assert whether the given prefix exists in the Trie.
|
* 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] === '.') {
|
if (suffix[0] === '.') {
|
||||||
suffix = suffix.slice(1);
|
suffix = suffix.slice(1);
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ abstract class Triebase<Meta = any> {
|
|||||||
|
|
||||||
if (res === null) return false;
|
if (res === null) return false;
|
||||||
if (!res.node[0]) return false;
|
if (!res.node[0]) return false;
|
||||||
if (includeAllSubdoain) return res.node[1];
|
if (includeAllSubdomain) return res.node[1];
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -484,7 +484,7 @@ abstract class Triebase<Meta = any> {
|
|||||||
export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
|
export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
|
||||||
public smolTree = true;
|
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 node: TrieNode<Meta> = this.$root;
|
||||||
let curNodeChildren: Map<string, TrieNode<Meta>> = node[3];
|
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 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
|
// 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)
|
// 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[0] = true;
|
||||||
node[1] = includeAllSubdoain;
|
node[1] = includeAllSubdomain;
|
||||||
node[4] = meta!;
|
node[4] = meta!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public whitelist(suffix: string, includeAllSubdoain = suffix[0] === '.') {
|
public whitelist(suffix: string, includeAllSubdomain = suffix[0] === '.') {
|
||||||
if (suffix[0] === '.') {
|
if (suffix[0] === '.') {
|
||||||
suffix = suffix.slice(1);
|
suffix = suffix.slice(1);
|
||||||
}
|
}
|
||||||
@ -551,7 +551,7 @@ export class HostnameSmolTrie<Meta = any> extends Triebase<Meta> {
|
|||||||
const { node, toPrune, tokenToPrune } = res;
|
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
|
// 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
|
// If there is a `[start]sub.example.com` here, remove it
|
||||||
node[0] = false;
|
node[0] = false;
|
||||||
node[1] = false;
|
node[1] = false;
|
||||||
@ -578,7 +578,7 @@ export class HostnameTrie<Meta = any> extends Triebase<Meta> {
|
|||||||
return this.$size;
|
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;
|
let node: TrieNode<Meta> = this.$root;
|
||||||
|
|
||||||
const onToken = (token: string) => {
|
const onToken = (token: string) => {
|
||||||
@ -609,7 +609,7 @@ export class HostnameTrie<Meta = any> extends Triebase<Meta> {
|
|||||||
|
|
||||||
this.$size++;
|
this.$size++;
|
||||||
node[0] = true;
|
node[0] = true;
|
||||||
node[1] = includeAllSubdoain;
|
node[1] = includeAllSubdomain;
|
||||||
node[4] = meta!;
|
node[4] = meta!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user