Re[2]: [ZODB-Dev] lazy BTreeItems

2005-12-10 Thread Victor Safronovich
Hello Dieter Maurer,

Saturday, December 10, 2005, 12:32:35 AM, you wrote:

DM l = range(10)
DM for f in l: l.remove(f)
DM l
-- [1, 3, 5, 7, 9]

DM   Due to the much more complex BTree structures, the results
DM   of modifications during iteration might be even more surprising.
I know about this

Hello Tim Peters,

Saturday, December 10, 2005, 1:08:55 AM, you wrote:

TP The .keys(), .values(), and .items() methods of BTrees are very different
TP from those methods on dicts in that the BTree methods return lazy iterators
TP but the dict methods return lists.
I  undestand  that i need keys|values|items cast to list, and from this new list
get the new iterator.

And a funny situation

Starting debugger (the name app is bound to the top-level Zope object)
 from OFS.ObjectManager import ObjectManager
 from OFS.SimpleItem import SimpleItem
 m = ObjectManager()
 m._setObject('1',SimpleItem())
'1'
 m._setObject('2',SimpleItem())
'2'
 o_ids = m.objectIds()
 o_ids
['1', '2']
 m._delObject('1')
 o_ids
['1', '2']
 from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
 m = BTreeFolder2()
 m._setObject('1',SimpleItem())
'1'
 m._setObject('2',SimpleItem())
'2'
 o_ids = m.objectIds()
 o_ids
OOBTreeItems object at 0x4015dca0
 list(o_ids)
['1', '2']
 m._delObject('1')
 list(o_ids)
['2']

I`ll want to migrate my large object containers from Folder to BTreeFolder2, 
but my
code have many next places:

for id in container.objectIds():
   if some_condition:
   container._delObject(id)

or

container.manage_delObjects( container.objectIds() )

Be careful with migration of such type.

-- 
Best regards,
 Victor Safronovich
 NauMen.NauDoc.SoftwareDeveloper  http://www.naumen.ru

___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


Re: [ZODB-Dev] lazy BTreeItems

2005-12-09 Thread Dieter Maurer
Victor Safronovich wrote at 2005-12-9 12:05 +0500:
Hello zodb-dev!

Is this a correct behaviour?
 from BTrees.IIBTree import IIBTree
 t = IIBTree(map(None,range(5),range(5)))
 list(t.keys())
[0, 1, 2, 3, 4]
 k = t.keys()
 list(k)
[0, 1, 2, 3, 4]
 del t[0]
 list(k)
[]

BUT
 i = iter(t.keys())
 del t[1]
 list(i)
[2, 3, 4]

Things like these are to be expected!

  The BTrees methods keys, values and items are implemented
  as iterators.

  You should *NEVER* change the data structure being iterated over.
  If you do, funny things can happen -- not only with BTrees
  but with *ANY* iterator.

  E.g.

l = range(10)
for f in l: l.remove(f)
l
-- [1, 3, 5, 7, 9]

  Due to the much more complex BTree structures, the results
  of modifications during iteration might be even more surprising.

-- 
Dieter
___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


RE: [ZODB-Dev] lazy BTreeItems

2005-12-09 Thread Tim Peters
[Victor Safronovich]
 Hello zodb-dev!

 Is this a correct behaviour?
  from BTrees.IIBTree import IIBTree
  t = IIBTree(map(None,range(5),range(5)))
  list(t.keys())
 [0, 1, 2, 3, 4]
  k = t.keys()
  list(k)
 [0, 1, 2, 3, 4]
  del t[0]
 list(k)
 []

Nothing is defined about what an iterator sees after you mutate the object
from which the iterator was obtained.  What you see consists of
implementation accidents then.  More about this in the Iteration and
Mutation subsection of the BTrees docs at:

http://www.zope.org/Wikis/ZODB/FrontPage/guide/node6.html

... [skipping to next msg] ...

  t = dict(map(None,range(5),range(5)))
  for i in t.keys():
 if i in [1,3]:
 del t[i]
 print i

 0
 1
 2
 3
 4

That's not the same thing.  dict.keys() does not return a lazy iterator, it
returns a list.  BTrees.keys() does not return a list, it returns a lazy
iterator.  To make a dict example similar to the BTree example, use
dict.iterkeys(), or just iterate over the dict directly:

 five = range(5)
 t = dict(zip(five, five))
 t
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
 for i in t:  # same as for i in t.iterkeys():
... if i in [1, 3]:
... del t[i]
... print i
...
0
1
Traceback (most recent call last):
  File stdin, line 1, in ?
RuntimeError: dictionary changed size during iteration

 But this behaviour differs from dict objects, is this correct :)?

The .keys(), .values(), and .items() methods of BTrees are very different
from those methods on dicts in that the BTree methods return lazy iterators
but the dict methods return lists.

___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev