jakearchibald / idb-keyval

A super-simple-small promise-based keyval store implemented with IndexedDB

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use getAll and getAllKeys when possible

JanOschii opened this issue · comments

My getAll() function

export function getAll<T=any>(
  customStore = defaultGetStore()
): Promise<T[]> {
  return customStore( 'readonly', (store) => promisifyRequest(store.getAll()) )
}

Why / Use Case
I need to load the full table (10000 entries) at startup in the memory. If I use your function entries() it needs 20 secs.
So I changed my concept and now every value field is an object with a key and value property. So i can use getAll() and have all the entries (keys and values) in under 100ms. 200times faster!

I thought I share this expirence with you.

This gives the same result as values, no?

Yes, my test has the same results for both functions, but getAll() is 200 times faster.

Reading 10.000 values with values() needs 12.168ms
Reading 10.000 values with getAll() needs     62ms

The function getAll() don't use cursors to iterate throught the table. The function values() is using the cursor.

export function values<T = any>(customStore = defaultGetStore()): Promise<T[]> {
  const items: T[] = [];
  return eachCursor(customStore, (cursor) => items.push(cursor.value)).then(
    () => items,
  );
}

From the API-Point of view the naming for the result is similar to getMany(), but you get all – getAll().
There is also a getAllKeys() function which do not need a cursor, nearly 500 times faster.

Reading 10.000 keys with keys() needs        9.963ms
Reading 10.000 keys with getAllKeys() needs     26ms

To bring everything together:

/**
 * Get all values in the store.
 *
 * @param customStore Method to get a custom store. Use with caution (see the docs).
 */
export function getAll<T=any>(
  customStore  = defaultGetStore()
): Promise<T[]> {
  return customStore( 'readonly', (store) => promisifyRequest(store.getAll()) )
}

/**
 * Get all keys in the store.
 *
 * @param customStore Method to get a custom store. Use with caution (see the docs).
 */
export function getAllKeys(
  customStore  = defaultGetStore()
): Promise<IDBValidKey[]> {
  return customStore( 'readonly', (store) => promisifyRequest(store.getAllKeys()) )
}

Support of getAll(): https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAll
Support of getAllKeys(): https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAllKeys

Yeah, I avoided getAll due to lack of support in IE and the old Edge engine. However, it seems fine to add these as performance enhancements.

I don't think these should be new methods, just performance enhancements to the existing methods.

Although, if you're dealing with that amount of data, you might find it easier to work with https://github.com/jakearchibald/idb

I see, but I am fine with idb-keyval. I solved all my use cases. Thanks m8 and good luck.

Could you test #141 for me?

I would, but if I try to install the branch I get:

Could not install from "github.com:jakearchibald\idb-keyval.git#optimise-get-all" 
as it does not contain a package.json file