Skip to content

Commit

Permalink
on_update delta calculations are now lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
texodus committed Mar 26, 2019
1 parent 389356d commit c225a8e
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 99 deletions.
60 changes: 36 additions & 24 deletions packages/perspective/src/js/perspective.js
Original file line number Diff line number Diff line change
Expand Up @@ -638,39 +638,51 @@ export default function(Module) {
return this._View.set_depth(depth, this.config.row_pivot.length);
};

view.prototype._get_step_delta = async function() {
let delta = this._View.get_step_delta(0, 2147483647);
let data;
if (delta.cells.size() === 0) {
// FIXME This is currently not implemented for 1+ sided contexts.
data = await this.to_json();
} else {
let rows = {};
for (let x = 0; x < delta.cells.size(); x++) {
rows[delta.cells.get(x).row] = true;
}
rows = Object.keys(rows);
const results = await Promise.all(
rows.map(row =>
this.to_json({
start_row: Number.parseInt(row),
end_row: Number.parseInt(row) + 1
})
)
);
data = [].concat.apply([], results);
}
delta.cells.delete();
return data;
};

/**
* Register a callback with this {@link view}. Whenever the {@link view}'s
* underlying table emits an update, this callback will be invoked with the
* aggregated row deltas.
*
* @param {function} callback A callback function invoked on update. The
* parameter to this callback shares a structure with the return type of
* {@link view#to_json}.
* parameter to this callback is dependent on the `mode` parameter:
* - "none" (default): The callback is invoked without an argument.
* - "rows": The callback is invoked with the changed rows.
*/
view.prototype.on_update = function(callback) {
view.prototype.on_update = function(callback, {mode = "none"} = {}) {
if (["none", "rows"].indexOf(mode) === -1) {
throw new Error(`Invalid update mode "${mode}" - valid modes are "none" and "rows"`);
}
this.callbacks.push({
view: this,
callback: () => {
if (this._View.get_step_delta) {
let delta = this._View.get_step_delta(0, 2147483647);
if (delta.cells.size() === 0) {
this.to_json().then(callback);
} else {
let rows = {};
for (let x = 0; x < delta.cells.size(); x++) {
rows[delta.cells.get(x).row] = true;
}
rows = Object.keys(rows);
Promise.all(
rows.map(row =>
this.to_json({
start_row: Number.parseInt(row),
end_row: Number.parseInt(row) + 1
})
)
).then(results => callback([].concat.apply([], results)));
}
delta.cells.delete();
callback: async () => {
if (mode === "rows") {
callback(await this._get_step_delta());
} else {
callback();
}
Expand Down
177 changes: 102 additions & 75 deletions packages/perspective/test/js/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,15 @@ module.exports = perspective => {
it("`on_update()`", function(done) {
var table = perspective.table(meta);
var view = table.view();
view.on_update(function(new_data) {
expect(new_data).toEqual(data);
view.delete();
table.delete();
done();
});
view.on_update(
function(new_data) {
expect(new_data).toEqual(data);
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(data);
});

Expand All @@ -257,15 +260,18 @@ module.exports = perspective => {
var view = table.view();
table.update(data);
var ran = false;
view.on_update(function(new_data) {
if (!ran) {
expect(new_data).toEqual(data);
ran = true;
view.delete();
table.delete();
done();
}
});
view.on_update(
function(new_data) {
if (!ran) {
expect(new_data).toEqual(data);
ran = true;
view.delete();
table.delete();
done();
}
},
{mode: "rows"}
);
table.update(data);
});

Expand All @@ -274,16 +280,19 @@ module.exports = perspective => {
var table2 = perspective.table(meta);
var view1 = table1.view();
var view2 = table2.view();
view1.on_update(async function(x) {
table2.update(x);
let result = await view2.to_json();
expect(result).toEqual(data);
view1.delete();
view2.delete();
table1.delete();
table2.delete();
done();
});
view1.on_update(
async function(x) {
table2.update(x);
let result = await view2.to_json();
expect(result).toEqual(data);
view1.delete();
view2.delete();
table1.delete();
table2.delete();
done();
},
{mode: "rows"}
);
table1.update(data);
});

Expand All @@ -295,16 +304,19 @@ module.exports = perspective => {

table1.update(data);
table2.update(data);
view1.on_update(async function(x) {
table2.update(x);
let result = await view2.to_json();
expect(result).toEqual(data.concat(data));
view1.delete();
view2.delete();
table1.delete();
table2.delete();
done();
});
view1.on_update(
async function(x) {
table2.update(x);
let result = await view2.to_json();
expect(result).toEqual(data.concat(data));
view1.delete();
view2.delete();
table1.delete();
table2.delete();
done();
},
{mode: "rows"}
);
table1.update(data);
});
});
Expand Down Expand Up @@ -410,29 +422,35 @@ module.exports = perspective => {
var table = perspective.table(meta, {index: "x"});
var view = table.view();
table.update(data);
view.on_update(async function(new_data) {
expect(data_2).toEqual(new_data);
let json = await view.to_json();
expect(json).toEqual(data.slice(0, 2).concat(data_2));
view.delete();
table.delete();
done();
});
view.on_update(
async function(new_data) {
expect(data_2).toEqual(new_data);
let json = await view.to_json();
expect(json).toEqual(data.slice(0, 2).concat(data_2));
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(data_2);
});

it("update and index (string)", function(done) {
var table = perspective.table(meta, {index: "y"});
var view = table.view();
table.update(data);
view.on_update(async function(new_data) {
expect(data_2).toEqual(new_data);
let json = await view.to_json();
expect(json).toEqual(data.slice(0, 2).concat(data_2));
view.delete();
table.delete();
done();
});
view.on_update(
async function(new_data) {
expect(data_2).toEqual(new_data);
let json = await view.to_json();
expect(json).toEqual(data.slice(0, 2).concat(data_2));
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(data_2);
});

Expand Down Expand Up @@ -466,14 +484,17 @@ module.exports = perspective => {
var table = perspective.table(meta, {index: "y"});
var view = table.view();
table.update(data);
view.on_update(async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
});
view.on_update(
async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(partial);
});

Expand All @@ -488,14 +509,17 @@ module.exports = perspective => {
var table = perspective.table(meta, {index: "y"});
var view = table.view();
table.update(col_data);
view.on_update(async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
});
view.on_update(
async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(partial);
});

Expand All @@ -509,14 +533,17 @@ module.exports = perspective => {
var table = perspective.table(meta, {index: "y"});
var view = table.view();
table.update(col_data);
view.on_update(async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
});
view.on_update(
async function(new_data) {
expect(new_data).toEqual(expected.slice(0, 2));
let json = await view.to_json();
expect(json).toEqual(expected);
view.delete();
table.delete();
done();
},
{mode: "rows"}
);
table.update(partial);
});
});
Expand Down

0 comments on commit c225a8e

Please sign in to comment.