Improvements

This commit is contained in:
jason5ng32 committed 2026-10-05 15:06:00 +08:00
1 parent bbcc53c518
commit d8426e6017
2 files changed
+16 -16

No files matched your search

+7 -8
View File
@@ -188,8 +188,9 @@ export const normalizePrefixOrigins = (result) => {
};
const GEO_TOP = 50; // countries in the response
const GEO_PREFIX_CAP = 20000; // bound on prefixes considered per request
const GEO_LOOKUP_BUDGET = 100000; // hard cap on MaxMind lookups per request (~0.3 s)
// Hard cap on MaxMind lookups per request (~0.3 s). Every uncovered prefix
// costs at least one, so this bounds the walk however many Radar returns.
const GEO_LOOKUP_BUDGET = 100000;
// Share of the ASN's announced IPv4 addresses per geolocated country, largest
// first. v4-only and address-weighted (a /16 counts 256× a /24); prefixes
@@ -200,16 +201,14 @@ const GEO_LOOKUP_BUDGET = 100000; // hard cap on MaxMind lookups per request (~0
// `lookupRange(ip) → { country, prefixLength } | null` is injected so tests
// need no MaxMind database; null = no answer (no database, or the lookup
// failed), unlike an address MaxMind places nowhere ({ country: null }).
// Resolves { shares, complete }: more IPv4 prefixes than the cap, a null
// answer or the budget ending the walk gives { shares: [], complete: false } — shares over part of the space
// Resolves { shares, complete }: a null answer or the budget ending the walk
// gives { shares: [], complete: false } — shares over part of the space
// would read as the whole distribution — and the caller must not cache it.
// Exported for tests.
export const buildCountryShares = (prefixes, lookupRange) => {
const v4 = (prefixes || [])
const blocks = (prefixes || [])
.map((row) => parseCidr(row?.prefix))
.filter((cidr) => cidr?.family === 4);
if (v4.length > GEO_PREFIX_CAP) return { shares: [], complete: false };
const blocks = v4
.filter((cidr) => cidr?.family === 4)
.map((cidr) => ({ start: cidr.network, size: 2n ** BigInt(32 - cidr.prefix) }))
.sort((a, b) => (a.start === b.start ? Number(b.size - a.size) : (a.start < b.start ? -1 : 1)));
+9 -8
View File
@@ -432,15 +432,16 @@ describe('buildCountryShares', () => {
assert.deepEqual(result, { shares: [], complete: false });
});
it('more IPv4 prefixes than the cap is incomplete, with no lookups', () => {
// 20001 distinct /24s under 10.0.0.0/8.
const many = Array.from({ length: 20001 }, (_, i) => ({ prefix: `10.${i >> 8}.${i & 255}.0/24` }));
it('bounds the walk by lookups, not by how many prefixes Radar returns', () => {
// 30000 /24s under 10.0.0.0/8 (one per 256 addresses).
const specifics = Array.from({ length: 30000 }, (_, i) => ({ prefix: `10.${i >> 8}.${i & 255}.0/24` }));
// Under a covering /8 they are skipped: one lookup, complete.
let calls = 0;
const result = buildCountryShares(many, () => { calls++; return { country: 'US', prefixLength: 24 }; });
assert.deepEqual(result, { shares: [], complete: false });
assert.equal(calls, 0);
// At the cap the walk still runs.
assert.equal(buildCountryShares(many.slice(0, 20000), () => ({ country: 'US', prefixLength: 24 })).complete, true);
const wide = () => { calls++; return { country: 'US', prefixLength: 8 }; };
assert.deepEqual(shares([{ prefix: '10.0.0.0/8' }, ...specifics], wide), [{ country: 'US', share: 1 }]);
assert.equal(calls, 1);
// Uncovered, each costs a lookup; well within the budget, complete.
assert.equal(buildCountryShares(specifics, () => ({ country: 'US', prefixLength: 24 })).complete, true);
});
it('a lookup without an answer (no database, failed lookup) is incomplete, not "no countries"', () => {