Commit 9d49fa3f authored by Jim Fulton's avatar Jim Fulton

Fixed major bug in (de)activation control logic.

parent 9bc6638b
...@@ -53,17 +53,21 @@ ...@@ -53,17 +53,21 @@
static char Trie_module_documentation[] = static char Trie_module_documentation[] =
"" ""
"\n$Id: Trie.c,v 1.9 1997/05/19 17:49:35 jim Exp $" "\n$Id: Trie.c,v 1.10 1997/06/06 19:36:36 jim Exp $"
; ;
#define PERSISTENT #define PERSISTENT 1
/* Note that I haven't put ifdefs everywhere they apply yet. */ /* Note that I haven't put ifdefs everywhere they apply yet. */
#ifdef PERSISTENT #ifdef PERSISTENT
# include "cPersistence.h" # include "cPersistence.h"
#else #else
# include "ExtensionClass.h" # include "ExtensionClass.h"
# define PER_PREVENT_DEACTIVATION(SELF)
# define PER_ALLOW_DEACTIVATION(SELF)
# define PER_CHANGED(O) 0
# define PER_USE_OR_RETURN(O,R)
#endif #endif
static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;} static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;}
...@@ -92,6 +96,8 @@ staticforward PyExtensionClass TrieType; ...@@ -92,6 +96,8 @@ staticforward PyExtensionClass TrieType;
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
#ifdef PERSISTENT
static PyObject * static PyObject *
PER_RETURN(TrieObject *self, PyObject *r) PER_RETURN(TrieObject *self, PyObject *r)
{ {
...@@ -106,6 +112,11 @@ PER_INT_RETURN(TrieObject *self, int r) ...@@ -106,6 +112,11 @@ PER_INT_RETURN(TrieObject *self, int r)
return r; return r;
} }
#else
#define PER_RETURN(SELF,R) R
#define PER_INT_RETURN(SELF,R) R
#endif
static PyObject * static PyObject *
Trie___setstate__(TrieObject *self, PyObject *args) Trie___setstate__(TrieObject *self, PyObject *args)
{ {
...@@ -113,9 +124,7 @@ Trie___setstate__(TrieObject *self, PyObject *args) ...@@ -113,9 +124,7 @@ Trie___setstate__(TrieObject *self, PyObject *args)
UNLESS(PyArg_ParseTuple(args, "O", &state)) return NULL; UNLESS(PyArg_ParseTuple(args, "O", &state)) return NULL;
#ifdef PERSISTENT
PER_PREVENT_DEACTIVATION(self); PER_PREVENT_DEACTIVATION(self);
#endif
if(state != Py_None) if(state != Py_None)
{ {
...@@ -142,10 +151,7 @@ Trie___getstate__(TrieObject *self, PyObject *args) ...@@ -142,10 +151,7 @@ Trie___getstate__(TrieObject *self, PyObject *args)
UNLESS(PyArg_ParseTuple(args, "")) return NULL; UNLESS(PyArg_ParseTuple(args, "")) return NULL;
#ifdef PERSISTENT PER_USE_OR_RETURN(self, NULL);
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) PER_RETURN(self, NULL);
#endif
if(self->value) if(self->value)
if(self->bins) if(self->bins)
...@@ -194,10 +200,7 @@ getiork(TrieObject *self, PyObject * r, keybuf *buf, int l, int dokeys) ...@@ -194,10 +200,7 @@ getiork(TrieObject *self, PyObject * r, keybuf *buf, int l, int dokeys)
int i; int i;
PyObject *item=0; PyObject *item=0;
#ifdef PERSISTENT PER_USE_OR_RETURN(self, NULL);
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) return PER_RETURN(self, NULL);
#endif
if(self->value) if(self->value)
{ {
...@@ -280,10 +283,7 @@ Trie_keys(TrieObject *self, PyObject *args) ...@@ -280,10 +283,7 @@ Trie_keys(TrieObject *self, PyObject *args)
static PyObject * static PyObject *
Trie_cvalues(TrieObject *self, PyObject *r) Trie_cvalues(TrieObject *self, PyObject *r)
{ {
#ifdef PERSISTENT PER_USE_OR_RETURN(self, NULL);
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) return PER_RETURN(self, NULL);
#endif
if(self->value) if(self->value)
if(PyList_Append(r,self->value) < 0) return PER_RETURN(self, NULL); if(PyList_Append(r,self->value) < 0) return PER_RETURN(self, NULL);
...@@ -335,12 +335,10 @@ Trie_cclear(TrieObject *self) ...@@ -335,12 +335,10 @@ Trie_cclear(TrieObject *self)
{ {
#ifdef PERSISTENT #ifdef PERSISTENT
int changed=0; int changed=0;
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0)
return PER_INT_RETURN(self, -1);
#endif #endif
PER_USE_OR_RETURN(self, -1);
if(self->value) if(self->value)
{ {
Py_DECREF(self->value); Py_DECREF(self->value);
...@@ -380,8 +378,7 @@ Trie_cclear(TrieObject *self) ...@@ -380,8 +378,7 @@ Trie_cclear(TrieObject *self)
} }
#ifdef PERSISTENT #ifdef PERSISTENT
if(changed && cPersistenceCAPI->changed(PyOb(self)) < 0) if(changed && PER_CHANGED(self) < 0) return PER_INT_RETURN(self, -1);
return PER_INT_RETURN(self, -1);
#endif #endif
return PER_INT_RETURN(self, 0); return PER_INT_RETURN(self, 0);
...@@ -430,39 +427,48 @@ Trie_cget(TrieObject *self, char *word, PyObject *oword) ...@@ -430,39 +427,48 @@ Trie_cget(TrieObject *self, char *word, PyObject *oword)
{ {
int c; int c;
char *k; char *k;
PyObject *bins; PyObject *bins, *bin;
PyTypeObject *typ; PyTypeObject *typ;
PyObject *key; PyObject *key;
#ifdef PERSISTENT PER_USE_OR_RETURN(self, NULL);
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) return PER_RETURN(self, NULL);
#endif
typ=self->ob_type; typ=self->ob_type;
Py_INCREF(self);
while(c=*word++) while(c=*word++)
{ {
if(! (bins=self->bins) || c < self->min) if(! (bins=self->bins) || c < self->min) goto not_found;
return PER_RETURN(self, NotFoundError(oword));
c-=self->min; c-=self->min;
if(c >= PyList_SIZE(bins)) return PER_RETURN(self, NotFoundError(oword)); if(c >= PyList_SIZE(bins)) goto not_found;
self=(TrieObject *)PyList_GET_ITEM(LIST(bins), c); bin=PyList_GET_ITEM(LIST(bins), c);
if(self->ob_type != typ) Py_INCREF(bin);
if(PyTuple_Check(PyOb(self)) && PER_ALLOW_DEACTIVATION(self);
PyString_Check((key=PyTuple_GET_ITEM(PyOb(self),0))) && Py_DECREF(self);
strcmp(word,PyString_AS_STRING(STRING(key)))==0) if(bin->ob_type != typ)
return PER_RETURN(self, PySequence_GetItem(PyOb(self),1)); {
else if(PyTuple_Check(bin) &&
return PER_RETURN(self, NotFoundError(oword)); PyString_Check((key=PyTuple_GET_ITEM(bin,0))) &&
strcmp(word,PyString_AS_STRING(STRING(key)))==0
#ifdef PERSISTENT )
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) ASSIGN(bin,PySequence_GetItem(bin,1));
return PER_RETURN(self, NULL); else
#endif ASSIGN(bin,NotFoundError(oword));
return bin;
}
self=(TrieObject *)bin;
PER_USE_OR_RETURN(self, NULL);
} }
if(! self->value) return PER_RETURN(self, NotFoundError(oword)); if(! self->value) return PER_RETURN(self, NotFoundError(oword));
Py_INCREF(self->value); bin=self->value;
return PER_RETURN(self, self->value); Py_INCREF(bin);
return PER_RETURN(self, bin);
not_found:
PER_ALLOW_DEACTIVATION(self);
Py_DECREF(self);
return NotFoundError(oword);
} }
static int static int
...@@ -472,11 +478,10 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword) ...@@ -472,11 +478,10 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword)
int c, r, max; int c, r, max;
#ifdef PERSISTENT #ifdef PERSISTENT
int ch=0; int ch=0;
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0) goto err;
#endif #endif
PER_USE_OR_RETURN(self, -1);
c=*word++; c=*word++;
if(! c) if(! c)
{ {
...@@ -488,7 +493,7 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword) ...@@ -488,7 +493,7 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword)
Py_XINCREF(v); Py_XINCREF(v);
ASSIGN(self->value, v); ASSIGN(self->value, v);
#ifdef PERSISTENT #ifdef PERSISTENT
if(cPersistenceCAPI->changed(PyOb(self)) < 0) goto err; if(PER_CHANGED(self) < 0) goto err;
PER_ALLOW_DEACTIVATION(self); PER_ALLOW_DEACTIVATION(self);
#endif #endif
return 0; return 0;
...@@ -574,7 +579,7 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword) ...@@ -574,7 +579,7 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword)
r=PyList_SetItem(self->bins, c, bin); r=PyList_SetItem(self->bins, c, bin);
#ifdef PERSISTENT #ifdef PERSISTENT
if(cPersistenceCAPI->changed(PyOb(self)) < 0) goto err; if(PER_CHANGED(self) < 0) goto err;
PER_ALLOW_DEACTIVATION(self); PER_ALLOW_DEACTIVATION(self);
#endif #endif
...@@ -584,16 +589,14 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword) ...@@ -584,16 +589,14 @@ Trie_cset(TrieObject *self, char *word, PyObject *v, PyObject *oword)
r=Trie_cset((TrieObject*)bin,word,v,oword); r=Trie_cset((TrieObject*)bin,word,v,oword);
#ifdef PERSISTENT #ifdef PERSISTENT
if(ch && cPersistenceCAPI->changed(PyOb(self)) < 0) goto err; if(ch && PER_CHANGED(self) < 0) goto err;
PER_ALLOW_DEACTIVATION(self); PER_ALLOW_DEACTIVATION(self);
#endif #endif
return r; return r;
err: err:
Py_XDECREF(bin); Py_XDECREF(bin);
#ifdef PERSISTENT
PER_ALLOW_DEACTIVATION(self); PER_ALLOW_DEACTIVATION(self);
#endif
return -1; return -1;
} }
...@@ -603,11 +606,7 @@ Trie_length(TrieObject *self) ...@@ -603,11 +606,7 @@ Trie_length(TrieObject *self)
int i, li, l=0; int i, li, l=0;
PyObject *bin; PyObject *bin;
#ifdef PERSISTENT PER_USE_OR_RETURN(self, -1);
PER_PREVENT_DEACTIVATION(self);
if(cPersistenceCAPI->setstate(PyOb(self)) < 0)
return PER_INT_RETURN(self, -1);
#endif
if(self->bins) if(self->bins)
for(i=PyList_SIZE(self->bins); --i >= 0; ) for(i=PyList_SIZE(self->bins); --i >= 0; )
...@@ -617,20 +616,7 @@ Trie_length(TrieObject *self) ...@@ -617,20 +616,7 @@ Trie_length(TrieObject *self)
{ {
li=Trie_length((TrieObject*)bin); li=Trie_length((TrieObject*)bin);
if(li < 0) return PER_INT_RETURN(self, li); if(li < 0) return PER_INT_RETURN(self, li);
if(li) l+=li;
l+=li;
else
{
#ifdef PERSISTENT
if(cPersistenceCAPI->changed(PyOb(self)) < 0)
return PER_INT_RETURN(self, -1);
#endif
/* Database management concerns make us leery of this
Py_INCREF(Py_None);
if(PyList_SetItem(self->bins, i, Py_None) < 1)
return PER_INT_RETURN(self, -1);
*/
}
} }
else if(PyTuple_Check(bin)) l++; else if(PyTuple_Check(bin)) l++;
} }
...@@ -763,7 +749,7 @@ void ...@@ -763,7 +749,7 @@ void
initTrie() initTrie()
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.9 $"; char *rev="$Revision: 1.10 $";
UNLESS(ExtensionClassImported) return; UNLESS(ExtensionClassImported) return;
...@@ -803,6 +789,9 @@ initTrie() ...@@ -803,6 +789,9 @@ initTrie()
Revision Log: Revision Log:
$Log: Trie.c,v $ $Log: Trie.c,v $
Revision 1.10 1997/06/06 19:36:36 jim
Fixed major bug in (de)activation control logic.
Revision 1.9 1997/05/19 17:49:35 jim Revision 1.9 1997/05/19 17:49:35 jim
Added logic to disable deactivation during methods. This sort of Added logic to disable deactivation during methods. This sort of
logic will be needed for any C-based persistent object. logic will be needed for any C-based persistent object.
......
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