[Zodb-checkins] CVS: Zope/lib/python/BTrees - BTreeModuleTemplate.c:1.37 MergeTemplate.c:1.15 SetOpTemplate.c:1.26
Tim Peters
tim.one@comcast.net
Tue, 25 Jun 2002 18:02:27 -0400
Update of /cvs-repository/Zope/lib/python/BTrees
In directory cvs.zope.org:/tmp/cvs-serv8056
Modified Files:
BTreeModuleTemplate.c MergeTemplate.c SetOpTemplate.c
Log Message:
A step on the way to repairing negative weights used with the weighted
intersection and union functions: get the concept of weight entirely out
of the internal set iteration protocol. The caller wants values, or
doesn't, and that's just a Boolean. This makes for some nice little
internal simplifications, but doesn't yet change any semantics.
=== Zope/lib/python/BTrees/BTreeModuleTemplate.c 1.36 => 1.37 ===
* When you want to iterate over a set or bucket or BTree (even an
* individual key!),
- * 1. Declare a new iterator and a "merge" int:
+ * 1. Declare a new iterator:
* SetIteration si = {0,0,0};
- * int merge = 0;
* Using "{0,0,0}" or "{0,0}" appear most common. Only one {0} is
* necssary. At least one must be given so that finiSetIteration() works
* correctly even if you don't get around to calling initSetIteration().
* 2. Initialize it via
- * initSetIteration(&si, PyObject *s, int weight, &merge)
+ * initSetIteration(&si, PyObject *s, useValues)
* It's an error if that returns an int < 0. In case of error on the
* init call, calling finiSetIteration(&si) is optional. But if the
* init call succeeds, you must eventually call finiSetIteration(),
@@ -200,8 +199,7 @@
* If the set isn't empty, this sets si.position to an int >= 0,
* si.key to the element's key (of type KEY_TYPE), and maybe si.value to
* the element's value (of type VALUE_TYPE). si.value is defined
- * iff merge was set to true by the initSetIteration() call, which is
- * equivalent to whether si.usesValue is true.
+ * iff si.usesValue is true.
* 4. Process all the elements:
* while (si.position >= 0) {
* do something with si.key and/or si.value;
@@ -219,7 +217,6 @@
PyObject *set; /* the set, bucket, BTree, ..., being iterated */
int position; /* initialized to 0; set to -1 by next() when done */
int usesValue; /* true iff 'set' has values & we iterate them */
- int hasValue; /* true iff 'set' has values (as well as keys) */
KEY_TYPE key; /* next() sets to next key */
VALUE_TYPE value; /* next() may set to next value */
int (*next)(struct SetIteration_s*); /* function to get next key+value */
=== Zope/lib/python/BTrees/MergeTemplate.c 1.14 => 1.15 ===
PyObject *s;
SetIteration i1 = {0,0,0}, i2 = {0,0,0}, i3 = {0,0,0};
- int cmp12, cmp13, cmp23, mapping=0, set;
+ int cmp12, cmp13, cmp23, mapping, set;
- if (initSetIteration(&i1, OBJECT(s1), 0, &mapping) < 0) goto err;
- if (initSetIteration(&i2, OBJECT(s2), 0, &mapping) < 0) goto err;
- if (initSetIteration(&i3, OBJECT(s3), 0, &mapping) < 0) goto err;
+ if (initSetIteration(&i1, OBJECT(s1), 1) < 0) goto err;
+ if (initSetIteration(&i2, OBJECT(s2), 1) < 0) goto err;
+ if (initSetIteration(&i3, OBJECT(s3), 1) < 0) goto err;
+ mapping = i1.usesValue | i2.usesValue | i3.usesValue;
set = ! mapping;
if (mapping)
=== Zope/lib/python/BTrees/SetOpTemplate.c 1.25 => 1.26 ===
*
* Arguments
- * i The address of a SetIteration control struct.
- * s The address of the set, bucket, BTree, ..., to be iterated.
- * w If w < 0, ignore values when iterating.
- * merge Is set to 1 if s has values (as well as keys) and w >= 0.
- * The value on input is ignored.
+ * i The address of a SetIteration control struct.
+ * s The address of the set, bucket, BTree, ..., to be iterated.
+ * useValues Boolean; if true, and s has values (is a mapping), copy
+ * them into i->value each time i->next() is called; else
+ * ignore s's values even if s is a mapping.
*
* Return
* 0 on success; -1 and an exception set if error.
- * *merge is set to 1 if s has values and w >= 0, else merge is left
- * alone.
- * i.usesValue is also set to 1 if s has values and w >= 0, else
- * .usesValue is set to 0.
+ * i.usesValue is set to 1 (true) if s has values and useValues was
+ * true; else usesValue is set to 0 (false).
* i.set gets a new reference to s, or to some other object used to
* iterate over s.
* i.position is set to 0.
- * i.hasValue is set to true if s has values, and to false otherwise.
- * Note that this is done independent of w's value, and when w < 0
- * may differ from i.usesValue.
* i.next is set to an appropriate iteration function.
* i.key and i.value are left alone.
*
@@ -102,20 +97,18 @@
* A SetIteration struct has been cleaned up iff i.set is NULL.
*/
static int
-initSetIteration(SetIteration *i, PyObject *s, int w, int *merge)
+initSetIteration(SetIteration *i, PyObject *s, int useValues)
{
i->set = NULL;
i->position = -1; /* set to 0 only on normal return */
- i->hasValue = 0; /* assume it's a set */
i->usesValue = 0; /* assume it's a set or that values aren't iterated */
if (ExtensionClassSubclassInstance_Check(s, &BucketType))
{
i->set = s;
Py_INCREF(s);
- i->hasValue = 1;
- if (w >= 0)
+ if (useValues)
{
i->usesValue = 1;
i->next = nextBucket;
@@ -133,9 +126,8 @@
{
i->set = BTree_rangeSearch(BTREE(s), NULL, 'i');
UNLESS(i->set) return -1;
- i->hasValue = 1;
- if (w >= 0)
+ if (useValues)
{
i->usesValue = 1;
i->next = nextBTreeItems;
@@ -176,7 +168,6 @@
return -1;
}
- *merge |= i->usesValue;
i->position = 0;
return 0;
@@ -214,17 +205,18 @@
{
Bucket *r=0;
SetIteration i1 = {0,0,0}, i2 = {0,0,0};
- int cmp, merge=0;
+ int cmp, merge;
- if (initSetIteration(&i1, s1, w1, &merge) < 0) goto err;
- if (initSetIteration(&i2, s2, w2, &merge) < 0) goto err;
+ if (initSetIteration(&i1, s1, w1 >= 0) < 0) goto err;
+ if (initSetIteration(&i2, s2, w2 >= 0) < 0) goto err;
+ merge = i1.usesValue | i2.usesValue;
if (merge)
{
#ifndef MERGE
- if (c12 && i1.hasValue && i2.hasValue) goto invalid_set_operation;
+ if (c12 && i1.usesValue && i2.usesValue) goto invalid_set_operation;
#endif
- if (! i1.hasValue && i2.hasValue)
+ if (! i1.usesValue && i2.usesValue)
{
SetIteration t;
int i;
@@ -237,9 +229,9 @@
i1.value=MERGE_DEFAULT;
i2.value=MERGE_DEFAULT;
#else
- if (i1.hasValue)
+ if (i1.usesValue)
{
- if (! i2.hasValue && c2) goto invalid_set_operation;
+ if (! i2.usesValue && c2) goto invalid_set_operation;
}
else
{
@@ -506,9 +498,7 @@
}
else {
/* No cheap way: iterate over set's elements one at a time. */
- int merge; /* dummy needed for initSetIteration */
-
- if (initSetIteration(&setiter, set, -1, &merge) < 0) goto Error;
+ if (initSetIteration(&setiter, set, 0) < 0) goto Error;
if (setiter.next(&setiter) < 0) goto Error;
while (setiter.position >= 0) {
if (result->len >= result->size && Bucket_grow(result, -1, 1) < 0)