Re: [indexeddb] Keypath attribute lookup question

On Sat, Nov 12, 2011 at 2:14 PM, Jonas Sicking <jonas@sicking.cc> wrote:
> On Fri, Nov 11, 2011 at 5:07 PM, Israel Hilerio <israelh@microsoft.com> wrote:
>> On Wednesday, November 09, 2011 4:47 PM, Joshua Bell wrote:
>>>On Wed, Nov 9, 2011 at 3:35 PM, Israel Hilerio <israelh@microsoft.com> wrote:
>>>>In section "4.7 Steps for extracting a key from a value using a key path" step #4 it states that:
>>>>* If object does not have an attribute named attribute, then skip the rest of these steps and no value is returned.
>>
>>>>We want to verify that the attribute lookup is taking place on the immediate object attributes and the prototype chain, correct?
>>
>>>My reading of the spec: In 3.2.5 the description of add (etc) says that
>>>the method creates a structured clone of value then runs the store
>>>operation with that cloned value. The steps for storing a record (5.1) are the context where the key path is evaluated, which would imply that it is done against the cloned value. The structured cloning algorithm doesn't walk the prototype chain, so this reading would indicate that the attribute lookup only occurs against the immediate object.
>>
>>>I believe there's a spec issue in that in section 3.2.5 the list of
>>>cases where DataError is thrown are described without reference to the
>>>value parameter (it's implied, but not stated), followed by "Otherwise
>>>this method creates a structured clone of the value parameter". That
>>>implies that these error cases apply to the value, whereas the storage
>>>operations apply to the structured clone of the value. (TOCTOU?)
>>
>>>We (Chrome) believe that the structured clone step should occur prior to the checks and the cloned value be used for these operations.
>>
>> What you're saying makes sense!  The scenario we are worried about is the one in which we want to be able to index on the size, type, name, and lastModifiedDate attributes of a File object.  Given the current SCA serialization logic, I'm not sure this is directly supported.  This could become an interoperable problem if we allow these properties to be serialized and indexed in our implementation but FF or Chrome don't. We consider Blobs and Files to be host objects and we treat those a little different from regular JavaScript Objects.
>>
>> We feel that the ability to index these properties enables many useful scenarios and would like to see all browsers support it.
>>
>> What do you and Jonas think?
>
> Wow, good points all around.
>
> My concern about getting properties off of the structured clone is one
> of performance. Currently when we do a structured clone we actually
> simply serialize the object graph. Serializing needs to happen anyway
> so we might as well do it as part of structured cloning.
>
> Turns out this is the case in basically *all* APIs which use
> structured clones, that they need to both clone and serialize, so this
> has worked great as an implementation strategy, both for code reuse
> and performance reasons.
>
> So my concern is that if we get the properties off of the structured
> clone, then it means getting them not from an object graph, but from a
> serialized "thing".
>
> I also concur with Israel's comment. Though this seems solvable by
> simply adding more smarts to the code which reads the values from the
> serialized "thing" as to make it support native objects. We have the
> exact same issue as microsoft here.
>
> On the flip side, I definitely see a risk if we get the index values
> from the object prior to structured clone. This could prevent
> optimizations such as being able to read out the index values on the
> database thread. This could be useful when deleting an item from the
> objectStore so that the relevant values from all indexes can be
> removed.
>
> I'll have to confer with other people at mozilla before expressing a
> too strong opinion either way here.

I talked this over with people that knows our structured clone
implementation better than me.

As I see it, the main question is if we should do the index-value
lookup on the value handed to the .put/.add/.update function, or if we
should do the lookup on the structured clone of that value.

I.e. if someone calls objectStore.add(X);

we will before the .add function returns, create a structured clone of
the value in X. The question is if we should look up index values on
X, or on the structured clone of X.

There are several behavioral differences between the two. For example
if any values on X are implemented using getters, then those getters
might return different things when the structured clone is happening,
and when the index-value-getting code is executing.

Another difference is that for any non-host object, any values that
live on the prototype chain get lost during the structured clone since
it doesn't copy the prototype chain.

What I think we should do is to get index values from the structured
clone of X. There at least two advantages of this:

1. The code to get index values can run on the database thread of the
IDB implementation. This enables a more parallel implementation.
2. It means that .add/.put/.update is consistent with .createIndex

.createIndex always has to get values from the structured clone since
at the time when it runs, the structured clones stored in the database
is the only thing we have.

I do however think that we should simply state that getting the index
values will use the normal method for looking up properties on JS
objects. This includes walking the prototype chain. Practically
speaking this only makes a difference on host objects like Files and
ArrayBuffers since plain JS objects loose their prototype during
structured clones.

This should alleviate Israels concern about being able to index on
Blob.size or File.name.

In any case, I filed
http://www.w3.org/Bugs/Public/show_bug.cgi?id=14830 on specifying
behavior here explicitly one way or another.

/ Jonas

/ Jonas

Received on Tuesday, 15 November 2011 01:53:06 UTC