- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 16 Sep 2010 12:57:22 -0700
- To: Jeremy Orlow <jorlow@chromium.org>
- Cc: public-webapps WG <public-webapps@w3.org>
On Thu, Sep 16, 2010 at 4:08 AM, Jeremy Orlow <jorlow@chromium.org> wrote: > On Thu, Sep 16, 2010 at 10:15 AM, Jeremy Orlow <jorlow@chromium.org> wrote: >> >> On Wed, Sep 15, 2010 at 10:45 PM, Jonas Sicking <jonas@sicking.cc> wrote: >>> >>> Heh, I've also been thinking about this exact issue lately. There is a >>> similar question for IDBCursor.delete. >>> >>> On Wed, Sep 15, 2010 at 8:55 AM, Jeremy Orlow <jorlow@chromium.org> >>> wrote: >>> > I think it's clear what IDBCursor does when created from >>> > IDBObjectStore.openCursor or IDBIndex.openObjectCursor: it modifies the >>> > objectStore's value and updates all indexes (or does nothing and >>> > returns an >>> > error if all of that can't be done while satisfying the constraints). >>> >>> Agreed. >>> >>> > But what about IDBCursor.update when created from IDBIndex.openCursor? >>> > I >>> > see two options: we could modify the value within the objectStore's >>> > value >>> > that corresponds to the objectStore's key path or we could do like >>> > above and >>> > simply modify the objectStore's value. >>> >>> There's also a third option: Throw an exception. Maybe that's what >>> you're referring to by "make this unsupported" below? >>> >>> > More concretely, if we have an object store with a "id" key path and an >>> > index with a "fname" key path, and our index.openCursor() created >>> > cursor is >>> > currently on the {id: 22, fname: "Fred"} value (and thus cursor.key == >>> > "Fred" and cursor.value == 22), let's say I wanted to change the object >>> > to >>> > be {id: 23, fname: "Fred"}. In other words, I want id to change from >>> > 22 to >>> > 23. Which of the following should I write? >>> > 1) calling cursor.update(23) or >>> > 2) calling cursor.update({id: 23, fname: "Fred"}) >>> > The former seems to match the behavior of the IDBObjectStore.openCursor >>> > and >>> > IDBIndex.openObjectCursor better (i.e. it modifies the cursor.value). >>> > The >>> > latter intuitively seems like it'd be more useful. But to be honest, I >>> > can't think of any use cases for either. Can anyone else? If not, >>> > maybe we >>> > should just make this unsupported for now? >>> >>> The only use case I have thought of is wanting to update some set of >>> entries, where the best way to find these entries is through an index. >>> For example updating every entry with a specific shipping-id. You can >>> use IDBIndex.openObjectCursor for this, but that's slower than >>> IDBIndex.openCursor. So in the rare instance when you can make the >>> modification without inspecting the existing value (i.e. you only need >>> to write, read-modify-write), then IDBIndex.openCursor + >>> IDBCursor.update() would be a perf optimization. >>> >>> On the other hand, it might be just as quick to call >>> IDBObjectStore.put(). >>> >>> Since the use case if pretty weak (when would you be able to update an >>> entry without first reading the entry), and that you can seemingly get >>> the same performance using IDBObjectStore.put(), I would be fine with >>> making this unsupported. >>> >>> As for IDBCursor.delete(), I can see a somewhat stronger use case >>> there. For example removing all entries with a specific shipping-id or >>> some such. If you can determine which entries should be removed purely >>> on the information in the index, then using IDBIndex.openCursor is >>> definitely faster than IDBIndex.openObjectCursor. So on one hand it >>> would be nice to allow people to use that. On the other hand, I >>> suspect you can get the same performance using IDBObjectStore.delete() >>> and we might want to be consistent with IDBCursor.update(). >>> >>> In this case I'm actually leaning towards allowing IDBCursor.delete(), >>> but I could go either way. >> >> Wait a sec. What are the use cases for non-object cursors anyway? They >> made perfect sense back when we allowed explicit index management, but now >> they kind of seem like a premature optimization or possibly even dead >> weight. Maybe we should just remove them altogether? > > Actually, for that matter, are remove and update needed at all? I think > they may just be more cruft left over from the explicit index days. As far > as I can tell, any .delete or .remove should be doable via an objectCursor + > .puts/.removes on the objectStore. They are not strictly needed, but they are a decent convinence feature, and with a proper implementation they can even be a performance optimization. With a cursor iterating a b-tree you can let the cursor keep a pointer to the b-tree entry. They way .delete and .update doesn't have to do a b-tree lookup at all. We're currently not able to do this since our backend (sqlite) doesn't have good enough cursor support, but I suspect that this will change at some point in the future. In the mean time it seems like a good thing to allow people to use API that will be faster in the future. / Jonas
Received on Thursday, 16 September 2010 19:58:20 UTC