fix(oceanbase): preserve concurrent full-value hydration during save preparation

This commit is contained in:
efeire
2026-10-09 18:50:03 +08:00
parent 1d607021c7
commit ec950ea77c
2 changed files with 13 additions and 3 deletions
@@ -1395,7 +1395,7 @@ describe("useDataGridEditor saveChanges reload", () => {
it("loads complete original baselines before generating forward and rollback SQL", async () => {
const source = { columns: ["id", "status"], rows: [[1, "LOB preview"]] as CellValue[][] };
const prepareSaveBaseline = vi.fn(async (changes) => {
const prepareSaveBaseline = vi.fn(async (changes: Parameters<NonNullable<import("@/composables/useDataGridEditor").UseDataGridEditorOptions["prepareSaveBaseline"]>>[0]) => {
expect(changes.dirtyRows.get(0).get(1)).toBeNull();
source.rows[0]![1] = "complete original LOB";
});
@@ -660,11 +660,21 @@ export function useDataGridLargeValues(options: UseDataGridLargeValuesOptions) {
rows[cell.row_index]![cell.column_index] = value;
}
if (!isCurrent()) throw new Error("LOB result context changed");
// Other consumers can hydrate another cell while these requests await.
// Merge only the requested baselines into the latest rows and budget.
const mergedRows = source.rows.map((row) => [...row]);
const mergedSizes = new Map(materializedSnapshotBytes.get(source));
for (const cell of cells) {
mergedRows[cell.row_index]![cell.column_index] = rows[cell.row_index]![cell.column_index];
const key = largeValueCellKey(cell.row_index, cell.column_index);
mergedSizes.set(key, sizes.get(key)!);
}
if ([...mergedSizes.values()].reduce((sum, size) => sum + size, 0) > 64 * 1024 * 1024) throw new Error("LOB save baseline exceeds the 64 MiB view/edit limit; reload and edit a smaller selection");
source.large_value_refs = [...new Set([...(source.large_value_refs ?? []), ...cells.map((cell) => cell.value_ref!)])];
const resolved = new Set(cells.map((cell) => largeValueCellKey(cell.row_index, cell.column_index)));
source.rows = rows;
source.rows = mergedRows;
source.large_value_cells = source.large_value_cells?.filter((cell) => !resolved.has(largeValueCellKey(cell.row_index, cell.column_index)));
materializedSnapshotBytes.set(source, sizes);
materializedSnapshotBytes.set(source, mergedSizes);
options.largeValueResolutionVersion.value += 1;
options.clearCellFormatCache();
options.invalidateResultEstimate(source);