Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZEO
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
ZEO
Commits
226ee421
Commit
226ee421
authored
Mar 27, 2002
by
Toby Dickenson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merged toby-stiff-cache-branch and toby-unicode-branch
parent
87c6d4a6
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
2669 additions
and
1429 deletions
+2669
-1429
src/BTrees/BTreeTemplate.c
src/BTrees/BTreeTemplate.c
+3
-3
src/BTrees/BucketTemplate.c
src/BTrees/BucketTemplate.c
+2
-2
src/Persistence/cPersistence.c
src/Persistence/cPersistence.c
+107
-12
src/Persistence/cPersistence.h
src/Persistence/cPersistence.h
+19
-5
src/Persistence/cPickleCache.c
src/Persistence/cPickleCache.c
+744
-454
src/ZODB/Connection.py
src/ZODB/Connection.py
+40
-7
src/ZODB/DB.py
src/ZODB/DB.py
+14
-4
src/ZODB/cPersistence.c
src/ZODB/cPersistence.c
+107
-12
src/ZODB/cPersistence.h
src/ZODB/cPersistence.h
+19
-5
src/ZODB/cPickleCache.c
src/ZODB/cPickleCache.c
+744
-454
src/persistent/cPersistence.c
src/persistent/cPersistence.c
+107
-12
src/persistent/cPersistence.h
src/persistent/cPersistence.h
+19
-5
src/persistent/cPickleCache.c
src/persistent/cPickleCache.c
+744
-454
No files found.
src/BTrees/BTreeTemplate.c
View file @
226ee421
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
****************************************************************************/
****************************************************************************/
#define BTREETEMPLATE_C "$Id: BTreeTemplate.c,v 1.2
5 2002/03/08 18:33:01 jeremy
Exp $\n"
#define BTREETEMPLATE_C "$Id: BTreeTemplate.c,v 1.2
6 2002/03/27 10:14:01 htrd
Exp $\n"
/*
/*
** _BTree_get
** _BTree_get
...
@@ -540,7 +540,7 @@ _BTree_clear(BTree *self)
...
@@ -540,7 +540,7 @@ _BTree_clear(BTree *self)
if
(
self
->
firstbucket
)
if
(
self
->
firstbucket
)
{
{
ASSERT
(
self
->
firstbucket
->
ob_refcnt
>
1
,
ASSERT
(
self
->
firstbucket
->
ob_refcnt
>
0
,
"Invalid firstbucket pointer"
,
-
1
);
"Invalid firstbucket pointer"
,
-
1
);
Py_DECREF
(
self
->
firstbucket
);
Py_DECREF
(
self
->
firstbucket
);
self
->
firstbucket
=
NULL
;
self
->
firstbucket
=
NULL
;
...
@@ -573,7 +573,7 @@ BTree__p_deactivate(BTree *self, PyObject *args)
...
@@ -573,7 +573,7 @@ BTree__p_deactivate(BTree *self, PyObject *args)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
)
{
{
if
(
_BTree_clear
(
self
)
<
0
)
return
NULL
;
if
(
_BTree_clear
(
self
)
<
0
)
return
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
PER_GHOSTIFY
(
self
)
;
}
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
...
...
src/BTrees/BucketTemplate.c
View file @
226ee421
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
****************************************************************************/
****************************************************************************/
#define BUCKETTEMPLATE_C "$Id: BucketTemplate.c,v 1.2
8 2002/03/08 18:33:01 jeremy
Exp $\n"
#define BUCKETTEMPLATE_C "$Id: BucketTemplate.c,v 1.2
9 2002/03/27 10:14:01 htrd
Exp $\n"
/*
/*
** _bucket_get
** _bucket_get
...
@@ -809,7 +809,7 @@ bucket__p_deactivate(Bucket *self, PyObject *args)
...
@@ -809,7 +809,7 @@ bucket__p_deactivate(Bucket *self, PyObject *args)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
)
{
{
if
(
_bucket_clear
(
self
)
<
0
)
return
NULL
;
if
(
_bucket_clear
(
self
)
<
0
)
return
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
PER_GHOSTIFY
(
self
)
;
}
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
...
...
src/Persistence/cPersistence.c
View file @
226ee421
...
@@ -14,11 +14,21 @@
...
@@ -14,11 +14,21 @@
static
char
cPersistence_doc_string
[]
=
static
char
cPersistence_doc_string
[]
=
"Defines Persistent mixin class for persistent objects.
\n
"
"Defines Persistent mixin class for persistent objects.
\n
"
"
\n
"
"
\n
"
"$Id: cPersistence.c,v 1.5
0 2002/03/08 18:36:13 jeremy
Exp $
\n
"
;
"$Id: cPersistence.c,v 1.5
1 2002/03/27 10:14:04 htrd
Exp $
\n
"
;
#include <string.h>
#include <string.h>
#include "cPersistence.h"
#include "cPersistence.h"
/* the layout of this struct is the same as the start of ccobject in cPickleCache.c */
struct
ccobject_head_struct
{
PyObject_HEAD
CPersistentRing
ring_home
;
int
non_ghost_count
;
};
#define HOME(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->ring_home)) )
#define NON_GHOST_COUNT(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->non_ghost_count)) )
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
{ \
{ \
PyObject *r; \
PyObject *r; \
\
\
int *count = NON_GHOST_COUNT(self); \
if(count) \
{ \
(*count)++; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \
Py_INCREF(self); \
} \
self->state=cPersistent_CHANGED_STATE; \
self->state=cPersistent_CHANGED_STATE; \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
{ \
{ \
self->state=cPersistent_GHOST_STATE;
\
ghostify(self);
\
return ER; \
return ER; \
} \
} \
self->state=cPersistent_UPTODATE_STATE; \
self->state=cPersistent_UPTODATE_STATE; \
Py_DECREF(r); \
Py_DECREF(r); \
}
}
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) \
if(HOME(self) && self->state>=0) { \
self->ring.prev->next = self->ring.next; \
self->ring.next->prev = self->ring.prev; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; }
/****************************************************************************/
/****************************************************************************/
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
Pertype
;
static
void
accessed
(
cPersistentObject
*
self
)
{
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
}
static
void
ghostify
(
cPersistentObject
*
self
)
{
int
*
count
;
count
=
NON_GHOST_COUNT
(
self
);
if
(
count
&&
(
self
->
state
>=
0
))
{
(
*
count
)
--
;
self
->
ring
.
next
->
prev
=
self
->
ring
.
prev
;
self
->
ring
.
prev
->
next
=
self
->
ring
.
next
;
self
->
ring
.
prev
=
NULL
;
self
->
ring
.
next
=
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
Py_DECREF
(
self
);
}
else
{
self
->
state
=
cPersistent_GHOST_STATE
;
}
}
static
void
deallocated
(
cPersistentObject
*
self
)
{
if
(
self
->
state
>=
0
)
ghostify
(
self
);
if
(
self
->
cache
)
{
PyObject
*
v
=
PyObject_CallMethod
(
self
->
cache
,
"_oid_unreferenced"
,
"O"
,
self
->
oid
);
if
(
!
v
)
PyErr_Clear
();
/* and explode later */
Py_XDECREF
(
v
);
}
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
oid
);
}
static
int
static
int
changed
(
cPersistentObject
*
self
)
changed
(
cPersistentObject
*
self
)
{
{
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
static
PyObject
*
static
PyObject
*
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
dict
;
PyObject
*
dict
,
*
dict2
=
NULL
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
{
{
dict2
=
PyDict_Copy
(
dict
);
PyDict_Clear
(
dict
);
PyDict_Clear
(
dict
);
/* Note that we need to set to ghost state unless we are
/* Note that we need to set to ghost state unless we are
called directly. Methods that override this need to
called directly. Methods that override this need to
do the same! */
do the same! */
self
->
state
=
cPersistent_GHOST_STATE
;
ghostify
(
self
)
;
}
}
/* need to delay releasing the last reference on instance attributes
until after we have finished accounting for losing our state */
if
(
dict2
)
{
PyDict_Clear
(
dict2
);
Py_DECREF
(
dict2
);
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
#endif
#endif
Py_XDECREF
(
self
->
jar
);
deallocated
(
self
);
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
cache
);
Py_DECREF
(
self
->
ob_type
);
Py_DECREF
(
self
->
ob_type
);
PyObject_DEL
(
self
);
PyObject_DEL
(
self
);
}
}
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
{
if
(
HOME
(
self
))
{
int
result
;
if
(
!
v
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not delete the oid of a cached object"
);
return
-
1
;
}
if
(
PyObject_Cmp
(
self
->
oid
,
v
,
&
result
)
<
0
)
return
-
1
;
if
(
result
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not change the oid of a cached object"
);
return
-
1
;
}
}
Py_XINCREF
(
v
);
Py_XINCREF
(
v
);
ASSIGN
(
self
->
oid
,
v
);
ASSIGN
(
self
->
oid
,
v
);
return
0
;
return
0
;
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
Py_DECREF
(
v
);
}
if
(
v
)
{
Py_DECREF
(
v
);
}
self
->
state
=
cPersistent_GHOST_STATE
;
return
0
;
return
0
;
}
}
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
/* Record access times */
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
changed
,
changed
,
accessed
,
ghostify
,
deallocated
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
pergetattr
)
Per_getattr
,
(
pergetattr
)
Per_getattr
,
(
persetattr
)
_setattro
,
};
};
void
void
...
...
src/Persistence/cPersistence.h
View file @
226ee421
...
@@ -18,12 +18,21 @@
...
@@ -18,12 +18,21 @@
#include "ExtensionClass.h"
#include "ExtensionClass.h"
#include <time.h>
#include <time.h>
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid; char serial[8]; unsigned short atime; signed char state; unsigned char reserved;
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid, *cache; CPersistentRing ring; char serial[8]; signed char state; unsigned char reserved[3];
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_CHANGED_STATE 1
#define cPersistent_CHANGED_STATE 1
#define cPersistent_STICKY_STATE 2
#define cPersistent_STICKY_STATE 2
struct
ccobject_head_struct
;
typedef
struct
CPersistentRing_struct
{
struct
CPersistentRing_struct
*
prev
;
struct
CPersistentRing_struct
*
next
;
}
CPersistentRing
;
typedef
struct
{
typedef
struct
{
cPersistent_HEAD
cPersistent_HEAD
}
cPersistentObject
;
}
cPersistentObject
;
...
@@ -36,6 +45,9 @@ typedef struct {
...
@@ -36,6 +45,9 @@ typedef struct {
getattrofunc
getattro
;
getattrofunc
getattro
;
setattrofunc
setattro
;
setattrofunc
setattro
;
int
(
*
changed
)(
cPersistentObject
*
);
int
(
*
changed
)(
cPersistentObject
*
);
void
(
*
accessed
)(
cPersistentObject
*
);
void
(
*
ghostify
)(
cPersistentObject
*
);
void
(
*
deallocated
)(
cPersistentObject
*
);
int
(
*
setstate
)(
PyObject
*
);
int
(
*
setstate
)(
PyObject
*
);
pergetattr
pergetattro
;
pergetattr
pergetattro
;
persetattr
persetattro
;
persetattr
persetattro
;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_GHOSTIFY(O) (cPersistenceCAPI->ghostify((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O)
Py_XDECREF((O)->jar); Py_XDECREF((O)->oid);
#define PER_DEL(O)
(cPersistenceCAPI->deallocated((cPersistentObject*)(O)))
#define PER_USE(O) \
#define PER_USE(O) \
(((O)->state != cPersistent_GHOST_STATE \
(((O)->state != cPersistent_GHOST_STATE \
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
? (((O)->state==cPersistent_UPTODATE_STATE) \
? (((O)->state==cPersistent_UPTODATE_STATE) \
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
#define PER_ACCESSED(O)
((O)->atime=((long)(time(NULL)/3))%65536)
#define PER_ACCESSED(O)
(cPersistenceCAPI->accessed((cPersistentObject*)(O)))
#endif
#endif
...
...
src/Persistence/cPickleCache.c
View file @
226ee421
This diff is collapsed.
Click to expand it.
src/ZODB/Connection.py
View file @
226ee421
...
@@ -13,14 +13,14 @@
...
@@ -13,14 +13,14 @@
##############################################################################
##############################################################################
"""Database connection support
"""Database connection support
$Id: Connection.py,v 1.6
3 2002/02/11 23:40:42 gvanrossum
Exp $"""
$Id: Connection.py,v 1.6
4 2002/03/27 10:14:03 htrd
Exp $"""
__version__
=
'$Revision: 1.6
3
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.6
4
$'
[
11
:
-
2
]
from
cPickleCache
import
PickleCache
from
cPickleCache
import
PickleCache
,
MUCH_RING_CHECKING
from
POSException
import
ConflictError
,
ReadConflictError
from
POSException
import
ConflictError
,
ReadConflictError
from
ExtensionClass
import
Base
from
ExtensionClass
import
Base
import
ExportImport
,
TmpStore
import
ExportImport
,
TmpStore
from
zLOG
import
LOG
,
ERROR
,
BLATHER
from
zLOG
import
LOG
,
ERROR
,
BLATHER
,
WARNING
from
coptimizations
import
new_persistent_id
from
coptimizations
import
new_persistent_id
from
ConflictResolution
import
ResolvedSerial
from
ConflictResolution
import
ResolvedSerial
...
@@ -32,6 +32,11 @@ from types import StringType, ClassType
...
@@ -32,6 +32,11 @@ from types import StringType, ClassType
global_code_timestamp
=
0
global_code_timestamp
=
0
if
MUCH_RING_CHECKING
:
# To get rid of this warning, change the define inside cPickleCache.c and recompile.
LOG
(
'ZODB'
,
WARNING
,
'Using cPickleCache with low performance (but extra debugging checks)'
)
del
MUCH_RING_CHECKING
def
updateCodeTimestamp
():
def
updateCodeTimestamp
():
'''
'''
Called after changes are made to persistence-based classes.
Called after changes are made to persistence-based classes.
...
@@ -65,12 +70,35 @@ class Connection(ExportImport.ExportImport):
...
@@ -65,12 +70,35 @@ class Connection(ExportImport.ExportImport):
"""Create a new Connection"""
"""Create a new Connection"""
self
.
_version
=
version
self
.
_version
=
version
self
.
_cache
=
cache
=
PickleCache
(
self
,
cache_size
,
cache_deactivate_after
)
self
.
_cache
=
cache
=
PickleCache
(
self
,
cache_size
,
cache_deactivate_after
)
if
version
:
# Caches for versions end up empty if the version
# is not used for a while. Non-version caches
# keep their content indefinitely.
self
.
_cache
.
cache_drain_resistance
=
100
self
.
_incrgc
=
self
.
cacheGC
=
cache
.
incrgc
self
.
_incrgc
=
self
.
cacheGC
=
cache
.
incrgc
self
.
_invalidated
=
d
=
{}
self
.
_invalidated
=
d
=
{}
self
.
_invalid
=
d
.
has_key
self
.
_invalid
=
d
.
has_key
self
.
_committed
=
[]
self
.
_committed
=
[]
self
.
_code_timestamp
=
global_code_timestamp
self
.
_code_timestamp
=
global_code_timestamp
def
_cache_items
(
self
):
# find all items on the lru list
items
=
self
.
_cache
.
lru_items
()
# fine everything. some on the lru list, some not
everything
=
self
.
_cache
.
cache_data
# remove those items that are on the lru list
for
k
,
v
in
items
:
del
everything
[
k
]
# return a list of [ghosts....not recently used.....recently used]
return
everything
.
items
()
+
items
def
__repr__
(
self
):
if
self
.
_version
:
ver
=
' (in version %s)'
%
`self._version`
else
:
ver
=
''
return
'<Connection at %08x%s>'
%
(
id
(
self
),
ver
)
def
_breakcr
(
self
):
def
_breakcr
(
self
):
try
:
del
self
.
_cache
try
:
del
self
.
_cache
except
:
pass
except
:
pass
...
@@ -414,9 +442,9 @@ class Connection(ExportImport.ExportImport):
...
@@ -414,9 +442,9 @@ class Connection(ExportImport.ExportImport):
for
oid
in
creating
:
for
oid
in
creating
:
o
=
cache_get
(
oid
,
None
)
o
=
cache_get
(
oid
,
None
)
if
o
is
not
None
:
if
o
is
not
None
:
del
cache
[
oid
]
del
o
.
_p_jar
del
o
.
_p_jar
del
o
.
_p_oid
del
o
.
_p_oid
del
cache
[
oid
]
#XXX
#XXX
...
@@ -441,9 +469,14 @@ class Connection(ExportImport.ExportImport):
...
@@ -441,9 +469,14 @@ class Connection(ExportImport.ExportImport):
def
root
(
self
):
return
self
[
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
]
def
root
(
self
):
return
self
[
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
]
def
setstate
(
self
,
object
):
def
setstate
(
self
,
object
):
oid
=
object
.
_p_oid
if
self
.
_storage
is
None
:
msg
=
"Shouldn't load state for %s when the connection is closed"
%
`oid`
LOG
(
'ZODB'
,
ERROR
,
msg
)
raise
RuntimeError
(
msg
)
try
:
try
:
oid
=
object
.
_p_oid
p
,
serial
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
p
,
serial
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
# XXX this is quite conservative!
# XXX this is quite conservative!
...
...
src/ZODB/DB.py
View file @
226ee421
...
@@ -13,8 +13,8 @@
...
@@ -13,8 +13,8 @@
##############################################################################
##############################################################################
"""Database objects
"""Database objects
$Id: DB.py,v 1.
39 2002/02/11 23:40:42 gvanrossum
Exp $"""
$Id: DB.py,v 1.
40 2002/03/27 10:14:04 htrd
Exp $"""
__version__
=
'$Revision: 1.
39
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
40
$'
[
11
:
-
2
]
import
cPickle
,
cStringIO
,
sys
,
POSException
,
UndoLogCompatible
import
cPickle
,
cStringIO
,
sys
,
POSException
,
UndoLogCompatible
from
Connection
import
Connection
from
Connection
import
Connection
...
@@ -177,7 +177,7 @@ class DB(UndoLogCompatible.UndoLogCompatible):
...
@@ -177,7 +177,7 @@ class DB(UndoLogCompatible.UndoLogCompatible):
def
f
(
con
,
detail
=
detail
,
rc
=
sys
.
getrefcount
,
conn_no
=
conn_no
):
def
f
(
con
,
detail
=
detail
,
rc
=
sys
.
getrefcount
,
conn_no
=
conn_no
):
conn_no
[
0
]
=
conn_no
[
0
]
+
1
conn_no
[
0
]
=
conn_no
[
0
]
+
1
cn
=
conn_no
[
0
]
cn
=
conn_no
[
0
]
for
oid
,
ob
in
con
.
_cache
.
items
():
for
oid
,
ob
in
con
.
_cache
_
items
():
id
=
''
id
=
''
if
hasattr
(
ob
,
'__dict__'
):
if
hasattr
(
ob
,
'__dict__'
):
d
=
ob
.
__dict__
d
=
ob
.
__dict__
...
@@ -224,11 +224,21 @@ class DB(UndoLogCompatible.UndoLogCompatible):
...
@@ -224,11 +224,21 @@ class DB(UndoLogCompatible.UndoLogCompatible):
def
cacheSize
(
self
):
def
cacheSize
(
self
):
m
=
[
0
]
m
=
[
0
]
def
f
(
con
,
m
=
m
):
def
f
(
con
,
m
=
m
):
m
[
0
]
=
m
[
0
]
+
len
(
con
.
_cache
)
m
[
0
]
=
m
[
0
]
+
con
.
_cache
.
cache_non_ghost_count
self
.
_connectionMap
(
f
)
self
.
_connectionMap
(
f
)
return
m
[
0
]
return
m
[
0
]
def
cacheDetailSize
(
self
):
m
=
[]
def
f
(
con
,
m
=
m
):
m
.
append
({
'connection'
:
repr
(
con
),
'ngsize'
:
con
.
_cache
.
cache_non_ghost_count
,
'size'
:
len
(
con
.
_cache
)})
self
.
_connectionMap
(
f
)
m
.
sort
()
return
m
def
close
(
self
):
self
.
_storage
.
close
()
def
close
(
self
):
self
.
_storage
.
close
()
def
commitVersion
(
self
,
source
,
destination
=
''
):
def
commitVersion
(
self
,
source
,
destination
=
''
):
...
...
src/ZODB/cPersistence.c
View file @
226ee421
...
@@ -14,11 +14,21 @@
...
@@ -14,11 +14,21 @@
static
char
cPersistence_doc_string
[]
=
static
char
cPersistence_doc_string
[]
=
"Defines Persistent mixin class for persistent objects.
\n
"
"Defines Persistent mixin class for persistent objects.
\n
"
"
\n
"
"
\n
"
"$Id: cPersistence.c,v 1.5
0 2002/03/08 18:36:13 jeremy
Exp $
\n
"
;
"$Id: cPersistence.c,v 1.5
1 2002/03/27 10:14:04 htrd
Exp $
\n
"
;
#include <string.h>
#include <string.h>
#include "cPersistence.h"
#include "cPersistence.h"
/* the layout of this struct is the same as the start of ccobject in cPickleCache.c */
struct
ccobject_head_struct
{
PyObject_HEAD
CPersistentRing
ring_home
;
int
non_ghost_count
;
};
#define HOME(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->ring_home)) )
#define NON_GHOST_COUNT(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->non_ghost_count)) )
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
{ \
{ \
PyObject *r; \
PyObject *r; \
\
\
int *count = NON_GHOST_COUNT(self); \
if(count) \
{ \
(*count)++; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \
Py_INCREF(self); \
} \
self->state=cPersistent_CHANGED_STATE; \
self->state=cPersistent_CHANGED_STATE; \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
{ \
{ \
self->state=cPersistent_GHOST_STATE;
\
ghostify(self);
\
return ER; \
return ER; \
} \
} \
self->state=cPersistent_UPTODATE_STATE; \
self->state=cPersistent_UPTODATE_STATE; \
Py_DECREF(r); \
Py_DECREF(r); \
}
}
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) \
if(HOME(self) && self->state>=0) { \
self->ring.prev->next = self->ring.next; \
self->ring.next->prev = self->ring.prev; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; }
/****************************************************************************/
/****************************************************************************/
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
Pertype
;
static
void
accessed
(
cPersistentObject
*
self
)
{
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
}
static
void
ghostify
(
cPersistentObject
*
self
)
{
int
*
count
;
count
=
NON_GHOST_COUNT
(
self
);
if
(
count
&&
(
self
->
state
>=
0
))
{
(
*
count
)
--
;
self
->
ring
.
next
->
prev
=
self
->
ring
.
prev
;
self
->
ring
.
prev
->
next
=
self
->
ring
.
next
;
self
->
ring
.
prev
=
NULL
;
self
->
ring
.
next
=
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
Py_DECREF
(
self
);
}
else
{
self
->
state
=
cPersistent_GHOST_STATE
;
}
}
static
void
deallocated
(
cPersistentObject
*
self
)
{
if
(
self
->
state
>=
0
)
ghostify
(
self
);
if
(
self
->
cache
)
{
PyObject
*
v
=
PyObject_CallMethod
(
self
->
cache
,
"_oid_unreferenced"
,
"O"
,
self
->
oid
);
if
(
!
v
)
PyErr_Clear
();
/* and explode later */
Py_XDECREF
(
v
);
}
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
oid
);
}
static
int
static
int
changed
(
cPersistentObject
*
self
)
changed
(
cPersistentObject
*
self
)
{
{
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
static
PyObject
*
static
PyObject
*
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
dict
;
PyObject
*
dict
,
*
dict2
=
NULL
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
{
{
dict2
=
PyDict_Copy
(
dict
);
PyDict_Clear
(
dict
);
PyDict_Clear
(
dict
);
/* Note that we need to set to ghost state unless we are
/* Note that we need to set to ghost state unless we are
called directly. Methods that override this need to
called directly. Methods that override this need to
do the same! */
do the same! */
self
->
state
=
cPersistent_GHOST_STATE
;
ghostify
(
self
)
;
}
}
/* need to delay releasing the last reference on instance attributes
until after we have finished accounting for losing our state */
if
(
dict2
)
{
PyDict_Clear
(
dict2
);
Py_DECREF
(
dict2
);
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
#endif
#endif
Py_XDECREF
(
self
->
jar
);
deallocated
(
self
);
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
cache
);
Py_DECREF
(
self
->
ob_type
);
Py_DECREF
(
self
->
ob_type
);
PyObject_DEL
(
self
);
PyObject_DEL
(
self
);
}
}
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
{
if
(
HOME
(
self
))
{
int
result
;
if
(
!
v
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not delete the oid of a cached object"
);
return
-
1
;
}
if
(
PyObject_Cmp
(
self
->
oid
,
v
,
&
result
)
<
0
)
return
-
1
;
if
(
result
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not change the oid of a cached object"
);
return
-
1
;
}
}
Py_XINCREF
(
v
);
Py_XINCREF
(
v
);
ASSIGN
(
self
->
oid
,
v
);
ASSIGN
(
self
->
oid
,
v
);
return
0
;
return
0
;
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
Py_DECREF
(
v
);
}
if
(
v
)
{
Py_DECREF
(
v
);
}
self
->
state
=
cPersistent_GHOST_STATE
;
return
0
;
return
0
;
}
}
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
/* Record access times */
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
changed
,
changed
,
accessed
,
ghostify
,
deallocated
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
pergetattr
)
Per_getattr
,
(
pergetattr
)
Per_getattr
,
(
persetattr
)
_setattro
,
};
};
void
void
...
...
src/ZODB/cPersistence.h
View file @
226ee421
...
@@ -18,12 +18,21 @@
...
@@ -18,12 +18,21 @@
#include "ExtensionClass.h"
#include "ExtensionClass.h"
#include <time.h>
#include <time.h>
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid; char serial[8]; unsigned short atime; signed char state; unsigned char reserved;
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid, *cache; CPersistentRing ring; char serial[8]; signed char state; unsigned char reserved[3];
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_CHANGED_STATE 1
#define cPersistent_CHANGED_STATE 1
#define cPersistent_STICKY_STATE 2
#define cPersistent_STICKY_STATE 2
struct
ccobject_head_struct
;
typedef
struct
CPersistentRing_struct
{
struct
CPersistentRing_struct
*
prev
;
struct
CPersistentRing_struct
*
next
;
}
CPersistentRing
;
typedef
struct
{
typedef
struct
{
cPersistent_HEAD
cPersistent_HEAD
}
cPersistentObject
;
}
cPersistentObject
;
...
@@ -36,6 +45,9 @@ typedef struct {
...
@@ -36,6 +45,9 @@ typedef struct {
getattrofunc
getattro
;
getattrofunc
getattro
;
setattrofunc
setattro
;
setattrofunc
setattro
;
int
(
*
changed
)(
cPersistentObject
*
);
int
(
*
changed
)(
cPersistentObject
*
);
void
(
*
accessed
)(
cPersistentObject
*
);
void
(
*
ghostify
)(
cPersistentObject
*
);
void
(
*
deallocated
)(
cPersistentObject
*
);
int
(
*
setstate
)(
PyObject
*
);
int
(
*
setstate
)(
PyObject
*
);
pergetattr
pergetattro
;
pergetattr
pergetattro
;
persetattr
persetattro
;
persetattr
persetattro
;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_GHOSTIFY(O) (cPersistenceCAPI->ghostify((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O)
Py_XDECREF((O)->jar); Py_XDECREF((O)->oid);
#define PER_DEL(O)
(cPersistenceCAPI->deallocated((cPersistentObject*)(O)))
#define PER_USE(O) \
#define PER_USE(O) \
(((O)->state != cPersistent_GHOST_STATE \
(((O)->state != cPersistent_GHOST_STATE \
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
? (((O)->state==cPersistent_UPTODATE_STATE) \
? (((O)->state==cPersistent_UPTODATE_STATE) \
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
#define PER_ACCESSED(O)
((O)->atime=((long)(time(NULL)/3))%65536)
#define PER_ACCESSED(O)
(cPersistenceCAPI->accessed((cPersistentObject*)(O)))
#endif
#endif
...
...
src/ZODB/cPickleCache.c
View file @
226ee421
This diff is collapsed.
Click to expand it.
src/persistent/cPersistence.c
View file @
226ee421
...
@@ -14,11 +14,21 @@
...
@@ -14,11 +14,21 @@
static
char
cPersistence_doc_string
[]
=
static
char
cPersistence_doc_string
[]
=
"Defines Persistent mixin class for persistent objects.
\n
"
"Defines Persistent mixin class for persistent objects.
\n
"
"
\n
"
"
\n
"
"$Id: cPersistence.c,v 1.5
0 2002/03/08 18:36:13 jeremy
Exp $
\n
"
;
"$Id: cPersistence.c,v 1.5
1 2002/03/27 10:14:04 htrd
Exp $
\n
"
;
#include <string.h>
#include <string.h>
#include "cPersistence.h"
#include "cPersistence.h"
/* the layout of this struct is the same as the start of ccobject in cPickleCache.c */
struct
ccobject_head_struct
{
PyObject_HEAD
CPersistentRing
ring_home
;
int
non_ghost_count
;
};
#define HOME(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->ring_home)) )
#define NON_GHOST_COUNT(O) ((!((O)->cache))?(NULL): (&(((struct ccobject_head_struct *)((O)->cache))->non_ghost_count)) )
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
...
@@ -112,21 +122,82 @@ if(self->state < 0 && self->jar) \
{ \
{ \
PyObject *r; \
PyObject *r; \
\
\
int *count = NON_GHOST_COUNT(self); \
if(count) \
{ \
(*count)++; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \
Py_INCREF(self); \
} \
self->state=cPersistent_CHANGED_STATE; \
self->state=cPersistent_CHANGED_STATE; \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \
{ \
{ \
self->state=cPersistent_GHOST_STATE;
\
ghostify(self);
\
return ER; \
return ER; \
} \
} \
self->state=cPersistent_UPTODATE_STATE; \
self->state=cPersistent_UPTODATE_STATE; \
Py_DECREF(r); \
Py_DECREF(r); \
}
}
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) \
if(HOME(self) && self->state>=0) { \
self->ring.prev->next = self->ring.next; \
self->ring.next->prev = self->ring.prev; \
self->ring.next = HOME(self); \
self->ring.prev = HOME(self)->prev; \
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; }
/****************************************************************************/
/****************************************************************************/
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
Pertype
;
static
void
accessed
(
cPersistentObject
*
self
)
{
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
}
static
void
ghostify
(
cPersistentObject
*
self
)
{
int
*
count
;
count
=
NON_GHOST_COUNT
(
self
);
if
(
count
&&
(
self
->
state
>=
0
))
{
(
*
count
)
--
;
self
->
ring
.
next
->
prev
=
self
->
ring
.
prev
;
self
->
ring
.
prev
->
next
=
self
->
ring
.
next
;
self
->
ring
.
prev
=
NULL
;
self
->
ring
.
next
=
NULL
;
self
->
state
=
cPersistent_GHOST_STATE
;
Py_DECREF
(
self
);
}
else
{
self
->
state
=
cPersistent_GHOST_STATE
;
}
}
static
void
deallocated
(
cPersistentObject
*
self
)
{
if
(
self
->
state
>=
0
)
ghostify
(
self
);
if
(
self
->
cache
)
{
PyObject
*
v
=
PyObject_CallMethod
(
self
->
cache
,
"_oid_unreferenced"
,
"O"
,
self
->
oid
);
if
(
!
v
)
PyErr_Clear
();
/* and explode later */
Py_XDECREF
(
v
);
}
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
oid
);
}
static
int
static
int
changed
(
cPersistentObject
*
self
)
changed
(
cPersistentObject
*
self
)
{
{
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
...
@@ -185,7 +256,7 @@ Per___changed__(cPersistentObject *self, PyObject *args)
static
PyObject
*
static
PyObject
*
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per__p_deactivate
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
dict
;
PyObject
*
dict
,
*
dict2
=
NULL
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"reinit"
,
self
);
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
...
@@ -197,13 +268,22 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
self
->
jar
&&
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
{
{
dict2
=
PyDict_Copy
(
dict
);
PyDict_Clear
(
dict
);
PyDict_Clear
(
dict
);
/* Note that we need to set to ghost state unless we are
/* Note that we need to set to ghost state unless we are
called directly. Methods that override this need to
called directly. Methods that override this need to
do the same! */
do the same! */
self
->
state
=
cPersistent_GHOST_STATE
;
ghostify
(
self
)
;
}
}
/* need to delay releasing the last reference on instance attributes
until after we have finished accounting for losing our state */
if
(
dict2
)
{
PyDict_Clear
(
dict2
);
Py_DECREF
(
dict2
);
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
...
@@ -333,8 +413,8 @@ Per_dealloc(cPersistentObject *self)
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
if
(
idebug_log
<
0
)
call_debug
(
"del"
,
self
);
#endif
#endif
Py_XDECREF
(
self
->
jar
);
deallocated
(
self
);
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
cache
);
Py_DECREF
(
self
->
ob_type
);
Py_DECREF
(
self
->
ob_type
);
PyObject_DEL
(
self
);
PyObject_DEL
(
self
);
}
}
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -387,7 +467,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
if
(
self
->
serial
[
7
]
==
'\0'
&&
self
->
serial
[
6
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
self
->
serial
[
5
]
==
'\0'
&&
self
->
serial
[
4
]
==
'\0'
&&
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -419,7 +499,7 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
)
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -466,6 +546,21 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
{
if
(
HOME
(
self
))
{
int
result
;
if
(
!
v
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not delete the oid of a cached object"
);
return
-
1
;
}
if
(
PyObject_Cmp
(
self
->
oid
,
v
,
&
result
)
<
0
)
return
-
1
;
if
(
result
)
{
PyErr_SetString
(
PyExc_ValueError
,
"can not change the oid of a cached object"
);
return
-
1
;
}
}
Py_XINCREF
(
v
);
Py_XINCREF
(
v
);
ASSIGN
(
self
->
oid
,
v
);
ASSIGN
(
self
->
oid
,
v
);
return
0
;
return
0
;
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -509,7 +604,6 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
v
=
PyObject_GetAttr
(
OBJECT
(
self
),
py__p_deactivate
);
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
ASSIGN
(
v
,
PyObject_CallObject
(
v
,
NULL
));
}
if
(
v
)
{
Py_DECREF
(
v
);
}
if
(
v
)
{
Py_DECREF
(
v
);
}
self
->
state
=
cPersistent_GHOST_STATE
;
return
0
;
return
0
;
}
}
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
if
(
PyObject_IsTrue
(
v
))
return
changed
(
self
);
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -521,8 +615,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
{
{
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
UPDATE_STATE_IF_NECESSARY
(
self
,
-
1
);
/* Record access times */
KEEP_THIS_ONE_AROUND_FOR_A_WHILE
(
self
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
if
((
!
(
*
name
==
'_'
&&
name
[
1
]
==
'v'
&&
name
[
2
]
==
'_'
))
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
&&
(
self
->
state
!=
cPersistent_CHANGED_STATE
&&
self
->
jar
)
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
...
@@ -680,9 +773,11 @@ truecPersistenceCAPI = {
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
changed
,
changed
,
accessed
,
ghostify
,
deallocated
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
intfunctionwithpythonarg
)
Per_setstate
,
(
pergetattr
)
Per_getattr
,
(
pergetattr
)
Per_getattr
,
(
persetattr
)
_setattro
,
};
};
void
void
...
...
src/persistent/cPersistence.h
View file @
226ee421
...
@@ -18,12 +18,21 @@
...
@@ -18,12 +18,21 @@
#include "ExtensionClass.h"
#include "ExtensionClass.h"
#include <time.h>
#include <time.h>
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid; char serial[8]; unsigned short atime; signed char state; unsigned char reserved;
#define cPersistent_HEAD PyObject_HEAD PyObject *jar, *oid, *cache; CPersistentRing ring; char serial[8]; signed char state; unsigned char reserved[3];
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_CHANGED_STATE 1
#define cPersistent_CHANGED_STATE 1
#define cPersistent_STICKY_STATE 2
#define cPersistent_STICKY_STATE 2
struct
ccobject_head_struct
;
typedef
struct
CPersistentRing_struct
{
struct
CPersistentRing_struct
*
prev
;
struct
CPersistentRing_struct
*
next
;
}
CPersistentRing
;
typedef
struct
{
typedef
struct
{
cPersistent_HEAD
cPersistent_HEAD
}
cPersistentObject
;
}
cPersistentObject
;
...
@@ -36,6 +45,9 @@ typedef struct {
...
@@ -36,6 +45,9 @@ typedef struct {
getattrofunc
getattro
;
getattrofunc
getattro
;
setattrofunc
setattro
;
setattrofunc
setattro
;
int
(
*
changed
)(
cPersistentObject
*
);
int
(
*
changed
)(
cPersistentObject
*
);
void
(
*
accessed
)(
cPersistentObject
*
);
void
(
*
ghostify
)(
cPersistentObject
*
);
void
(
*
deallocated
)(
cPersistentObject
*
);
int
(
*
setstate
)(
PyObject
*
);
int
(
*
setstate
)(
PyObject
*
);
pergetattr
pergetattro
;
pergetattr
pergetattro
;
persetattr
persetattro
;
persetattr
persetattro
;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -59,11 +71,13 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_CHANGED(O) (cPersistenceCAPI->changed((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_GHOSTIFY(O) (cPersistenceCAPI->ghostify((cPersistentObject*)(O)))
#define PER_ALLOW_DEACTIVATION(O) ((O)->state==cPersistent_STICKY_STATE && ((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_PREVENT_DEACTIVATION(O) ((O)->state==cPersistent_UPTODATE_STATE && ((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O)
Py_XDECREF((O)->jar); Py_XDECREF((O)->oid);
#define PER_DEL(O)
(cPersistenceCAPI->deallocated((cPersistentObject*)(O)))
#define PER_USE(O) \
#define PER_USE(O) \
(((O)->state != cPersistent_GHOST_STATE \
(((O)->state != cPersistent_GHOST_STATE \
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -71,7 +85,7 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
? (((O)->state==cPersistent_UPTODATE_STATE) \
? (((O)->state==cPersistent_UPTODATE_STATE) \
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
? ((O)->state=cPersistent_STICKY_STATE) : 1) : 0)
#define PER_ACCESSED(O)
((O)->atime=((long)(time(NULL)/3))%65536)
#define PER_ACCESSED(O)
(cPersistenceCAPI->accessed((cPersistentObject*)(O)))
#endif
#endif
...
...
src/persistent/cPickleCache.c
View file @
226ee421
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment