Skip to content

Commit

Permalink
perf: use batch cursor for full DB scan (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
nolanlawson committed Dec 25, 2020
1 parent bf15703 commit e5b1750
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -183,7 +183,7 @@
"bundlesize": [
{
"path": "./bundle.js",
"maxSize": "41 kB",
"maxSize": "41.5 kB",
"compression": "none"
},
{
Expand Down
41 changes: 31 additions & 10 deletions src/database/idbInterface.js
Expand Up @@ -24,19 +24,40 @@ export async function hasData (db, url, eTag) {
}

async function doFullDatabaseScanForSingleResult (db, predicate) {
// TODO: we could do batching here using getAll(). Not sure if it's worth the extra code though.
// This batching algorithm is just a perf improvement over a basic
// cursor. The BATCH_SIZE is an estimate of what would give the best
// perf for doing a full DB scan (worst case).
//
// Mini-benchmark for determining the best batch size:
//
// PERF=1 yarn build:rollup && yarn test:adhoc
//
// (async () => {
// performance.mark('start')
// await $('emoji-picker').database.getEmojiByShortcode('doesnotexist')
// performance.measure('total', 'start')
// console.log(performance.getEntriesByName('total').slice(-1)[0].duration)
// })()
const BATCH_SIZE = 50 // Typically around 150ms for 6x slowdown in Chrome for above benchmark
return dbPromise(db, STORE_EMOJI, MODE_READONLY, (emojiStore, cb) => {
emojiStore.openCursor().onsuccess = e => {
const cursor = e.target.result

if (!cursor) { // no more results
cb()
} else if (predicate(cursor.value)) {
cb(cursor.value)
} else {
cursor.continue()
let lastKey

const processNextBatch = () => {
emojiStore.getAll(lastKey && IDBKeyRange.lowerBound(lastKey, true), BATCH_SIZE).onsuccess = e => {
const results = e.target.result
for (const result of results) {
lastKey = result.unicode
if (predicate(result)) {
return cb(result)
}
}
if (results.length < BATCH_SIZE) {
return cb()
}
processNextBatch()
}
}
processNextBatch()
})
}

Expand Down

0 comments on commit e5b1750

Please sign in to comment.