Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue with sort on TABLE_ROWS #757

Merged
merged 1 commit into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions vuu-ui/packages/vuu-data/src/message-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,14 @@ export const getFirstAndLastRows = (
const lastRow = rows.at(-1) as VuuRow;
return [firstRow, lastRow];
};

export type ViewportRowMap = { [key: string]: VuuRow[] };
export const groupRowsByViewport = (rows: VuuRow[]): ViewportRowMap => {
const result: ViewportRowMap = {};
for (const row of rows) {
const rowsForViewport =
result[row.viewPortId] || (result[row.viewPortId] = []);
rowsForViewport.push(row);
}
return result;
};
98 changes: 31 additions & 67 deletions vuu-ui/packages/vuu-data/src/server-proxy/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
DataSourceVisualLinkRemovedMessage,
} from "../data-source";
import {
groupRowsByViewport,
isVuuMenuRpcRequest,
stripRequestId,
WithRequestId,
Expand Down Expand Up @@ -107,18 +108,6 @@ function addLabelsToLinks(
});
}

const byViewportRowIdxTimestamp = (row1: VuuRow, row2: VuuRow) => {
if (row1.viewPortId === row2.viewPortId) {
if (row1.rowIndex === row2.rowIndex) {
return row1.ts > row2.ts ? 1 : -1;
} else {
return row1.rowIndex > row2.rowIndex ? 1 : -1;
}
} else {
return row1.viewPortId > row2.viewPortId ? 1 : -1;
}
};

