Skip to content

Commit 293ab69

Browse files
authored
Shrink file size sorting (#75)
* fix(file-size): use exact multipliers for MiB, GiB, etc. * refactor(file-size): use table for byte->MiB conversion instead of ifs Shrink the code size a bit by using a table instead of repeating code. * fix(file-size): fix special case for Megabyte and first row For some reason, the removeUnitTypeConvertToBytes code was special cased for the first row. This forced a workaround for the Megabyte case. Fix removeUnitTypeConvertToBytes to not special case i==0 and remove the need for the Megabyte workarond. * refactor(file-size): inline helper table Shrink code size by inlining the 'fileSizes' helper table. * refactor(file-size): simplify: s.replace(s, r) -> r * refactor(file-size): simplify some regular expressions * refactor(file-size): extract number and unit from table cell once, not twice * refactor(file-size): simplify unit matching regexps * refactor(file-size): use simple string comparisons for unit matching * refactor(file-size): simplify removeUnitTypeConvertToBytes * refactor(file-size): use lookup table for unit-to-multiplier conversion * refactor(file-size): inline function
1 parent 1b8f42b commit 293ab69

File tree

3 files changed

+35
-96
lines changed

3 files changed

+35
-96
lines changed

public/table-sort.js

Lines changed: 33 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -88,59 +88,28 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
8888
}
8989

