Skip to content

Commit

Permalink
Update rules + add fast path for experimental bundle as well
Browse files Browse the repository at this point in the history
  • Loading branch information
remusao committed Jun 6, 2019
1 parent 7a7f1f7 commit e2555ba
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 118 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

### Not Released

### 5.1.0

*2019-06-06*

- [#164](https://github.com/remusao/tldts/pull/164) Update rules + add fast path for experimental bundle as well

### 5.0.3

*2019-05-29*
Expand Down
93 changes: 50 additions & 43 deletions bench/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const chalk = require('chalk');
const { URL } = require('url');
const fs = require('fs');
const path = require('path');
const tldts = require('..');
const tldtsDefault = require('../dist/tldts.cjs.min.js');
const tldtsExperimental = require('../dist/tldts-experimental.cjs.min.js');

function main() {
const urls = Array.from(
Expand Down Expand Up @@ -31,52 +32,58 @@ function main() {
.run({ async: false });
}

for (const method of [
'parse',
'getHostname',
'getPublicSuffix',
'getDomain',
'getSubdomain',
]) {
console.log(`= ${chalk.bold(method)}`);
const fn = tldts[method];

for (const options of [
undefined, // defaults
{ validateHostname: false },
{ validateHostname: false, detectIp: false, mixedInputs: false },
function run(bundleName, tldts) {
console.log(bundleName);
for (const method of [
'parse',
'getHostname',
'getPublicSuffix',
'getDomain',
'getSubdomain',
]) {
bench(
`#${chalk.bold(method)}(url, ${chalk.underline(
JSON.stringify(options),
)})`,
urls,
urls => {
for (let i = 0; i < urls.length; i += 1) {
fn(urls[i], options);
}
},
);
}
console.log(`= ${chalk.bold(method)}`);
const fn = tldts[method];

for (const options of [
undefined, // defaults
{ validateHostname: false },
{ validateHostname: false, detectIp: false, extractHostname: false },
]) {
bench(
`#${chalk.bold(method)}(hostname, ${chalk.underline(
JSON.stringify(options),
)})`,
hostnames,
hostnames => {
for (let i = 0; i < hostnames.length; i += 1) {
fn(hostnames[i], options);
}
},
);
for (const options of [
undefined, // defaults
{ validateHostname: false },
{ validateHostname: false, detectIp: false, mixedInputs: false },
]) {
bench(
`#${chalk.bold(method)}(url, ${chalk.underline(
JSON.stringify(options),
)})`,
urls,
urls => {
for (let i = 0; i < urls.length; i += 1) {
fn(urls[i], options);
}
},
);
}

for (const options of [
undefined, // defaults
{ validateHostname: false },
{ validateHostname: false, detectIp: false, extractHostname: false },
]) {
bench(
`#${chalk.bold(method)}(hostname, ${chalk.underline(
JSON.stringify(options),
)})`,
hostnames,
hostnames => {
for (let i = 0; i < hostnames.length; i += 1) {
fn(hostnames[i], options);
}
},
);
}
}
}

run('tldts-experimental', tldtsExperimental);
run('tldts', tldtsDefault);
}

main();
2 changes: 1 addition & 1 deletion lib/lookup/data/hashes.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/lookup/data/trie.ts

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions lib/lookup/fast-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { IPublicSuffix, ISuffixLookupOptions } from './interface';

export default function(
hostname: string,
options: ISuffixLookupOptions,
out: IPublicSuffix,
): boolean {
// Fast path for very popular suffixes; this allows to by-pass lookup
// completely as well as any extra allocation or string manipulation.
if (options.allowPrivateDomains === false && hostname.length > 3) {
const last: number = hostname.length - 1;
const c3: number = hostname.charCodeAt(last);
const c2: number = hostname.charCodeAt(last - 1);
const c1: number = hostname.charCodeAt(last - 2);
const c0: number = hostname.charCodeAt(last - 3);

if (
c3 === 109 /* 'm' */ &&
c2 === 111 /* 'o' */ &&
c1 === 99 /* 'c' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'com';
return true;
} else if (
c3 === 103 /* 'g' */ &&
c2 === 114 /* 'r' */ &&
c1 === 111 /* 'o' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'org';
return true;
} else if (
c3 === 117 /* 'u' */ &&
c2 === 100 /* 'd' */ &&
c1 === 101 /* 'e' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'edu';
return true;
} else if (
c3 === 118 /* 'v' */ &&
c2 === 111 /* 'o' */ &&
c1 === 103 /* 'g' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'gov';
return true;
} else if (
c3 === 116 /* 't' */ &&
c2 === 101 /* 'e' */ &&
c1 === 110 /* 'n' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'net';
return true;
} else if (
c3 === 101 /* 'e' */ &&
c2 === 100 /* 'd' */ &&
c1 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'de';
return true;
}
}

return false;
}
9 changes: 8 additions & 1 deletion lib/lookup/packed-hashes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import packed from './data/hashes';
import fastPathLookup from './fast-path';
import { IPublicSuffix, ISuffixLookupOptions } from './interface';

/**
Expand Down Expand Up @@ -100,9 +101,15 @@ const enum Result {
*/
export default function suffixLookup(
hostname: string,
{ allowIcannDomains, allowPrivateDomains }: ISuffixLookupOptions,
options: ISuffixLookupOptions,
out: IPublicSuffix,
): void {
if (fastPathLookup(hostname, options, out) === true) {
return;
}

const { allowIcannDomains, allowPrivateDomains } = options;

// Keep track of longest match
let matchIndex = -1;
let matchKind = Result.NO_MATCH;
Expand Down
72 changes: 3 additions & 69 deletions lib/lookup/suffix-trie.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { exceptions, ITrie, rules } from './data/trie';
import fastPathLookup from './fast-path';
import { IPublicSuffix, ISuffixLookupOptions } from './interface';

// Flags used to know if a rule is ICANN or Private
Expand Down Expand Up @@ -57,75 +58,8 @@ export default function suffixLookup(
options: ISuffixLookupOptions,
out: IPublicSuffix,
): void {
// Fast path for very popular suffixes; this allows to by-pass lookup
// completely as well as any extra allocation or string manipulation.
if (options.allowPrivateDomains === false && hostname.length > 3) {
const last: number = hostname.length - 1;
const c3: number = hostname.charCodeAt(last);
const c2: number = hostname.charCodeAt(last - 1);
const c1: number = hostname.charCodeAt(last - 2);
const c0: number = hostname.charCodeAt(last - 3);

if (
c3 === 109 /* 'm' */ &&
c2 === 111 /* 'o' */ &&
c1 === 99 /* 'c' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'com';
return;
} else if (
c3 === 103 /* 'g' */ &&
c2 === 114 /* 'r' */ &&
c1 === 111 /* 'o' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'org';
return;
} else if (
c3 === 117 /* 'u' */ &&
c2 === 100 /* 'd' */ &&
c1 === 101 /* 'e' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'edu';
return;
} else if (
c3 === 118 /* 'v' */ &&
c2 === 111 /* 'o' */ &&
c1 === 103 /* 'g' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'gov';
return;
} else if (
c3 === 116 /* 't' */ &&
c2 === 101 /* 'e' */ &&
c1 === 110 /* 'n' */ &&
c0 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'net';
return;
} else if (
c3 === 101 /* 'e' */ &&
c2 === 100 /* 'd' */ &&
c1 === 46 /* '.' */
) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'de';
return;
}
if (fastPathLookup(hostname, options, out) === true) {
return;
}

const hostnameParts = hostname.split('.');
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "tldts",
"description": "Library to work against complex domain names, subdomains and URIs.",
"version": "5.0.3",
"version": "5.1.0",
"homepage": "https://github.com/remusao/tldts",
"author": "Rémi Berson",
"contributors": [
Expand Down
2 changes: 1 addition & 1 deletion publicsuffix

0 comments on commit e2555ba

Please sign in to comment.