type PendingRequest<T = unknown> = {
reject: (err: unknown) => void;
resolve: (value: T | PromiseLike<T>) => void;
Expand Down Expand Up @@ -786,74 +775,49 @@ export class ServerProxy {
break;
case Message.TABLE_ROW:
{
body.rows.sort(byViewportRowIdxTimestamp);
let currentViewportId = "";
let viewport: Viewport | undefined;
let startIdx = 0;

if (process.env.NODE_ENV === "development") {
if (debugEnabled) {
const [firstRow, secondRow] = body.rows;
if (body.rows.length === 0) {
debug("handleMessageFromServer TABLE_ROW 0 rows");
} else if (firstRow?.rowIndex === -1) {
if (body.rows.length === 1) {
if (firstRow.updateType === "SIZE") {
debug(
`handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ONLY ${firstRow.vpSize}`
);
} else {
debug(
`handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ${firstRow.vpSize} rowIdx ${firstRow.rowIndex}`
);
}
const viewportRowMap = groupRowsByViewport(body.rows);

if (process.env.NODE_ENV === "development" && debugEnabled) {
const [firstRow, secondRow] = body.rows;
if (body.rows.length === 0) {
debug("handleMessageFromServer TABLE_ROW 0 rows");
} else if (firstRow?.rowIndex === -1) {
if (body.rows.length === 1) {
if (firstRow.updateType === "SIZE") {
debug(
`handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ONLY ${firstRow.vpSize}`
);
} else {
debug(
`handleMessageFromServer TABLE_ROW ${
body.rows.length
} rows, SIZE ${firstRow.vpSize}, [${
secondRow?.rowIndex
}] - [${body.rows[body.rows.length - 1]?.rowIndex}]`
`handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ${firstRow.vpSize} rowIdx ${firstRow.rowIndex}`
);
}
} else {
debug(
`handleMessageFromServer TABLE_ROW ${
body.rows.length
} rows [${firstRow?.rowIndex}] - [${
body.rows[body.rows.length - 1]?.rowIndex
}]`
} rows, SIZE ${firstRow.vpSize}, [${
secondRow?.rowIndex
}] - [${body.rows[body.rows.length - 1]?.rowIndex}]`
);
}
} else {
debug(
`handleMessageFromServer TABLE_ROW ${body.rows.length} rows [${
firstRow?.rowIndex
}] - [${body.rows[body.rows.length - 1]?.rowIndex}]`
);
}
}

for (
let i = 0, count = body.rows.length, isLast = i === count - 1;
i < count;
i++, isLast = i === count - 1
) {
const row = body.rows[i];
if (row.viewPortId !== currentViewportId || isLast) {
const viewportId =
count === 1 ? row.viewPortId : currentViewportId;
if (viewportId !== "") {
viewport = viewports.get(viewportId);
if (viewport) {
if (startIdx === 0 && isLast) {
viewport.updateRows(body.rows);
} else {
const end = isLast ? count : i;
viewport.updateRows(body.rows.slice(startIdx, end));
startIdx = i;
}
} else {
warn?.(
`TABLE_ROW message received for non registered viewport ${viewportId}`
);
}
}
currentViewportId = row.viewPortId;
for (const [viewportId, rows] of Object.entries(viewportRowMap)) {
const viewport = viewports.get(viewportId);
if (viewport) {
viewport.updateRows(rows);
} else {
warn?.(
`TABLE_ROW message received for non registered viewport ${viewportId}`
);
}
}

Expand Down
14 changes: 0 additions & 14 deletions vuu-ui/packages/vuu-data/src/server-proxy/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ export class Viewport {
private batchMode = true;
private useBatchMode = true;

private ignorePostFilterRepeats = false;

private rangeMonitor = new RangeMonitor("ViewPort");

public clientViewportId: string;
Expand Down Expand Up @@ -632,8 +630,6 @@ export class Viewport {
data: dataSourceFilter,
});

this.ignorePostFilterRepeats = true;

if (this.useBatchMode) {
this.batchMode = true;
}
Expand Down Expand Up @@ -745,16 +741,6 @@ export class Viewport {
this.removePendingRangeRequest(firstRow.rowIndex, lastRow.rowIndex);
}

if (this.ignorePostFilterRepeats) {
if (firstRow.vpSize === this.dataWindow?.rowCount) {
debug?.(`ignore data, rows are post filter repeats`);
this.ignorePostFilterRepeats = false;
return;
} else {
this.ignorePostFilterRepeats = false;
}
}

if (rows.length === 1 && firstRow.vpSize === 0 && this.disabled) {
debug?.(
`ignore a SIZE=0 message on disabled viewport (${rows.length} rows)`
Expand Down
47 changes: 47 additions & 0 deletions vuu-ui/packages/vuu-data/test/message-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, it } from "vitest";
import { createTableRows } from "./test-utils";

import { groupRowsByViewport } from "../src/message-utils";

describe("message-utils", () => {
describe("groupRowsByViewport", () => {
it("returns empty map for empty rowset", () => {
expect(groupRowsByViewport([])).toEqual({});
});
it("preserves order of rows in map by viewport, simple rowset", () => {
const rows = createTableRows("server-vp-1", 0, 10);
expect(groupRowsByViewport(rows)).toEqual({
"server-vp-1": rows,
});
});

it("preserves order of rows in map by viewport, multiple rowsets, same viewport", () => {
const rows1 = createTableRows("server-vp-1", 0, 10);
const rows2 = createTableRows("server-vp-1", 0, 10);
expect(groupRowsByViewport(rows1.concat(rows2))).toEqual({
"server-vp-1": rows1.concat(rows2),
});
});

it("preserves order of rows in map by viewport, multiple rowsets, multiple viewports", () => {
const rows1 = createTableRows("server-vp-1", 0, 10);
const rows2 = createTableRows("server-vp-2", 0, 10);
expect(groupRowsByViewport(rows1.concat(rows2))).toEqual({
"server-vp-1": rows1,
"server-vp-2": rows2,
});
});

it("preserves order of rows in map by viewport, multiple rowsets, multiple viewports, interleaved", () => {
const rows1 = createTableRows("server-vp-1", 0, 10);
const rows2 = createTableRows("server-vp-2", 0, 10);
const rows = rows1
.concat(rows2)
.sort(({ rowIndex: i1 }, { rowIndex: i2 }) => i1 - i2);
expect(groupRowsByViewport(rows)).toEqual({
"server-vp-1": rows1,
"server-vp-2": rows2,
});
});
});
});
Loading