[Zope-Checkins] CVS: Zope2 - BTreeTemplate.c:1.9.2.10

Jim Fulton jim@digiciool.com
Wed, 14 Mar 2001 09:53:22 -0500 (EST)


Update of /cvs-repository/Zope2/lib/python/BTrees
In directory korak:/tmp/cvs-serv547

Modified Files:
      Tag: Catalog-BTrees-Integration
	BTreeTemplate.c 
Log Message:
Added conflict resolution for small BTrees and TreeSets (with a single
bucket that hasn't been stored in it's own database record.

Fixed a bug that caused BTrees to be incorrectly marked as changed
when sub-buckets were changed.



--- Updated File BTreeTemplate.c in package Zope2 --
--- BTreeTemplate.c	2001/03/12 17:29:38	1.9.2.9
+++ BTreeTemplate.c	2001/03/14 14:53:22	1.9.2.10
@@ -396,7 +396,7 @@
 _BTree_set(BTree *self, PyObject *keyarg, PyObject *value, 
            int unique, int noval)
 {
-  int i, min, max, cmp, grew, copied=1, changed=0;
+  int i, min, max, cmp, grew, copied=1, changed=0, bchanged=0;
   BTreeItem *d;
   KEY_TYPE key;
 
@@ -436,11 +436,13 @@
   if (SameType_Check(self, d->value))
     grew= _BTree_set( BTREE(d->value), keyarg, value, unique, noval);
   else
-    grew=_bucket_set(BUCKET(d->value), keyarg, value, unique, noval, &changed);
+    grew=_bucket_set(BUCKET(d->value), keyarg, value, unique, noval, 
+                     &bchanged);
   if (grew < 0) goto err;
 
   if (grew)
     {
+      bchanged=1;               /* A bucket changed size */
       if (value)			/* got bigger */
 	{
           if (SameType_Check(self, d->value))
@@ -530,9 +532,10 @@
 
 #ifdef PERSISTENT
   if (changed 
-      || (self->len == 1 
-          && ! SameType_Check(self, self->data->value)
-          && BUCKET(self->data->value)->oid == NULL
+      || (bchanged                                     /* The bucket changed */
+          && self->len == 1                            /* We have only one   */
+          && ! SameType_Check(self, self->data->value) /* It's our child     */
+          && BUCKET(self->data->value)->oid == NULL    /* It's in our record */
           )
       ) 
     if (PER_CHANGED(self) < 0) 
@@ -808,6 +811,35 @@
   return Py_None;
 }
 
+#ifdef PERSISTENT
+static PyObject *
+BTree__p_resolveConflict(BTree *self, PyObject *args)
+{
+  PyObject *s[3], *r;
+  int i;
+
+  UNLESS (PyArg_ParseTuple(args, "OOO", s, s+1, s+2)) return NULL;
+
+                                /* for each state, detuplefy it twice */
+  for (i=0; i < 3; i++)
+    UNLESS (s[i]==Py_None || PyArg_ParseTuple(s[i], "O", s+i)) return NULL;
+  for (i=0; i < 3; i++)
+    UNLESS (s[i]==Py_None || PyArg_ParseTuple(s[i], "O", s+i)) return NULL;
+
+  for (i=0; i < 3; i++)         /* Now make sure detupled thing is a tuple */
+    UNLESS (s[i]==Py_None || PyTuple_Check(s[i]))
+      return merge_error(-100, -100, -100, -100);
+
+  if (ExtensionClassSubclassInstance_Check(self, &BTreeType))
+      r = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
+  else
+      r = _bucket__p_resolveConflict(OBJECT(&SetType), s);
+
+  if (r) ASSIGN(r, Py_BuildValue("((O))", r));
+
+  return r;
+}
+#endif
 
 /*
  BTree_findRangeEnd -- Find one end, expressed as a bucket and
@@ -1197,6 +1229,8 @@
   {"__init__",	(PyCFunction) Mapping_update,	METH_VARARGS,
    "__init__(collection) -- Initialize with items from the given collection"},
 #ifdef PERSISTENT
+  {"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
+   "_p_resolveConflict() -- Reinitialize from a newly created copy"},
   {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_VARARGS,
    "_p_deactivate() -- Reinitialize from a newly created copy"},
 #endif