9090
function sortFileSize(tableRows, columnData) {
91-
const numberWithUnitType =
92-
/[.0-9]+(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|\s?GiB|T\s?B|\s?TiB)/i;
93-
const unitType =
94-
/(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|G\s?iB|\s?TB|\s?TiB)/i;
95-
const fileSizes = {
96-
Kibibyte: 1024,
97-
Mebibyte: 1.049e6,
98-
Gibibyte: 1.074e9,
99-
Tebibyte: 1.1e12,
100-
Pebibyte: 1.126e15,
101-
Kilobyte: 1000,
102-
Megabyte: 1e6,
103-
Gigabyte: 1e9,
104-
Terabyte: 1e12,
91+
let unitToMultiplier = {
92+
b: 1,
93+
kb: 1000,
94+
kib: 2 ** 10,
95+
mb: 1e6,
96+
mib: 2 ** 20,
97+
gb: 1e9,
98+
gib: 2 ** 30,
99+
tb: 1e12,
100+
tib: 2 ** 40,
105101
};
106-
function removeUnitTypeConvertToBytes(fileSizeTd, _replace, i) {
107-
fileSizeTd = fileSizeTd.replace(unitType, "");
108-
fileSizeTd = fileSizeTd.replace(
109-
fileSizeTd,
110-
fileSizeTd * fileSizes[_replace]
111-
);
112-
if (i) {
113-
columnData.push(`${fileSizeTd}#${i}`);
114-
}
115-
return fileSizeTd;
116-
}
102+
const numberWithUnitType = /([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
117103
for (let [i, tr] of tableRows.entries()) {
118104
let fileSizeTd = tr
119105
.querySelectorAll("td")
120106
.item(columnIndex).textContent;
121-
if (fileSizeTd.match(numberWithUnitType)) {
122-
if (fileSizeTd.match(/\s?KB/i)) {
123-
removeUnitTypeConvertToBytes(fileSizeTd, "Kilobyte", i);
124-
} else if (fileSizeTd.match(/\s?KiB/i)) {
125-
removeUnitTypeConvertToBytes(fileSizeTd, "Kibibyte", i);
126-
} else if (fileSizeTd.match(/\s?MB/i)) {
127-
// TODO: figure out why refactoring this line breaks test.
128-
fileSizeTd = removeUnitTypeConvertToBytes(fileSizeTd, "Megabyte");
129-
columnData.push(`${fileSizeTd}#${i}`);
130-
} else if (fileSizeTd.match(/\s?MiB/i)) {
131-
removeUnitTypeConvertToBytes(fileSizeTd, "Mebibyte", i);
132-
} else if (fileSizeTd.match(/\s?GB/i)) {
133-
removeUnitTypeConvertToBytes(fileSizeTd, "Gigabyte", i);
134-
} else if (fileSizeTd.match(/\s?GiB/i)) {
135-
removeUnitTypeConvertToBytes(fileSizeTd, "Gibibyte", i);
136-
} else if (fileSizeTd.match(/\s?TB/i)) {
137-
removeUnitTypeConvertToBytes(fileSizeTd, "Terabyte", i);
138-
} else if (fileSizeTd.match(/\s?TiB/i)) {
139-
removeUnitTypeConvertToBytes(fileSizeTd, "Tebibyte", i);
140-
} else if (fileSizeTd.match(/\s?B/i)) {
141-
fileSizeTd = fileSizeTd.replace(unitType, "");
142-
columnData.push(`${fileSizeTd}#${i}`);
143-
}
107+
let match = fileSizeTd.match(numberWithUnitType);
108+
if (match) {
109+
let number = parseFloat(match[1]);
110+
let unit = match[2].toLowerCase();
111+
let multiplier = unitToMultiplier[unit];
112+
columnData.push(`${number * multiplier}#${i}`);
144113
} else {
145114
columnData.push(`${fillValue}#${i}`);
146115
}
@@ -281,54 +250,24 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
281250
const fileSizeInBytesText = tr
282251
.querySelectorAll("td")
283252
.item(columnIndex).textContent;
284-
const fileSizes = {
285-
Kibibyte: 1024,
286-
Mebibyte: 1.049e6,
287-
Gibibyte: 1.074e9,
288-
Tebibyte: 1.1e12,
289-
Pebibyte: 1.126e15,
290-
};
291253
// Remove the unique identifyer for duplicate values(#number).
292254
columnData[i] = columnData[i].replace(/#[0-9]*/, "");
293-
const fileSize = columnData[i];
294-
if (fileSize < fileSizes.Kibibyte) {
295-
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
296-
fileSizeInBytesText,
297-
`${parseFloat(fileSize).toFixed(2)} B`
298-
);
299-
} else if (
300-
fileSize >= fileSizes.Kibibyte &&
301-
fileSize < fileSizes.Mebibyte
302-
) {
303-
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
304-
fileSizeInBytesText,
305-
`${(fileSize / fileSizes.Kibibyte).toFixed(2)} KiB`
306-
);
307-
} else if (
308-
fileSize >= fileSizes.Mebibyte &&
309-
fileSize < fileSizes.Gibibyte
310-
) {
311-
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
312-
fileSizeInBytesText,
313-
`${(fileSize / fileSizes.Mebibyte).toFixed(2)} MiB`
314-
);
315-
} else if (
316-
fileSize >= fileSizes.Gibibyte &&
317-
fileSize < fileSizes.Tebibyte
318-
) {
319-
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
320-
fileSizeInBytesText,
321-
`${(fileSize / fileSizes.Gibibyte).toFixed(2)} GiB`
322-
);
323-
} else if (
324-
fileSize >= fileSizes.Tebibyte &&
325-
fileSize < fileSizes.Pebibyte
326-
) {
327-
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
328-
fileSizeInBytesText,
329-
`${(fileSize / fileSizes.Tebibyte).toFixed(2)} TiB`
330-
);
331-
} else {
255+
const fileSize = parseFloat(columnData[i]);
256+
let prefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi"];
257+
let replaced = false;
258+
for (let i = 0; i < prefixes.length; ++i) {
259+
let nextPrefixMultiplier = 2 ** (10 * (i + 1));
260+
if (fileSize < nextPrefixMultiplier) {
261+
let prefixMultiplier = 2 ** (10 * i);
262+
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
263+
fileSizeInBytesText,
264+
`${(fileSize / prefixMultiplier).toFixed(2)} ${prefixes[i]}B`
265+
);
266+
replaced = true;
267+
break;
268+
}
269+
}
270+
if (!replaced) {
332271
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
333272
fileSizeInBytesText,
334273
"NaN"

test/order-by-desc.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ test("Order by file-size: file-size order-by-desc", () => {
9999
"10.00 GiB",
100100
"9.31 GiB",
101101
"10.00 MiB",
102-
"9.53 MiB",
102+
"9.54 MiB",
103103
"10.00 KiB",
104104
"9.77 KiB",
105105
"10.00 B",

test/table.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ test("Order by file-size: file-size", () => {
9595
"10.00 B",
9696
"9.77 KiB",
9797
"10.00 KiB",
98-
"9.53 MiB",
98+
"9.54 MiB",
9999
"10.00 MiB",
100100
"9.31 GiB",
101101
"10.00 GiB",

0 commit comments

Comments
 (0)