Commit 57145891 authored by Jim Fulton's avatar Jim Fulton

Added logic to updated the access time on BTree data structures as

they are used. This is important to keep used data structures in
memory when the ZODB garbage collector is busy.

Added Id strings.
parent 8c67e57e
......@@ -83,6 +83,8 @@
****************************************************************************/
#define BTREEITEMSTEMPLATE_C "$Id: BTreeItemsTemplate.c,v 1.6 2001/03/20 13:52:00 jim Exp $\n"
typedef struct {
PyObject_HEAD
Bucket *firstbucket; /* First bucket known */
......@@ -141,11 +143,13 @@ BTreeItems_length_or_nonzero(BTreeItems *self, int nonzero)
Py_INCREF(next);
PER_ALLOW_DEACTIVATION(b);
PER_ACCESSED(b);
Py_DECREF(b);
b=next;
PER_USE_OR_RETURN(b, -1);
}
PER_ALLOW_DEACTIVATION(b);
PER_ACCESSED(b);
Py_DECREF(b);
return r >= 0 ? r : 0;
......@@ -255,6 +259,7 @@ BTreeItems_seek(BTreeItems *self, int i)
if (b==NULL) goto no_match;
PER_ALLOW_DEACTIVATION(currentbucket);
PER_ACCESSED(currentbucket);
ASSIGNB(currentbucket, b);
UNLESS (PER_USE(currentbucket)) goto err;
......@@ -294,6 +299,7 @@ BTreeItems_seek(BTreeItems *self, int i)
pseudoindex += (currentbucket->len - currentoffset);
Py_INCREF(b);
PER_ALLOW_DEACTIVATION(currentbucket);
PER_ACCESSED(currentbucket);
ASSIGNB(currentbucket, b);
UNLESS (PER_USE(currentbucket)) goto err;
currentoffset = 0;
......
......@@ -83,11 +83,6 @@
****************************************************************************/
static char BTree_module_documentation[] =
""
"\n$Id: BTreeModuleTemplate.c,v 1.6 2001/03/15 17:33:07 brian Exp $"
;
#ifdef PERSISTENT
#include "cPersistence.h"
......@@ -101,8 +96,12 @@ static char BTree_module_documentation[] =
? (((O)->state==cPersistent_UPTODATE_STATE) \
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
#define PER_ACCESSED(O) ((O)->atime=((long)(time(NULL)/3))%65536)
#endif
/***************************************************************/
#else
#include "ExtensionClass.h"
#define PER_USE_OR_RETURN(self, NULL)
......@@ -110,9 +109,11 @@ static char BTree_module_documentation[] =
#define PER_PREVENT_DEACTIVATION(self)
#define PER_DEL(self)
#define PER_USE(O) 1
#define PER_ACCESSED(O) 1
#define PER_CHANGED(O) 0
#endif
static PyObject *sort_str, *reverse_str, *items_str, *__setstate___str;
static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;}
......@@ -213,6 +214,7 @@ PreviousBucket(Bucket *current, Bucket *first, int i)
if (first->next==current)
{
PER_ALLOW_DEACTIVATION(first);
PER_ACCESSED(first);
return first;
}
else if (first->next)
......@@ -220,12 +222,14 @@ PreviousBucket(Bucket *current, Bucket *first, int i)
Bucket *next = first->next;
Py_INCREF(next);
PER_ALLOW_DEACTIVATION(first);
PER_ACCESSED(first);
Py_DECREF(first);
first=next;
}
else
{
PER_ALLOW_DEACTIVATION(first);
PER_ACCESSED(first);
Py_DECREF(first);
IndexError(i);
return NULL;
......@@ -330,6 +334,22 @@ static struct PyMethodDef module_methods[] = {
{NULL, NULL} /* sentinel */
};
static char BTree_module_documentation[] =
"\n"
MASTER_ID
BTREEITEMSTEMPLATE_C
"$Id: BTreeModuleTemplate.c,v 1.7 2001/03/20 13:52:00 jim Exp $\n"
BTREETEMPLATE_C
BUCKETTEMPLATE_C
KEYMACROS_H
MERGETEMPLATE_C
SETOPTEMPLATE_C
SETTEMPLATE_C
TREESETTEMPLATE_C
VALUEMACROS_H
BTREEITEMSTEMPLATE_C
;
void
INITMODULE ()
{
......@@ -387,7 +407,7 @@ INITMODULE ()
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "__version__",
PyString_FromString("$Revision: 1.6 $"));
PyString_FromString("$Revision: 1.7 $"));
PyExtensionClass_Export(d,MOD_NAME_PREFIX "Bucket", BucketType);
PyExtensionClass_Export(d,MOD_NAME_PREFIX "BTree", BTreeType);
......
......@@ -83,6 +83,8 @@
****************************************************************************/
#define BTREETEMPLATE_C "$Id: BTreeTemplate.c,v 1.12 2001/03/20 13:52:00 jim Exp $\n"
/*
** _BTree_get
**
......@@ -132,6 +134,7 @@ _BTree_get(BTree *self, PyObject *keyarg, int has_key)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
}
......@@ -168,6 +171,7 @@ BTree_split(BTree *self, int index, BTree *next)
next->firstbucket = BTREE(next->data->value)->firstbucket;
Py_XINCREF(next->firstbucket);
PER_ALLOW_DEACTIVATION(BTREE(next->data->value));
PER_ACCESSED(BTREE(next->data->value));
}
else
{
......@@ -175,6 +179,7 @@ BTree_split(BTree *self, int index, BTree *next)
Py_XINCREF(next->firstbucket);
}
PER_CHANGED(self);
return 0;
}
......@@ -360,6 +365,7 @@ BTree_lastBucket(BTree *self)
PER_USE_OR_RETURN(self, NULL);
ASSIGN(o, OBJECT(BTree_lastBucket(self)));
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return BUCKET(o);
}
......@@ -374,6 +380,9 @@ BTree_deleteNextBucket(BTree *self)
UNLESS (b=BTree_lastBucket(self)) goto err;
if (Bucket_deleteNextBucket(b) < 0) goto err;
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
err:
......@@ -511,6 +520,7 @@ _BTree_set(BTree *self, PyObject *keyarg, PyObject *value,
BTREE(self->data->value)->firstbucket);
Py_XINCREF(self->firstbucket);
PER_ALLOW_DEACTIVATION(BTREE(self->data->value));
PER_ACCESSED(BTREE(self->data->value));
}
else
{
......@@ -544,10 +554,12 @@ _BTree_set(BTree *self, PyObject *keyarg, PyObject *value,
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return grew;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return -1;
}
......@@ -642,12 +654,14 @@ BTree_clear(BTree *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_INCREF(Py_None);
return Py_None;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return NULL;
}
......@@ -701,11 +715,13 @@ BTree_getstate(BTree *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return NULL;
}
......@@ -805,6 +821,7 @@ BTree_setstate(BTree *self, PyObject *args)
PER_PREVENT_DEACTIVATION(self);
r=_BTree_setstate(self, args, 0);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (r < 0) return NULL;
Py_INCREF(Py_None);
......@@ -882,6 +899,7 @@ BTree_findRangeEnd(BTree *self, PyObject *keyarg, int low,
PER_USE_OR_RETURN(self, -1);
i = BTree_findRangeEnd(self, keyarg, low, bucket, offset);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
}
else
{
......@@ -916,6 +934,7 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
goto empty;
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
PER_USE_OR_RETURN(bucket, NULL);
}
else if (min)
......@@ -923,6 +942,7 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
bucket = self->firstbucket;
Py_INCREF(bucket);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
PER_USE_OR_RETURN(bucket, NULL);
offset = 0;
if (offset >= bucket->len)
......@@ -938,6 +958,7 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
{
bucket = BTree_lastBucket(self);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
PER_USE_OR_RETURN(bucket, NULL);
if (bucket->len)
offset = bucket->len - 1;
......@@ -953,6 +974,7 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
COPY_KEY_TO_OBJECT(key, bucket->keys[offset]);
PER_ALLOW_DEACTIVATION(bucket);
PER_ACCESSED(bucket);
Py_DECREF(bucket);
return key;
......@@ -962,9 +984,11 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (bucket)
{
PER_ALLOW_DEACTIVATION(bucket);
PER_ACCESSED(bucket);
Py_DECREF(bucket);
}
return NULL;
......@@ -1039,9 +1063,11 @@ BTree_rangeSearch(BTree *self, PyObject *args, char type)
UNLESS (PER_USE(highbucket)) goto err;
highoffset = highbucket->len - 1;
PER_ALLOW_DEACTIVATION(highbucket);
PER_ACCESSED(highbucket);
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
f=newBTreeItems(type, lowbucket, lowoffset, highbucket, highoffset);
Py_DECREF(lowbucket);
......@@ -1050,10 +1076,12 @@ BTree_rangeSearch(BTree *self, PyObject *args, char type)
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return NULL;
empty:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return newBTreeItems(type, 0, 0, 0, 0);
}
......@@ -1141,10 +1169,12 @@ BTree_byValue(BTree *self, PyObject *args)
Py_DECREF(item);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(r);
Py_XDECREF(it.set);
Py_XDECREF(item);
......@@ -1258,6 +1288,7 @@ BTree_length_or_nonzero(BTree *self, int nonzero)
b = self->firstbucket;
Py_XINCREF(b);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
while (b != NULL)
{
......@@ -1267,12 +1298,14 @@ BTree_length_or_nonzero(BTree *self, int nonzero)
{
/* Short-circuit if all we care about is nonempty */
PER_ALLOW_DEACTIVATION(b);
PER_ACCESSED(b);
Py_DECREF(b);
return 1;
}
n = b->next;
Py_XINCREF(n);
PER_ALLOW_DEACTIVATION(b);
PER_ACCESSED(b);
ASSIGNB(b, n);
}
......
......@@ -82,6 +82,8 @@
****************************************************************************/
#define BUCKETTEMPLATE_C "$Id: BucketTemplate.c,v 1.9 2001/03/20 13:52:00 jim Exp $\n"
/*
** _bucket_get
**
......@@ -117,12 +119,14 @@ _bucket_get(Bucket *self, PyObject *keyarg, int has_key)
COPY_VALUE_TO_OBJECT(r, self->values[i]);
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
}
else max=i;
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (has_key) return PyInt_FromLong(0);
PyErr_SetObject(PyExc_KeyError, keyarg);
return NULL;
......@@ -213,6 +217,7 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
if (VALUE_SAME(self->values[i], value))
{ /* short-circuit if no change */
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
}
#endif
......@@ -223,6 +228,7 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
if (PER_CHANGED(self) < 0) goto err;
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
}
else /* There's no value so remove the item */
......@@ -257,6 +263,7 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
if (PER_CHANGED(self) < 0) goto err;
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 1;
}
}
......@@ -297,10 +304,12 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
if (PER_CHANGED(self) < 0) goto err;
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 1;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return -1;
}
......@@ -420,6 +429,8 @@ bucket_split(Bucket *self, int index, Bucket *next)
Py_INCREF(next);
self->next = next;
PER_CHANGED(self);
return 0;
}
......@@ -430,6 +441,7 @@ Bucket_nextBucket(Bucket *self, Bucket **r)
*r=self->next;
Py_XINCREF(*r);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
}
......@@ -445,9 +457,11 @@ Bucket_deleteNextBucket(Bucket *self)
PER_CHANGED(self);
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return -1;
}
/*
......@@ -486,6 +500,7 @@ Bucket_findRangeEnd(Bucket *self, PyObject *keyarg, int low, int *offset)
else if (cmp == 0)
{
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
*offset=i;
return 1;
}
......@@ -516,6 +531,7 @@ Bucket_findRangeEnd(Bucket *self, PyObject *keyarg, int low, int *offset)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return i;
}
......@@ -546,6 +562,7 @@ Bucket_maxminKey(Bucket *self, PyObject *args, int min)
COPY_KEY_TO_OBJECT(key, self->keys[offset]);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return key;
......@@ -554,6 +571,7 @@ Bucket_maxminKey(Bucket *self, PyObject *args, int min)
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return NULL;
}
......@@ -638,10 +656,12 @@ bucket_keys(Bucket *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(r);
return NULL;
}
......@@ -676,10 +696,12 @@ bucket_values(Bucket *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(r);
return NULL;
}
......@@ -724,10 +746,12 @@ bucket_items(Bucket *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(r);
Py_XDECREF(item);
return NULL;
......@@ -787,10 +811,12 @@ bucket_byValue(Bucket *self, PyObject *args)
Py_DECREF(item);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(r);
Py_XDECREF(item);
return NULL;
......@@ -856,11 +882,13 @@ bucket_clear(Bucket *self, PyObject *args)
if (PER_CHANGED(self) < 0) goto err;
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_INCREF(Py_None);
return Py_None;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return NULL;
}
......@@ -909,11 +937,13 @@ bucket_getstate(Bucket *self, PyObject *args)
ASSIGN(items, Py_BuildValue("(O)", items));
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return items;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
Py_XDECREF(items);
return NULL;
}
......@@ -981,6 +1011,7 @@ _bucket_setstate(Bucket *self, PyObject *args)
}
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return 0;
}
......@@ -995,6 +1026,7 @@ bucket_setstate(Bucket *self, PyObject *args)
PER_PREVENT_DEACTIVATION(self);
r=_bucket_setstate(self, args);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (r < 0) return NULL;
Py_INCREF(Py_None);
......@@ -1160,6 +1192,7 @@ Bucket_length( Bucket *self)
PER_USE_OR_RETURN(self, -1);
r=self->len;
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
}
......@@ -1225,10 +1258,10 @@ static PyExtensionClass BucketType = {
static int
nextBucket(SetIteration *i)
{
UNLESS(PER_USE(BUCKET(i->set))) return -1;
if (i->position >= 0)
{
UNLESS(PER_USE(BUCKET(i->set))) return -1;
if (i->position)
{
DECREF_KEY(i->key);
......@@ -1244,10 +1277,14 @@ nextBucket(SetIteration *i)
i->position ++;
}
else
{
i->position = -1;
PER_ACCESSED(BUCKET(i->set));
}
PER_ALLOW_DEACTIVATION(BUCKET(i->set));
}
return 0;
}
/* Setup template macros */
#define MASTER_ID "$Id: IIBTree.c,v 1.8 2001/03/20 13:52:00 jim Exp $\n"
#define PERSISTENT
#define MOD_NAME_PREFIX "II"
......
#define MASTER_ID "$Id: IOBTree.c,v 1.9 2001/03/20 13:52:00 jim Exp $\n"
#define PERSISTENT
#define MOD_NAME_PREFIX "IO"
......
......@@ -83,6 +83,8 @@
****************************************************************************/
#define MERGETEMPLATE_C "$Id: MergeTemplate.c,v 1.3 2001/03/20 13:52:00 jim Exp $\n"
/****************************************************************************
Set operations
****************************************************************************/
......
#define MASTER_ID "$Id: OIBTree.c,v 1.7 2001/03/20 13:52:00 jim Exp $\n"
#define PERSISTENT
#define MOD_NAME_PREFIX "OI"
......
#define MASTER_ID "$Id: OOBTree.c,v 1.7 2001/03/20 13:52:00 jim Exp $\n"
#define PERSISTENT
#define MOD_NAME_PREFIX "OO"
......
......@@ -87,24 +87,30 @@
Set operations
****************************************************************************/
#define SETOPTEMPLATE_C "$Id: SetOpTemplate.c,v 1.5 2001/03/20 13:52:00 jim Exp $\n"
#ifdef INTSET_H
static int
nextIntSet(SetIteration *i)
{
UNLESS(PER_USE(INTSET(i->set))) return -1;
if (i->position >= 0)
{
UNLESS(PER_USE(INTSET(i->set))) return -1;
if (i->position < INTSET(i->set)->len)
{
i->key = INTSET(i->set)->data[i->position];
i->position ++;
}
else
{
i->position = -1;
PER_ACCESSED(INTSET(i->set));
}
PER_ALLOW_DEACTIVATION(INTSET(i->set));
}
return 0;
}
......
......@@ -83,6 +83,8 @@
****************************************************************************/
#define SETTEMPLATE_C "$Id: SetTemplate.c,v 1.9 2001/03/20 13:52:00 jim Exp $\n"
static PyObject *
Set_insert(Bucket *self, PyObject *args)
{
......@@ -203,6 +205,7 @@ set_setstate(Bucket *self, PyObject *args)
PER_PREVENT_DEACTIVATION(self);
r=_set_setstate(self, args);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (r < 0) return NULL;
Py_INCREF(Py_None);
......@@ -271,6 +274,7 @@ set_length(Bucket *self)
PER_USE_OR_RETURN(self, -1);
r = self->len;
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
}
......@@ -289,6 +293,7 @@ set_item(Bucket *self, int index)
IndexError(index);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return r;
}
......@@ -339,10 +344,11 @@ static PyExtensionClass SetType = {
static int
nextSet(SetIteration *i)
{
UNLESS(PER_USE(BUCKET(i->set))) return -1;
if (i->position >= 0)
{
UNLESS(PER_USE(BUCKET(i->set))) return -1;
if (i->position)
{
DECREF_KEY(i->key);
......@@ -355,10 +361,14 @@ nextSet(SetIteration *i)
i->position ++;
}
else
{
i->position = -1;
PER_ACCESSED(BUCKET(i->set));
}
PER_ALLOW_DEACTIVATION(BUCKET(i->set));
}
return 0;
}
......@@ -83,6 +83,8 @@
****************************************************************************/
#define TREESETTEMPLATE_C "$Id: TreeSetTemplate.c,v 1.9 2001/03/20 13:52:00 jim Exp $\n"
static PyObject *
TreeSet_insert(BTree *self, PyObject *args)
{
......@@ -151,6 +153,7 @@ TreeSet_setstate(BTree *self, PyObject *args)
PER_PREVENT_DEACTIVATION(self);
r=_BTree_setstate(self, args, 1);
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
if (r < 0) return NULL;
Py_INCREF(Py_None);
......
#define KEYMACROS_H "$Id: intkeymacros.h,v 1.4 2001/03/20 13:52:00 jim Exp $\n"
#define KEY_TYPE int
#define KEY_CHECK PyInt_Check
#define TEST_KEY(K, T) (((K) < (T)) ? -1 : (((K) > (T)) ? 1: 0))
......
#define VALUEMACROS_H "$Id: intvaluemacros.h,v 1.5 2001/03/20 13:52:00 jim Exp $\n"
#define VALUE_TYPE int
#define TEST_VALUE(K, T) (((K) < (T)) ? -1 : (((K) > (T)) ? 1: 0))
#define VALUE_SAME(VALUE, TARGET) ( (VALUE) == (TARGET) )
......
#define KEYMACROS_H "$Id: objectkeymacros.h,v 1.2 2001/03/20 13:52:00 jim Exp $\n"
#define KEY_TYPE PyObject *
#define TEST_KEY(KEY, TARGET) PyObject_Compare((KEY),(TARGET))
#define INCREF_KEY(k) Py_INCREF(k)
......
#define VALUEMACROS_H "$Id: objectvaluemacros.h,v 1.3 2001/03/20 13:52:00 jim Exp $\n"
#define VALUE_TYPE PyObject *
#define TEST_VALUE(VALUE, TARGET) PyObject_Compare((VALUE),(TARGET))
#define DECLARE_VALUE(NAME) VALUE_TYPE NAME
......
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