Bug 1486980 - Fetch tippytop collection in one bulk with getAll() r=asuth,nanj

Iterating an IDB cursor generates a lot of overhead. In this patch, we upgrade the kinto-offline to its latest version that uses `getAll()` when no filter is specified. We leverage this change in tippytop, by omitting the filter and filtering the whole list there instead. This allowed us to go from ~1sec on a 1000 entries to ~70ms.

Differential Revision: https://phabricator.services.mozilla.com/D9076

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mathieu Leplatre 2018-10-18 17:02:24 +00:00
parent deeb744526
commit cf4f74d9bf

View File

@ -33,7 +33,7 @@ const global = this;
var EXPORTED_SYMBOLS = ["Kinto"];
/*
* Version 12.1.1 - 6950498
* Version 12.2.0 - 266e100
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Kinto = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
@ -486,13 +486,20 @@ const cursorHandlers = {
*/
function createListRequest(cid, store, filters, done) {
const filterFields = Object.keys(filters); // If no filters, get all results in one bulk.
if (filterFields.length == 0) {
const request = store.index("cid").getAll(IDBKeyRange.only(cid));
request.onsuccess = event => done(event.target.result);
return request;
}
// Introspect filters and check if they leverage an indexed field.
const indexField = Object.keys(filters).find(field => {
const indexField = filterFields.find(field => {
return INDEXED_FIELDS.includes(field);
});
if (!indexField) {
// Get all records for this collection (ie. cid)
// Iterate on all records for this collection (ie. cid)
const request = store.index("cid").openCursor(IDBKeyRange.only(cid));
request.onsuccess = cursorHandlers.all(filters, done);
return request;
@ -501,8 +508,11 @@ function createListRequest(cid, store, filters, done) {
const remainingFilters = (0, _utils.omitKeys)(filters, indexField); // value specified in the filter (eg. `filters: { _status: ["created", "updated"] }`)
const value = filters[indexField]; // WHERE IN equivalent clause
const value = filters[indexField];
// For the "id" field, use the primary key.
const indexStore = indexField == "id" ? store : store.index(indexField);
// WHERE IN equivalent clause
if (Array.isArray(value)) {
if (value.length === 0) {
return done([]);
@ -510,13 +520,20 @@ function createListRequest(cid, store, filters, done) {
const values = value.map(i => [cid, i]).sort();
const range = IDBKeyRange.bound(values[0], values[values.length - 1]);
const request = store.index(indexField).openCursor(range);
const request = indexStore.openCursor(range);
request.onsuccess = cursorHandlers.in(values, remainingFilters, done);
return request;
}
// If no filters on custom attribute, get all results in one bulk.
if (remainingFilters.length == 0) {
const request = indexStore.getAll(IDBKeyRange.only([cid, value]));
request.onsuccess = event => done(event.target.result);
return request;
} // WHERE field = value clause
const request = store.index(indexField).openCursor(IDBKeyRange.only([cid, value]));
const request = indexStore.openCursor(IDBKeyRange.only([cid, value]));
request.onsuccess = cursorHandlers.all(remainingFilters, done);
return request;
}
@ -577,9 +594,7 @@ class IDB extends _base.default {
}); // An index to obtain all the records in a collection.
recordsStore.createIndex("cid", "_cid"); // Here we create indices for every known field in records by collection.
// Record id (generated by IdSchema, UUID by default)
recordsStore.createIndex("id", ["_cid", "id"]); // Local record status ("synced", "created", "updated", "deleted")
// Local record status ("synced", "created", "updated", "deleted")
recordsStore.createIndex("_status", ["_cid", "_status"]); // Last modified field