Skip to content

Instantly share code, notes, and snippets.

@Colkadome
Last active February 25, 2019 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Colkadome/7cd3c8111ba13f804908dcb6d06d2dab to your computer and use it in GitHub Desktop.
Save Colkadome/7cd3c8111ba13f804908dcb6d06d2dab to your computer and use it in GitHub Desktop.
/*
Node.js script to shrink the moment-timezone data file.
Works by replacing chunks in the 'indices' data, and numbers in the 'untils' data, with indexes.
Shrinks the latest data file from 903K to 377K.
*/
const fs = require('fs');
const largeFile = require('latest.json');
// String size when indexing 'indices'.
const I_LEN = 32;
// Get all 'untils' and 'incides' values, sorted by number of occurrences.
const uCounts = new Map();
const iCounts = new Map();
for (let i = 0; i < largeFile.zones.length; i++) {
const arr = largeFile.zones[i].split('|');
// Indices.
if (arr[3]) {
const indices = arr[3];
for (let i = 0; i < indices.length; i += I_LEN) {
const str = indices.substr(i, I_LEN);
iCounts.set(str, (uCounts.get(str) || 0) + 1);
}
}
// Untils.
if (arr[4]) {
const untils = arr[4].split(' ');
for (let u of untils) {
uCounts.set(u, (uCounts.get(u) || 0) + 1);
}
}
}
const uArr = [...uCounts.entries()].sort((a, b) => b[1] - a[1]).map(a => a[0]);
const iArr = [...iCounts.entries()].sort((a, b) => b[1] - a[1]).map(a => a[0]);
largeFile._z = uArr.join(' ');
largeFile._i = iArr.join(' ');
// Iterate through zones and replace 'untils' and 'indices' with base36 indexes
// pointing to the 'uArr' and 'iArr' respectively.
const uMap = new Map(uArr.map((str, i) => [str, i]));
const iMap = new Map(iArr.map((str, i) => [str, i]));
for (let i = 0; i < largeFile.zones.length; i++) {
const arr = largeFile.zones[i].split('|');
// Indices.
if (arr[3]) {
let iArr = [];
const indices = arr[3];
for (let i = 0; i < indices.length; i += I_LEN) {
const str = indices.substr(i, I_LEN);
iArr.push(iMap.get(str).toString(36));
}
arr[3] = iArr.join(' ');
}
// Untils.
if (arr[4]) {
const untils = arr[4].split(' ');
for (let i = 0; i < untils.length; i++) {
untils[i] = uMap.get(untils[i]).toString(36);
}
arr[4] = untils.join(' ');
}
largeFile.zones[i] = arr.join('|');
}
fs.writeFileSync('./latest.json', JSON.stringify(largeFile, null, 2));
/*
Example of how to decode the output.
*/
function decode(data) {
const zArr = data._z.split(' ');
const iArr = data._i.split(' ');
for (let i = 0; i < data.zones.length; i++) {
const arr = data.zones[i].split('|');
if (arr[3]) {
arr[3] = arr[3].split(' ').map(a => iArr[parseInt(a, 36)]).join('');
}
if (arr[4]) {
arr[4] = arr[4].split(' ').map(a => zArr[parseInt(a, 36)]).join(' ');
}
data.zones[i] = arr.join('|');
}
delete data._i;
delete data._z;
return data;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment