Commit c22307fb authored by Tim Peters's avatar Tim Peters

Enabled multiunion() for the IOBTree package too. There isn't a good

reason for it not being enabled before.
parent ad85dfb9
...@@ -138,8 +138,8 @@ mappings. If left undefined, MERGE_WEIGHT defaults to ...@@ -138,8 +138,8 @@ mappings. If left undefined, MERGE_WEIGHT defaults to
MULTI_INT_UNION MULTI_INT_UNION
The value doesn't matter. If defined, SetOpTemplate.c compiles The value doesn't matter. If defined, SetOpTemplate.c compiles
code for a multiunion() function (compute a union of many input sets code for a multiunion() function (compute a union of many input sets
at high speed). This currently makes sense only for II sets, so at high speed). This currently makes sense only for structures with
only _IIBTree.c defines it. integer keys.
BTree Clues BTree Clues
......
/* Setup template macros */ /* Setup template macros */
#define MASTER_ID "$Id: _IIBTree.c,v 1.6 2002/05/30 21:00:30 tim_one Exp $\n" #define MASTER_ID "$Id: _IIBTree.c,v 1.7 2002/06/25 02:00:55 tim_one Exp $\n"
#define PERSISTENT #define PERSISTENT
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#define INITMODULE init_IIBTree #define INITMODULE init_IIBTree
#define DEFAULT_MAX_BUCKET_SIZE 120 #define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500 #define DEFAULT_MAX_BTREE_SIZE 500
#define MULTI_INT_UNION 1
#include "intkeymacros.h" #include "intkeymacros.h"
#include "intvaluemacros.h" #include "intvaluemacros.h"
......
#define KEYMACROS_H "$Id: intkeymacros.h,v 1.8 2002/05/31 09:41:07 htrd Exp $\n" #define KEYMACROS_H "$Id: intkeymacros.h,v 1.9 2002/06/25 02:00:55 tim_one Exp $\n"
#define KEY_TYPE int #define KEY_TYPE int
#define KEY_CHECK PyInt_Check #define KEY_CHECK PyInt_Check
...@@ -12,3 +12,4 @@ ...@@ -12,3 +12,4 @@
if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else { \ if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else { \
PyErr_SetString(PyExc_TypeError, "expected integer key"); \ PyErr_SetString(PyExc_TypeError, "expected integer key"); \
(STATUS)=0; (TARGET)=0; } (STATUS)=0; (TARGET)=0; }
#define MULTI_INT_UNION 1
...@@ -19,8 +19,6 @@ from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet ...@@ -19,8 +19,6 @@ from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
from BTrees.IIBTree import multiunion
# XXX TODO Needs more tests. # XXX TODO Needs more tests.
# This file was created when multiunion was added. The other set operations # This file was created when multiunion was added. The other set operations
# don't appear to be tested anywhere yet. # don't appear to be tested anywhere yet.
...@@ -195,10 +193,14 @@ class PureOI(SetResult): ...@@ -195,10 +193,14 @@ class PureOI(SetResult):
from BTrees.OIBTree import union, intersection, difference from BTrees.OIBTree import union, intersection, difference
builders = OISet, OITreeSet, makeBuilder(OIBTree), makeBuilder(OIBucket) builders = OISet, OITreeSet, makeBuilder(OIBTree), makeBuilder(OIBucket)
class TestMultiUnion(TestCase): # Subclasses must set up (as class variables):
# multiunion, union
# mkset, mktreeset
# mkbucket, mkbtree
class MultiUnion(TestCase):
def testEmpty(self): def testEmpty(self):
self.assertEqual(len(multiunion([])), 0) self.assertEqual(len(self.multiunion([])), 0)
def testOne(self): def testOne(self):
for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2): for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2):
...@@ -208,22 +210,22 @@ class TestMultiUnion(TestCase): ...@@ -208,22 +210,22 @@ class TestMultiUnion(TestCase):
seqsorted = sequence[:] seqsorted = sequence[:]
seqsorted.sort() seqsorted.sort()
for seq in seq1, seq2, seqsorted: for seq in seq1, seq2, seqsorted:
for builder in IISet, IITreeSet: for builder in self.mkset, self.mktreeset:
input = builder(seq) input = builder(seq)
output = multiunion([input]) output = self.multiunion([input])
self.assertEqual(len(seq), len(output)) self.assertEqual(len(seq), len(output))
self.assertEqual(seqsorted, list(output)) self.assertEqual(seqsorted, list(output))
def testValuesIgnored(self): def testValuesIgnored(self):
for builder in IIBucket, IIBTree: for builder in self.mkbucket, self.mkbtree:
input = builder([(1, 2), (3, 4), (5, 6)]) input = builder([(1, 2), (3, 4), (5, 6)])
output = multiunion([input]) output = self.multiunion([input])
self.assertEqual([1, 3, 5], list(output)) self.assertEqual([1, 3, 5], list(output))
def testBigInput(self): def testBigInput(self):
N = 100000 N = 100000
input = IISet(range(N)) input = self.mkset(range(N))
output = multiunion([input] * 10) output = self.multiunion([input] * 10)
self.assertEqual(len(output), N) self.assertEqual(len(output), N)
self.assertEqual(output.minKey(), 0) self.assertEqual(output.minKey(), 0)
self.assertEqual(output.maxKey(), N-1) self.assertEqual(output.maxKey(), N-1)
...@@ -233,32 +235,43 @@ class TestMultiUnion(TestCase): ...@@ -233,32 +235,43 @@ class TestMultiUnion(TestCase):
from random import shuffle from random import shuffle
N = 5000 N = 5000
inputs = [] inputs = []
mkset, mktreeset = self.mkset, self.mktreeset
for i in range(N): for i in range(N):
base = i * 4 - N base = i * 4 - N
inputs.append(IISet([base, base+1])) inputs.append(mkset([base, base+1]))
inputs.append(IITreeSet([base+2, base+3])) inputs.append(mktreeset([base+2, base+3]))
shuffle(inputs) shuffle(inputs)
output = multiunion(inputs) output = self.multiunion(inputs)
self.assertEqual(len(output), N*4) self.assertEqual(len(output), N*4)
self.assertEqual(list(output), range(-N, 3*N)) self.assertEqual(list(output), range(-N, 3*N))
def testFunkyKeyIteration(self): def testFunkyKeyIteration(self):
# The internal set iteration protocol allows "iterating over" a # The internal set iteration protocol allows "iterating over" a
# a single key as if it were a set. # a single key as if it were a set.
from BTrees.IIBTree import union
N = 100 N = 100
slow = IISet() union, mkset = self.union, self.mkset
slow = mkset()
for i in range(N): for i in range(N):
slow = union(slow, IISet([i])) slow = union(slow, mkset([i]))
fast = multiunion(range(N)) # acts like N distinct singleton sets fast = self.multiunion(range(N)) # acts like N distinct singleton sets
self.assertEqual(len(slow), N) self.assertEqual(len(slow), N)
self.assertEqual(len(fast), N) self.assertEqual(len(fast), N)
self.assertEqual(list(slow.keys()), list(fast.keys())) self.assertEqual(list(slow.keys()), list(fast.keys()))
self.assertEqual(list(fast.keys()), range(N)) self.assertEqual(list(fast.keys()), range(N))
class TestIIMultiUnion(MultiUnion):
from BTrees.IIBTree import multiunion, union
from BTrees.IIBTree import IISet as mkset, IITreeSet as mktreeset
from BTrees.IIBTree import IIBucket as mkbucket, IIBTree as mkbtree
class TestIOMultiUnion(MultiUnion):
from BTrees.IOBTree import multiunion, union
from BTrees.IOBTree import IOSet as mkset, IOTreeSet as mktreeset
from BTrees.IOBTree import IOBucket as mkbucket, IOBTree as mkbtree
def test_suite(): def test_suite():
s = TestSuite() s = TestSuite()
for klass in (TestMultiUnion, for klass in (TestIIMultiUnion, TestIOMultiUnion,
PureII, PureIO, PureOI, PureOO): PureII, PureIO, PureOI, PureOO):
s.addTest(makeSuite(klass)) s.addTest(makeSuite(klass))
return s return s
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment