Tadashi Matsumoto wrote:
I was looking into the following code of intid's __init__.py.
91 def _generateId(self):
92 """Generate an id which is not yet taken.
94 This tries to allocate sequential ids so they fall into the
95 same BTree bucket, and randomizes if it stumbles upon a
96 used one.
98 while True:
99 if self._v_nextid is None:
100 self._v_nextid = random.randint(0, 2**31)
101 uid = self._v_nextid
102 self._v_nextid += 1
103 if uid not in self.refs:
104 return uid
105 self._v_nextid = None
107 def register(self, ob):
108 # Note that we'll still need to keep this proxy removal.
109 ob = removeSecurityProxy(ob)
110 key = IKeyReference(ob)
112 if key in self.ids:
113 return self.ids[key]
114 uid = self._generateId()
115 self.refs[uid] = key
116 self.ids[key] = uid
117 return uid
2**31 used at the line 100 is a long integer, and there is a possibility
of generating long integer. long interger can not be used with Btree
from BTrees import IOBTree
t[2**30] = 'abc'
t[2**31] = 'efg'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: expected integer key
I think it is better to use, for example, 2**30 instead of 2**31.
I think there are better strategies. This stragey would throw away
half of the key space.
By the way, there is a probability (less than 1/2**31 percent) of
generating same intids, if thread switching occurs between the line
114 and 115.
Yup, although, as Gary points out, this will be caught later.
This could should really have used the BTree insert API to combine
the test and insert. It's actually rather silly to have separated
_generateId into a separate method, as it is used only once.
As far as dealing with longs, a simple strategy would be to simply
catch TypeError when calling insert. If we get a TypeError, we should
pick a new random starting point.
Please report this problem in the collector.
Jim Fulton mailto:[EMAIL PROTECTED] Python Powered!
CTO (540) 361-1714 http://www.python.org
Zope Corporation http://www.zope.com http://www.zope.org
Zope3-dev mailing list