WebUI: avoid redundant operations when sorting

Avoid recomputing the same result on every sort operation.
Also clean up the caller site.

PR #22821.
This commit is contained in:
Chocobo1 2025-06-08 17:08:47 +08:00 committed by GitHub
parent 8e2125ee72
commit 4132173b30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -829,13 +829,11 @@ window.qBittorrent.DynamicTable ??= (() => {
filteredRows[row.rowId] = row;
}
const column = this.columns[this.sortedColumn];
const isReverseSort = (this.reverseSort === "0");
filteredRows.sort((row1, row2) => {
const column = this.columns[this.sortedColumn];
const res = column.compareRows(row1, row2);
if (this.reverseSort === "0")
return res;
else
return -res;
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
return filteredRows;
}
@ -1777,13 +1775,11 @@ window.qBittorrent.DynamicTable ??= (() => {
}
}
const column = this.columns[this.sortedColumn];
const isReverseSort = (this.reverseSort === "0");
filteredRows.sort((row1, row2) => {
const column = this.columns[this.sortedColumn];
const res = column.compareRows(row1, row2);
if (this.reverseSort === "0")
return res;
else
return -res;
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
return filteredRows;
}
@ -2037,13 +2033,11 @@ window.qBittorrent.DynamicTable ??= (() => {
filteredRows = [...this.getRowValues()];
}
const column = this.columns[this.sortedColumn];
const isReverseSort = (this.reverseSort === "0");
filteredRows.sort((row1, row2) => {
const column = this.columns[this.sortedColumn];
const res = column.compareRows(row1, row2);
if (this.reverseSort === "0")
return res;
else
return -res;
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
return filteredRows;
@ -2454,26 +2448,31 @@ window.qBittorrent.DynamicTable ??= (() => {
this.updateGlobalCheckbox();
}
#sortNodesByColumn(nodes, column) {
nodes.sort((row1, row2) => {
// list folders before files when sorting by name
if (column.name === "original") {
const node1 = this.getNode(row1.data.rowId);
const node2 = this.getNode(row2.data.rowId);
if (node1.isFolder && !node2.isFolder)
return -1;
if (node2.isFolder && !node1.isFolder)
return 1;
}
#sortNodesByColumn(root, column) {
const isColumnOriginal = (column.name === "original");
const isReverseSort = (this.reverseSort === "0");
const res = column.compareRows(row1, row2);
return (this.reverseSort === "0") ? res : -res;
});
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
nodes.each((node) => {
if (node.children.length > 0)
this.#sortNodesByColumn(node.children, column);
});
node.children.sort((row1, row2) => {
// list folders before files when sorting by name
if (isColumnOriginal) {
const node1 = this.getNode(row1.data.rowId);
const node2 = this.getNode(row2.data.rowId);
if (node1.isFolder && !node2.isFolder)
return -1;
if (!node1.isFolder && node2.isFolder)
return 1;
}
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
stack.push(...node.children);
}
}
#filterNodes(root, filterTerms) {
@ -2532,7 +2531,8 @@ window.qBittorrent.DynamicTable ??= (() => {
}
getFilteredAndSortedRows() {
if (this.getRoot() === null)
const root = this.getRoot();
if (root === null)
return [];
const generateRowsSignature = () => {
@ -2542,16 +2542,6 @@ window.qBittorrent.DynamicTable ??= (() => {
return JSON.stringify(rowsData);
};
const getFilteredRows = () => {
if (this.filterTerms.length === 0) {
const nodeArray = this.fileTree.toArray();
const filteredRows = nodeArray.map(node => this.getRow(node));
return filteredRows;
}
return this.#filterNodes(this.getRoot().children[0], this.filterTerms);
};
const hasRowsChanged = function(rowsString, prevRowsStringString) {
const rowsChanged = (rowsString !== prevRowsStringString);
const isFilterTermsChanged = this.filterTerms.reduce((acc, term, index) => {
@ -2570,16 +2560,23 @@ window.qBittorrent.DynamicTable ??= (() => {
return this.prevFilteredRows;
// sort, then filter
const column = this.columns[this.sortedColumn];
this.#sortNodesByColumn(this.getRoot().children, column);
const filteredRows = getFilteredRows();
this.#sortNodesByColumn(root, this.columns[this.sortedColumn]);
const rows = (() => {
if (this.filterTerms.length === 0) {
const nodeArray = this.fileTree.toArray();
const filteredRows = nodeArray.map(node => this.getRow(node));
return filteredRows;
}
return this.#filterNodes(root.children[0], this.filterTerms);
})();
this.prevFilterTerms = this.filterTerms;
this.prevRowsString = rowsString;
this.prevFilteredRows = filteredRows;
this.prevFilteredRows = rows;
this.prevSortedColumn = this.sortedColumn;
this.prevReverseSort = this.reverseSort;
return filteredRows;
return rows;
}
setIgnored(rowId, ignore) {
@ -2917,26 +2914,31 @@ window.qBittorrent.DynamicTable ??= (() => {
this.columns["availability"].updateTd = displayPercentage;
}
#sortNodesByColumn(nodes, column) {
nodes.sort((row1, row2) => {
// list folders before files when sorting by name
if (column.name === "name") {
const node1 = this.getNode(row1.data.rowId);
const node2 = this.getNode(row2.data.rowId);
if (node1.isFolder && !node2.isFolder)
return -1;
if (node2.isFolder && !node1.isFolder)
return 1;
}
#sortNodesByColumn(root, column) {
const isColumnName = (column.name === "name");
const isReverseSort = (this.reverseSort === "0");
const res = column.compareRows(row1, row2);
return (this.reverseSort === "0") ? res : -res;
});
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
nodes.each((node) => {
if (node.children.length > 0)
this.#sortNodesByColumn(node.children, column);
});
node.children.sort((row1, row2) => {
// list folders before files when sorting by name
if (isColumnName) {
const node1 = this.getNode(row1.data.rowId);
const node2 = this.getNode(row2.data.rowId);
if (node1.isFolder && !node2.isFolder)
return -1;
if (!node1.isFolder && node2.isFolder)
return 1;
}
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
stack.push(...node.children);
}
}
#filterNodes(root, filterTerms) {
@ -2995,7 +2997,8 @@ window.qBittorrent.DynamicTable ??= (() => {
}
getFilteredAndSortedRows() {
if (this.getRoot() === null)
const root = this.getRoot();
if (root === null)
return [];
const generateRowsSignature = () => {
@ -3005,8 +3008,6 @@ window.qBittorrent.DynamicTable ??= (() => {
return JSON.stringify(rowsData);
};
const getFilteredRows = () => this.#filterNodes(this.getRoot().children[0], this.filterTerms);
const hasRowsChanged = function(rowsString, prevRowsStringString) {
const rowsChanged = (rowsString !== prevRowsStringString);
const isFilterTermsChanged = this.filterTerms.reduce((acc, term, index) => {
@ -3025,16 +3026,15 @@ window.qBittorrent.DynamicTable ??= (() => {
return this.prevFilteredRows;
// sort, then filter
const column = this.columns[this.sortedColumn];
this.#sortNodesByColumn(this.getRoot().children, column);
const filteredRows = getFilteredRows();
this.#sortNodesByColumn(root, this.columns[this.sortedColumn]);
const rows = this.#filterNodes(root.children[0], this.filterTerms);
this.prevFilterTerms = this.filterTerms;
this.prevRowsString = rowsString;
this.prevFilteredRows = filteredRows;
this.prevFilteredRows = rows;
this.prevSortedColumn = this.sortedColumn;
this.prevReverseSort = this.reverseSort;
return filteredRows;
return rows;
}
setIgnored(rowId, ignore) {
@ -3603,10 +3603,11 @@ window.qBittorrent.DynamicTable ??= (() => {
filteredRows = [...this.getRowValues()];
}
const column = this.columns[this.sortedColumn];
const isReverseSort = (this.reverseSort === "0");
filteredRows.sort((row1, row2) => {
const column = this.columns[this.sortedColumn];
const res = column.compareRows(row1, row2);
return (this.reverseSort === "0") ? res : -res;
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
this.filteredLength = filteredRows.length;
@ -3661,10 +3662,11 @@ window.qBittorrent.DynamicTable ??= (() => {
filteredRows = [...this.getRowValues()];
}
const column = this.columns[this.sortedColumn];
const isReverseSort = (this.reverseSort === "0");
filteredRows.sort((row1, row2) => {
const column = this.columns[this.sortedColumn];
const res = column.compareRows(row1, row2);
return (this.reverseSort === "0") ? res : -res;
const result = column.compareRows(row1, row2);
return isReverseSort ? result : -result;
});
return filteredRows;