[Zodb-checkins] SVN: ZODB/branches/jim-python-btrees/src/BTrees/ checkpoint
Jim Fulton
jim at zope.com
Tue May 31 09:16:49 EDT 2011
Log message for revision 121847:
checkpoint
Changed:
U ZODB/branches/jim-python-btrees/src/BTrees/___BTree.py
U ZODB/branches/jim-python-btrees/src/BTrees/tests/testBTrees.py
-=-
Modified: ZODB/branches/jim-python-btrees/src/BTrees/___BTree.py
===================================================================
--- ZODB/branches/jim-python-btrees/src/BTrees/___BTree.py 2011-05-30 17:33:02 UTC (rev 121846)
+++ ZODB/branches/jim-python-btrees/src/BTrees/___BTree.py 2011-05-31 13:16:46 UTC (rev 121847)
@@ -14,8 +14,8 @@
"""Python BTree implementation
"""
-from struct import pack
-from ZODB.POSException import ConflictError
+from struct import pack, unpack
+from ZODB.POSException import BTreesConflictError
import persistent
import struct
@@ -25,13 +25,14 @@
class _Base(persistent.Persistent):
_key_type = list
- _to_key = lambda x: x
def __init__(self, items=None):
self.clear()
if items:
self.update(items)
+class _BucketBase(_Base):
+
def clear(self):
self._keys = self._key_type()
self._next = None
@@ -149,18 +150,23 @@
buckets = []
for state in states:
bucket = self.__class__()
- bucket.__setstate__(state)
+ if state:
+ bucket.__setstate__(state)
buckets.append(bucket)
if (buckets[1]._next != buckets[0]._next or
buckets[2]._next != buckets[0]._next):
- raise ConflictError(-1, -1, -1, 0)
+ raise BTreesConflictError(-1, -1, -1, 0)
- i1 = _SetIteration(buckets[0])
- i2 = _SetIteration(buckets[1])
- i3 = _SetIteration(buckets[2])
+ if not (buckets[1] and buckets[2]):
+ raise BTreesConflictError(-1, -1, -1, 12)
+ i1 = _SetIteration(buckets[0], True)
+ i2 = _SetIteration(buckets[1], True)
+ i3 = _SetIteration(buckets[2], True)
+
def merge_error(reason):
- return ConflictError(i1.position, i2.position, i3.position, reason)
+ return BTreesConflictError(
+ i1.position, i2.position, i3.position, reason)
result = self.__class__()
@@ -227,7 +233,7 @@
elif cmp13 > 0: # insert i3
merge_output(i3)
else:
- merge_error(5) # both deleted same key
+ raise merge_error(5) # both deleted same key
while i2.active and i3.active: # new inserts
cmp23 = cmp(i2.key, i3.key)
@@ -246,7 +252,7 @@
i1.advance()
i2.advance()
else: # dueling deletes or delete and change
- merge_error(7)
+ raise merge_error(7)
while i1.active and i3.active: # committed deletes rest of original
cmp13 = cmp(i1.key, i3.key)
@@ -257,16 +263,16 @@
i1.advance()
i3.advance()
else: # dueling deletes or delete and change
- merge_error(8)
+ raise merge_error(8)
if i1.active: # dueling deletes
- merge_error(9)
+ raise merge_error(9)
while i2.active:
merge_output(i2)
while i3.active:
- merge_output(i2)
+ merge_output(i3)
if len(result._keys) == 0:
# If the output bucket is empty, conflict resolution doesn't have
@@ -293,7 +299,7 @@
self.useValues = useValues
self._next = itmeth().next
- self.active
+ self.active = True
self.position = 0
self.advance()
@@ -354,14 +360,14 @@
for i in items:
add(i)
-class Bucket(_MappingBase):
+class Bucket(_MappingBase, _BucketBase):
_value_type = list
_to_value = lambda x: x
VALUE_SAME_CHECK = False
def clear(self):
- _Base.clear(self)
+ _BucketBase.clear(self)
self._values = self._value_type()
def get(self, key, default=None):
@@ -472,7 +478,7 @@
keys.append(state[i])
values.append(state[i+1])
-class Set(_SetBase):
+class Set(_SetBase, _BucketBase):
def __getstate__(self):
data = tuple(self._keys)
@@ -818,6 +824,32 @@
else:
assert_(False, "Incorrect child type")
+ def _p_resolveConflict(self, *states):
+ states = map(_get_simple_btree_bucket_state, states)
+ return ((self._bucket_type()._p_resolveConflict(*states), ), )
+
+def _get_simple_btree_bucket_state(state):
+ if state is None:
+ return state
+
+ if not isinstance(state, tuple):
+ raise TypeError("_p_resolveConflict: expected tuple or None for state")
+ if len(state) == 2:
+ raise BTreesConflictError(-1, -1, -1, 11)
+
+ if len(state) != 1:
+ raise TypeError("_p_resolveConflict: expected 1- or 2-tuple for state")
+
+ state = state[0]
+ if not isinstance(state, tuple) or len(state) != 1:
+ raise TypeError("_p_resolveConflict: expected 1-tuple containing "
+ "bucket state");
+ state = state[0]
+ if not isinstance(state, tuple):
+ raise TypeError("_p_resolveConflict: expected tuple for bucket state")
+
+ return state
+
class _TreeItems(object):
def __init__(self, firstbucket, itertype, iterargs):
@@ -862,14 +894,17 @@
bucket = self.firstbucket
itertype = self.itertype
iterargs = self.iterargs
+ done = 0
+ # Note that we don't mind if the first bucket yields no
+ # results due to an idiosyncrasy in how range searches are done.
while bucket is not None:
- done = 1
for k in getattr(bucket, itertype)(*iterargs):
yield k
done = 0
if done:
return
bucket = bucket._next
+ done = 1
# class _Slice:
@@ -913,7 +948,7 @@
# _, _, _, self._len = self._get_len(self.base, self.slice_)
# return self._len
-class Tree(_Tree, _MappingBase):
+class Tree(_Tree):
def get(self, key, default=None):
bucket = self._findbucket(key)
@@ -990,6 +1025,9 @@
i.advance()
else:
r = s1._set_type()
+ def copy(i, w):
+ r._keys.append(i.key)
+ i.advance()
while i1.active and i2.active:
cmp_ = cmp(i1.key, i2.key)
@@ -1016,26 +1054,35 @@
return r
-def difference(o1, o2):
+class setop(object):
+
+ def __init__(self, func, set_type):
+ self.func = func
+ self.set_type = set_type
+
+ def __call__(self, *a, **k):
+ return self.func(self.set_type, *a, **k)
+
+def difference(set_type, o1, o2):
if o1 is None or o2 is None:
return o1
return _set_operation(o1, o2, 1, 0, 1, 0, 1, 0, 0)
-def union(o1, o2):
+def union(set_type, o1, o2):
if o1 is None:
return o2
if o2 is None:
return o1
return _set_operation(o1, o2, 0, 0, 1, 1, 1, 1, 1)
-def intersection(o1, o2):
+def intersection(set_type, o1, o2):
if o1 is None:
return o2
if o2 is None:
return o1
return _set_operation(o1, o2, 0, 0, 1, 1, 0, 1, 0)
-def weightedUnion(o1, o2, w1=1, w2=1):
+def weightedUnion(set_type, o1, o2, w1=1, w2=1):
if o1 is None:
if o2 is None:
return 0, o2
@@ -1046,7 +1093,7 @@
else:
return 1, _set_operation(o1, o2, 1, 1, w1, w2, 0, 1, 0)
-def weightedIntersection(o1, o2, w1=1, w2=1):
+def weightedIntersection(set_type, o1, o2, w1=1, w2=1):
if o1 is None:
if o2 is None:
return 0, o2
@@ -1060,26 +1107,30 @@
_set_operation(o1, o2, 1, 1, w1, w2, 0, 1, 0),
)
-def multiunion(seqs):
+def multiunion(set_type, seqs):
# XXX simple/slow implementation. Goal is just to get tests to pass.
if not seqs:
- return None
- result = seqs[0]._set_type()
+ return set_type()
+ result = set_type()
for s in seqs:
+ try:
+ iter(s)
+ except TypeError:
+ s = set_type((s, ))
result.update(s)
+ return result
def to_ob(self, v):
return v
+int_types = int, long
def to_int(self, v):
try:
- pack("i", v)
+ if not unpack("i", pack("i", v))[0] == v:
+ raise TypeError('32-bit integer expected')
except struct.error:
raise TypeError('32-bit integer expected')
- if isinstance(v, float):
- raise TypeError('32-bit integer expected')
-
return int(v)
def to_float(self, v):
@@ -1091,13 +1142,15 @@
def to_long(self, v):
try:
- pack("q", v)
+ if not unpack("q", pack("q", v))[0] == v:
+ if isinstance(v, int_types):
+ raise ValueError("Value out of range", v)
+ raise TypeError('64-bit integer expected')
except struct.error:
+ if isinstance(v, int_types):
+ raise ValueError("Value out of range", v)
raise TypeError('64-bit integer expected')
- if isinstance(v, float):
- raise TypeError('32-bit integer expected')
-
return int(v)
def to_str(l):
@@ -1134,12 +1187,19 @@
Set = set,
BTree = tree,
TreeSet = treeset,
- difference = difference,
- union = union,
- intersection = intersection,
- weightedUnion = weightedUnion,
- weightedIntersection = weightedIntersection,
- multiunion = multiunion,
+ difference = setop(difference, set),
+ union = setop(union, set),
+ intersection = setop(intersection, set),
using64bits='L' in prefix,
)
+ if prefix[0] in 'IL':
+ globals.update(
+ multiunion = setop(multiunion, set),
+ )
+ if prefix[1] != 'O':
+ globals.update(
+ weightedUnion = setop(weightedUnion, set),
+ weightedIntersection = setop(weightedIntersection, set),
+ )
+
del globals['___BTree']
Modified: ZODB/branches/jim-python-btrees/src/BTrees/tests/testBTrees.py
===================================================================
--- ZODB/branches/jim-python-btrees/src/BTrees/tests/testBTrees.py 2011-05-30 17:33:02 UTC (rev 121846)
+++ ZODB/branches/jim-python-btrees/src/BTrees/tests/testBTrees.py 2011-05-31 13:16:46 UTC (rev 121847)
@@ -2057,6 +2057,7 @@
s.insert(BTrees.family64.minint)
self.assert_(BTrees.family64.minint in s)
s = LOTreeSet()
+ # XXX why oh why do we expect ValueError here, but TypeError in test32?
self.assertRaises(ValueError, s.insert, BTrees.family64.maxint + 1)
self.assertRaises(ValueError, s.insert, BTrees.family64.minint - 1)
self.check_pickling(BTrees.family64)
More information about the Zodb-checkins
mailing list