[Chandler-dev] empty value report (perf)

Andi Vajda vajda at osafoundation.org
Fri Jan 19 11:42:10 PST 2007


On Fri, 19 Jan 2007, Grant Baillie wrote:

> We can almost certainly replace a lot of the initialValue uses with 
> defaultValue, especially for values that aren't references. There's some risk 
> there, because the return value Item.hasLocalAttributeValue() is different in 
> the two cases, and some code (ICalendar/sharing, maybe) could rely on that.
>
> So far as reflists go, there are really two approaches in use right now:
>
> 1) Use defaultValue=None in your attribute.
>
> (Example: EventStamp.modifications or EventStamp.occurrences)
>
> Then, always make sure you can deal with None when iterating over myAttr. If 
> you have a biref, let the repository take care of setting up the biref where 
> possible, by always assigning to the "other" end. This avoids a lot of 
> checking for None, and initializing the attribute to [] (or set() or {} as 
> appropriate).

I could add support for new None-style reflist value, such as Nil, which can 
be iterated, thereby saving everyone from having to first check whether they 
have None or a valid ref list.

Currently, I already have such a value, Nil, but it is expressly meant to be 
NOT persistable. I could add another one, called Empty, of the same type 
that can.
Nil works as follows:
   - Nil is not true
   - len(Nil) == 0
   - Nil() -> None
   - 'blah' in Nil -> False
   - iter(Nil) -> iterator that stops right away
   - Nil is immutable

> 2) Use initialValue=[]
>
> (Example: Reminder.reminderItems)
>
> As you noticed, this leads to an extra attribute assignment every time you 
> create the Item. It does, however, make for simpler code: you assume that 
> attribute always exists, and just iterate over it, call 
> add()/remove()/whatever on it, and all's well. Unfortunately, it also has the 
> downside that initialValues don't always get set (if items are imported via 
> sharing, __init__ and initialValues are bypassed), which leads to bugs.

Yes, that's one problem. The other problem is that an initialValue, when set, 
is a local value and having lots of empty local values eventually adds up too.

> (As an aside, there's a movement afoot -- mainly PJE's work -- to have 
> initialValues in Stamp subclasses only be set up when the stamps are actually 
> added. This would probably cut down on some of the empty collection values in 
> your report. cf.

That would be great and probably address a large part of what my original mail 
was about.

> Anyway, is there a way to have the best of 1) and 2)? i.e. have something 
> that behaved like defaultValue=[], until you tried to modify the collection? 
> i.e. in code:
>
>>>> class MyItem(schema.Item):
> ...     myAttr = schema.Sequence(schema.Item, magicValue=[])
> ...
>>>> x = MyItem(...)
>>>> list(x.myAttr)
> []
>>>> x.hasLocalAttributeValue('myAttr')
> False
>>>> x.myAttr.add(x)
>>>> x.hasLocalAttributeValue('myAttr')
> True
>>>> x.myAttr.first()
> <MyItem ....>

I sure could add something like that beyond what I described above. Have a 
sort of Nil value that knows what to do when one attempts to append to it.

> In fact, shouldn't all many-valued attributes behave this way?

That could be useful in many cases, yes.

Is what we're discussing here something I should implement now or are we just 
discussing various ideas, nice-to-haves ?

Personally, I have no objections to implementing these now.
Let me know...

Andi..


More information about the chandler-dev mailing list