mirror of
https://github.com/SukkaW/Surge.git
synced 2026-01-29 01:51:52 +08:00
Prefer TimSort
This commit is contained in:
@@ -4,6 +4,7 @@ import { surgeDomainsetToClashDomainset, surgeRulesetToClashClassicalTextRuleset
|
||||
import picocolors from 'picocolors';
|
||||
import type { Span } from '../trace';
|
||||
import path from 'path';
|
||||
import { sort } from './timsort';
|
||||
|
||||
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {
|
||||
let isEqual = true;
|
||||
@@ -122,33 +123,35 @@ const sortTypeOrder: Record<string | typeof defaultSortTypeOrder, number> = {
|
||||
'IP-CIDR6': 400
|
||||
};
|
||||
// sort DOMAIN-SUFFIX and DOMAIN first, then DOMAIN-KEYWORD, then IP-CIDR and IP-CIDR6 if any
|
||||
export const sortRuleSet = (ruleSet: string[]) => ruleSet
|
||||
.map((rule) => {
|
||||
const type = collectType(rule);
|
||||
if (!type) {
|
||||
return [10, rule] as const;
|
||||
}
|
||||
if (!(type in sortTypeOrder)) {
|
||||
return [sortTypeOrder[defaultSortTypeOrder], rule] as const;
|
||||
}
|
||||
if (type === 'URL-REGEX') {
|
||||
let extraWeight = 0;
|
||||
if (rule.includes('.+') || rule.includes('.*')) {
|
||||
extraWeight += 10;
|
||||
export const sortRuleSet = (ruleSet: string[]) => {
|
||||
return sort(
|
||||
ruleSet.map((rule) => {
|
||||
const type = collectType(rule);
|
||||
if (!type) {
|
||||
return [10, rule] as const;
|
||||
}
|
||||
if (rule.includes('|')) {
|
||||
extraWeight += 1;
|
||||
if (!(type in sortTypeOrder)) {
|
||||
return [sortTypeOrder[defaultSortTypeOrder], rule] as const;
|
||||
}
|
||||
if (type === 'URL-REGEX') {
|
||||
let extraWeight = 0;
|
||||
if (rule.includes('.+') || rule.includes('.*')) {
|
||||
extraWeight += 10;
|
||||
}
|
||||
if (rule.includes('|')) {
|
||||
extraWeight += 1;
|
||||
}
|
||||
|
||||
return [
|
||||
sortTypeOrder[type] + extraWeight,
|
||||
rule
|
||||
] as const;
|
||||
}
|
||||
return [sortTypeOrder[type], rule] as const;
|
||||
})
|
||||
.sort((a, b) => a[0] - b[0])
|
||||
.map(c => c[1]);
|
||||
return [
|
||||
sortTypeOrder[type] + extraWeight,
|
||||
rule
|
||||
] as const;
|
||||
}
|
||||
return [sortTypeOrder[type], rule] as const;
|
||||
}),
|
||||
(a, b) => a[0] - b[0]
|
||||
).map(c => c[1]);
|
||||
};
|
||||
|
||||
const MARK = 'this_ruleset_is_made_by_sukkaw.ruleset.skk.moe';
|
||||
|
||||
|
||||
@@ -895,7 +895,7 @@ class TimSort<T> {
|
||||
* @param hi - Last element in the range.
|
||||
* comparator.
|
||||
*/
|
||||
export function sort<T>(array: T[], compare: Comparator<T> | undefined = alphabeticalCompare, lo = 0, hi: number = array.length) {
|
||||
export function sort<T>(array: T[], compare: Comparator<T> | undefined = alphabeticalCompare, lo = 0, hi: number = array.length): T[] {
|
||||
// if (!Array.isArray(array)) {
|
||||
// throw new TypeError('Can only sort arrays');
|
||||
// }
|
||||
@@ -914,7 +914,7 @@ export function sort<T>(array: T[], compare: Comparator<T> | undefined = alphabe
|
||||
|
||||
// The array is already sorted
|
||||
if (remaining < 2) {
|
||||
return;
|
||||
return array;
|
||||
}
|
||||
|
||||
let runLength = 0;
|
||||
@@ -922,7 +922,7 @@ export function sort<T>(array: T[], compare: Comparator<T> | undefined = alphabe
|
||||
if (remaining < DEFAULT_MIN_MERGE) {
|
||||
runLength = makeAscendingRun(array, lo, hi, compare);
|
||||
binaryInsertionSort(array, lo, hi, lo + runLength, compare);
|
||||
return;
|
||||
return array;
|
||||
}
|
||||
|
||||
const ts = new TimSort(array, compare);
|
||||
@@ -951,4 +951,6 @@ export function sort<T>(array: T[], compare: Comparator<T> | undefined = alphabe
|
||||
|
||||
// Force merging of remaining runs
|
||||
ts.forceMergeRuns();
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user