Last active
February 25, 2019 15:52
-
-
Save Colkadome/7cd3c8111ba13f804908dcb6d06d2dab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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