Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Nicolas Wavrant
ZODB
Commits
69c8c4a9
Commit
69c8c4a9
authored
May 07, 1999
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
parent
77e0ce28
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
820 additions
and
3259 deletions
+820
-3259
trunk/src/Persistence/PersistentMapping.py
trunk/src/Persistence/PersistentMapping.py
+3
-4
trunk/src/Persistence/cPersistence.c
trunk/src/Persistence/cPersistence.c
+85
-46
trunk/src/Persistence/cPersistence.h
trunk/src/Persistence/cPersistence.h
+10
-2
trunk/src/Persistence/cPickleCache.c
trunk/src/Persistence/cPickleCache.c
+41
-11
trunk/src/ZODB/BTree.c
trunk/src/ZODB/BTree.c
+0
-1804
trunk/src/ZODB/Connection.py
trunk/src/ZODB/Connection.py
+22
-41
trunk/src/ZODB/DB.py
trunk/src/ZODB/DB.py
+5
-5
trunk/src/ZODB/FileStorage.py
trunk/src/ZODB/FileStorage.py
+330
-288
trunk/src/ZODB/IIBTree.c
trunk/src/ZODB/IIBTree.c
+0
-8
trunk/src/ZODB/IOBTree.c
trunk/src/ZODB/IOBTree.c
+0
-7
trunk/src/ZODB/OIBTree.c
trunk/src/ZODB/OIBTree.c
+0
-7
trunk/src/ZODB/Persistence.py
trunk/src/ZODB/Persistence.py
+0
-158
trunk/src/ZODB/PersistentMapping.py
trunk/src/ZODB/PersistentMapping.py
+3
-4
trunk/src/ZODB/PickleCache.py
trunk/src/ZODB/PickleCache.py
+0
-114
trunk/src/ZODB/Setup
trunk/src/ZODB/Setup
+4
-10
trunk/src/ZODB/Transaction.py
trunk/src/ZODB/Transaction.py
+12
-15
trunk/src/ZODB/ZApplication.py
trunk/src/ZODB/ZApplication.py
+9
-3
trunk/src/ZODB/__init__.py
trunk/src/ZODB/__init__.py
+21
-2
trunk/src/ZODB/cPersistence.c
trunk/src/ZODB/cPersistence.c
+85
-46
trunk/src/ZODB/cPersistence.h
trunk/src/ZODB/cPersistence.h
+10
-2
trunk/src/ZODB/cPickleCache.c
trunk/src/ZODB/cPickleCache.c
+41
-11
trunk/src/ZODB/intSet.c
trunk/src/ZODB/intSet.c
+0
-608
trunk/src/persistent/cPersistence.c
trunk/src/persistent/cPersistence.c
+85
-46
trunk/src/persistent/cPersistence.h
trunk/src/persistent/cPersistence.h
+10
-2
trunk/src/persistent/cPickleCache.c
trunk/src/persistent/cPickleCache.c
+41
-11
trunk/src/persistent/mapping.py
trunk/src/persistent/mapping.py
+3
-4
No files found.
trunk/src/Persistence/PersistentMapping.py
View file @
69c8c4a9
...
@@ -48,12 +48,12 @@
...
@@ -48,12 +48,12 @@
__doc__
=
'''Python implementation of persistent base types
__doc__
=
'''Python implementation of persistent base types
$Id: PersistentMapping.py,v 1.
3 1998/11/11 02:00:56
jim Exp $'''
$Id: PersistentMapping.py,v 1.
4 1999/05/07 01:03:03
jim Exp $'''
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
4
$'
[
11
:
-
2
]
import
Persistence
import
Persistence
class
P
M
(
Persistence
.
Persistent
):
class
P
ersistentMapping
(
Persistence
.
Persistent
):
"""A persistent wrapper for mapping objects.
"""A persistent wrapper for mapping objects.
This class allows wrapping of mapping objects so that
This class allows wrapping of mapping objects so that
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
def
values
(
self
):
def
values
(
self
):
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
PersistentMapping
=
PM
trunk/src/Persistence/cPersistence.c
View file @
69c8c4a9
/***********************************************************************
/***********************************************************************
$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $
C Persistence Module
C Persistence Module
...
@@ -12,16 +12,19 @@
...
@@ -12,16 +12,19 @@
*****************************************************************************/
*****************************************************************************/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $"
;
#include <
time
.h>
#include <
string
.h>
#include "cPersistence.h"
#include "cPersistence.h"
#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)
#define OBJECT(V) ((PyObject*)(V))
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
;
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
,
*
py_timeTime
;
static
PyObject
*
TimeStamp
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
static
PyObject
*
debug_log
=
0
;
static
PyObject
*
debug_log
=
0
;
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
/*
/*
printf("%s %p\n",event,self->ob_type->tp_name);
printf("%s %p\n",event,self->ob_type->tp_name);
*/
*/
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
s#
i)"
,
event
,
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
O
i)"
,
event
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
8
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
self
->
state
);
self
->
state
);
Py_XDECREF
(
r
);
Py_XDECREF
(
r
);
}
}
...
@@ -48,6 +51,7 @@ init_strings()
...
@@ -48,6 +51,7 @@ init_strings()
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
keys
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
setstate
);
INIT_STRING
(
timeTime
);
INIT_STRING
(
__dict__
);
INIT_STRING
(
__dict__
);
#undef INIT_STRING
#undef INIT_STRING
}
}
...
@@ -201,14 +205,16 @@ static PyObject *
...
@@ -201,14 +205,16 @@ static PyObject *
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
v
=
0
;
PyObject
*
v
=
0
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
v
&&
!
PyObject_IsTrue
(
v
))
if
(
!
v
)
return
PyObject_GetAttrString
(
OBJECT
(
self
),
"_p_changed"
);
if
(
PyObject_IsTrue
(
v
))
{
{
PyErr_SetString
(
PyExc_TypeError
,
if
(
changed
(
self
)
<
0
)
return
NULL
;
"Only true arguments are allowed."
);
return
NULL
;
}
}
if
(
changed
(
self
)
<
0
)
return
NULL
;
else
if
(
self
->
state
>=
0
)
self
->
state
=
cPersistent_UPTODATE_STATE
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
static
PyObject
*
orNothing
(
PyObject
*
v
)
{
if
(
!
v
)
v
=
Py_None
;
Py_INCREF
(
v
);
return
v
;
}
static
PyObject
*
static
PyObject
*
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
{
{
char
*
n
=
name
;
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
n
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
{
switch
(
*
n
++
)
switch
(
*
n
++
)
{
{
case
'o'
:
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
return
orNothing
(
self
->
oid
);
return
PyString_FromStringAndSize
(
self
->
oid
,
8
);
break
;
break
;
case
'j'
:
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
return
orNothing
(
self
->
jar
);
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
break
;
case
'c'
:
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
cPersistent_CHANGED_STATE
);
cPersistent_CHANGED_STATE
);
}
}
break
;
break
;
case
's'
:
if
(
strcmp
(
n
,
"erial"
)
==
0
)
return
PyString_FromStringAndSize
(
self
->
serial
,
8
);
break
;
case
'm'
:
if
(
strcmp
(
n
,
"time"
)
==
0
)
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
oname
=
PyString_FromStringAndSize
(
self
->
serial
,
8
);
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallFunction
(
TimeStamp
,
"O"
,
oname
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_GetAttr
(
oname
,
py_timeTime
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallObject
(
oname
,
NULL
));
return
oname
;
}
break
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
if
(
!
(
name
&&
*
name
++==
'_'
&&
*
name
++==
'_'
&&
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
||
strcmp
(
name
,
"of__"
)
==
0
)))
||
strcmp
(
name
,
"of__"
)
==
0
)))
{
{
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
static
PyObject
*
static
PyObject
*
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
{
{
char
*
s
;
char
*
s
=
NULL
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
if
(
PyString_Check
(
name
))
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
}
}
static
int
static
int
...
@@ -456,27 +479,36 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -456,27 +479,36 @@ _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
(
!
v
)
return
bad_delattr
();
Py_XINCREF
(
v
);
if
(
PyString_Check
(
v
)
&&
PyString_GET_SIZE
(
v
)
==
8
)
ASSIGN
(
self
->
oid
,
v
);
memcpy
(
self
->
oid
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_AttributeError
,
"_p_oid must be an 8-character string"
);
return
-
1
;
}
return
0
;
return
0
;
}
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
jar
,
v
);
ASSIGN
(
self
->
jar
,
v
);
Py_XINCREF
(
self
->
jar
);
return
0
;
return
0
;
}
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
if
(
name
[
3
]
==
's'
&&
strcmp
(
name
+
4
,
"erial"
)
==
0
)
{
{
if
(
!
v
)
return
bad_delattr
();
if
(
v
)
if
(
v
==
Py_None
)
{
if
(
PyString_Check
(
v
)
&&
PyString_Size
(
v
)
==
8
)
memcpy
(
self
->
serial
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_ValueError
,
"_p_serial must be an 8-character string"
);
return
-
1
;
}
}
else
memset
(
self
->
serial
,
0
,
8
);
return
0
;
}
if
(
name
[
3
]
==
'c'
&&
strcmp
(
name
+
4
,
"hanged"
)
==
0
)
{
if
(
!
v
||
v
==
Py_None
)
{
{
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
return
0
;
return
0
;
...
@@ -585,8 +617,15 @@ void
...
@@ -585,8 +617,15 @@ void
initcPersistence
()
initcPersistence
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.25 $"
;
char
*
rev
=
"$Revision: 1.26 $"
;
TimeStamp
=
PyString_FromString
(
"TimeStamp"
);
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyImport_Import
(
TimeStamp
));
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyObject_GetAttrString
(
TimeStamp
,
"TimeStamp"
));
if
(
!
TimeStamp
)
return
;
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
""
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/Persistence/cPersistence.h
View file @
69c8c4a9
/*
/*
$Id: cPersistence.h,v 1.1
0 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.h,v 1.1
1 1999/05/07 01:03:03
jim Exp $
Definitions to facilitate making cPersistent subclasses in C.
Definitions to facilitate making cPersistent subclasses in C.
...
@@ -15,9 +15,11 @@
...
@@ -15,9 +15,11 @@
#define cPersistent_HEAD PyObject_HEAD \
#define cPersistent_HEAD PyObject_HEAD \
PyObject *jar; \
PyObject *jar; \
char oid[8]; \
PyObject *oid; \
char serial[8]; \
unsigned short atime; \
unsigned short atime; \
signed char state; \
signed char state; \
unsigned char reserved; \
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
...
@@ -43,6 +45,8 @@ typedef struct {
...
@@ -43,6 +45,8 @@ typedef struct {
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
#define cPersistanceModuleName "cPersistence"
#define PER_USE_OR_RETURN(O,R) { \
#define PER_USE_OR_RETURN(O,R) { \
if ((O)->state==cPersistent_GHOST_STATE && \
if ((O)->state==cPersistent_GHOST_STATE && \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
((O)->state==cPersistent_STICKY_STATE && \
((O)->state==cPersistent_STICKY_STATE && \
((O)->state=cPersistent_UPTODATE_STATE))
((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) \
((O)->state==cPersistent_UPTODATE_STATE && \
((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O) Py_XDECREF((O)->jar)
#define PER_DEL(O) Py_XDECREF((O)->jar)
#endif
#endif
...
...
trunk/src/Persistence/cPickleCache.c
View file @
69c8c4a9
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
6 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
7 1999/05/07 01:03:03
jim Exp $"
;
#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))
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
/* Declarations for objects of type cCache */
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
PyObject
*
data
;
PyObject
*
data
;
PyObject
*
jar
;
int
position
;
int
position
;
int
cache_size
;
int
cache_size
;
int
cache_age
;
int
cache_age
;
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
if
(
dt
&&
v
->
ob_type
->
tp_basicsize
>=
sizeof
(
cPersistentObject
)
&&
if
(
dt
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
(
!
PyExtensionClass_Check
(
v
))
&&
((
cPersistentObject
*
)
v
)
->
jar
==
self
->
jar
/* I'm paranoid */
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
{
{
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
if
(
now
<
0
)
now
+=
65536
;
if
(
now
<
0
)
now
+=
65536
;
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
};
};
static
ccobject
*
static
ccobject
*
newccobject
(
int
cache_size
,
int
cache_age
)
newccobject
(
PyObject
*
jar
,
int
cache_size
,
int
cache_age
)
{
{
ccobject
*
self
;
ccobject
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
if
(
self
->
data
=
PyDict_New
())
if
(
self
->
data
=
PyDict_New
())
{
{
self
->
jar
=
jar
;
Py_INCREF
(
jar
);
self
->
position
=
0
;
self
->
position
=
0
;
self
->
cache_size
=
cache_size
;
self
->
cache_size
=
cache_size
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
...
@@ -312,6 +315,7 @@ static void
...
@@ -312,6 +315,7 @@ static void
cc_dealloc
(
ccobject
*
self
)
cc_dealloc
(
ccobject
*
self
)
{
{
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
jar
);
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
return
r
;
return
r
;
}
}
static
PyExtensionClass
*
Persistent
=
0
;
static
int
static
int
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
{
if
(
v
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
if
(
v
)
{
if
(
PyExtensionClass_Check
(
v
)
||
(
PyExtensionInstance_Check
(
v
)
&&
ExtensionClassSubclassInstance_Check
(
v
,
Persistent
)
)
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
PyErr_SetString
(
PyExc_ValueError
,
"Cache values must be persistent objects or classes."
);
return
-
1
;
}
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
...
@@ -446,8 +464,10 @@ static PyObject *
...
@@ -446,8 +464,10 @@ static PyObject *
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
{
{
int
cache_size
=
100
,
cache_age
=
1000
;
int
cache_size
=
100
,
cache_age
=
1000
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|ii"
,
&
cache_size
,
&
cache_age
))
return
NULL
;
PyObject
*
jar
;
return
(
PyObject
*
)
newccobject
(
cache_size
,
cache_age
);
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|ii"
,
&
jar
,
&
cache_size
,
&
cache_age
))
return
NULL
;
return
(
PyObject
*
)
newccobject
(
jar
,
cache_size
,
cache_age
);
}
}
static
struct
PyMethodDef
cCM_methods
[]
=
{
static
struct
PyMethodDef
cCM_methods
[]
=
{
...
@@ -459,10 +479,20 @@ void
...
@@ -459,10 +479,20 @@ void
initcPickleCache
()
initcPickleCache
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.1
6
$"
;
char
*
rev
=
"$Revision: 1.1
7
$"
;
Cctype
.
ob_type
=&
PyType_Type
;
Cctype
.
ob_type
=&
PyType_Type
;
UNLESS
(
ExtensionClassImported
)
return
;
/* Get the Persistent base class */
UNLESS
(
m
=
PyString_FromString
(
cPersistanceModuleName
))
return
;
ASSIGN
(
m
,
PyImport_Import
(
m
));
UNLESS
(
m
)
return
;
ASSIGN
(
m
,
PyObject_GetAttrString
(
m
,
"Persistent"
));
UNLESS
(
m
)
return
;
Persistent
=
(
PyExtensionClass
*
)
m
;
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/ZODB/BTree.c
deleted
100755 → 0
View file @
77e0ce28
/***********************************************************
Copyright
Copyright 1997 Digital Creations, L.L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved.
******************************************************************/
static
char
BTree_module_documentation
[]
=
""
"
\n
$Id: BTree.c,v 1.17 1998/11/11 02:00:55 jim Exp $"
;
#define PERSISTENT
#ifdef PERSISTENT
#include "cPersistence.h"
#else
#include "ExtensionClass.h"
#define PER_USE_OR_RETURN(self, NULL)
#define PER_ALLOW_DEACTIVATION(self)
#define PER_DEL(self)
#endif
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;}
#define ASSIGN(V,E) PyVar_Assign(&(V),(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E); UNLESS(V)
#define RETURN_NONE Py_INCREF(Py_None); return Py_None
#define LIST(O) ((PyListObject*)(O))
#define OBJECT(O) ((PyObject*)(O))
#define MIN_BUCKET_ALLOC 8
#define MAX_SIZE(N) 32
#ifdef INTKEY
#define KEY_TYPE INTKEY
#define KEY_PARSE "i"
#define TEST_KEY(k) ((k)-ikey)
#define DECREF_KEY(k)
#define ASSIGN_KEY(k,e) (k=e)
#else
#define KEY_TYPE PyObject *
#define KEY_PARSE "O"
#define TEST_KEY(k) PyObject_Compare(k,key)
#define DECREF_KEY(k) Py_DECREF(k)
#define ASSIGN_KEY(k,e) ASSIGN(k,e)
#endif
#ifdef INTVAL
#define VALUE_TYPE INTVAL
#define VALUE_PARSE "i"
#define DECREF_VALUE(k)
#define ASSIGN_VALUE(k,e) (k=e)
#else
#define VALUE_TYPE PyObject *
#define VALUE_PARSE "O"
#define DECREF_VALUE(k) Py_DECREF(k)
#define ASSIGN_VALUE(k,e) ASSIGN(k,e)
#endif
typedef
struct
ItemStruct
{
KEY_TYPE
key
;
VALUE_TYPE
value
;
}
Item
;
typedef
struct
BTreeItemStruct
{
KEY_TYPE
key
;
PyObject
*
value
;
int
count
;
}
BTreeItem
;
typedef
struct
{
cPersistent_HEAD
int
size
,
len
;
Item
*
data
;
}
Bucket
;
staticforward
PyExtensionClass
BucketType
;
#define BUCKET(O) ((Bucket*)(O))
#define Bucket_Check(O) ((O)->ob_type==(PyTypeObject*)&BucketType)
typedef
struct
{
cPersistent_HEAD
int
size
,
len
;
BTreeItem
*
data
;
int
count
;
}
BTree
;
staticforward
PyExtensionClass
BucketType
;
#define BTREE(O) ((BTree*)(O))
#define BTree_Check(O) ((O)->ob_type==(PyTypeObject*)&BTreeType)
/************************************************************************
BTreeItems
*/
typedef
struct
{
PyObject_HEAD
BTree
*
data
;
int
first
,
len
;
char
kind
;
}
BTreeItems
;
staticforward
PyTypeObject
BTreeItemsType
;
static
PyObject
*
newBTreeItems
(
BTree
*
data
,
char
kind
,
int
first
,
int
last
)
{
BTreeItems
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
BTreeItems
,
&
BTreeItemsType
))
return
NULL
;
Py_INCREF
(
data
);
self
->
data
=
data
;
self
->
kind
=
kind
;
self
->
first
=
first
;
self
->
len
=
last
-
first
;
return
OBJECT
(
self
);
}
static
void
BTreeItems_dealloc
(
BTreeItems
*
self
)
{
Py_DECREF
(
self
->
data
);
PyMem_DEL
(
self
);
}
static
int
BTreeItems_length
(
BTreeItems
*
self
)
{
return
self
->
len
;
}
static
PyObject
*
BTreeItems_concat
(
BTreeItems
*
self
,
PyObject
*
bb
)
{
PyErr_SetString
(
PyExc_TypeError
,
"BTreeItems objects do not support concatenation"
);
return
NULL
;
}
static
PyObject
*
BTreeItems_repeat
(
BTreeItems
*
self
,
int
n
)
{
PyErr_SetString
(
PyExc_TypeError
,
"BTreeItems objects do not support repetition"
);
return
NULL
;
}
static
PyObject
*
BTreeItems_item_BTree
(
char
kind
,
int
i
,
BTree
*
btree
)
{
int
l
;
BTreeItem
*
d
;
PyObject
*
r
;
PER_USE_OR_RETURN
(
btree
,
NULL
);
for
(
d
=
btree
->
data
,
l
=
btree
->
len
;
--
l
>=
0
&&
i
>=
d
->
count
;
i
-=
d
->
count
,
d
++
);
PER_ALLOW_DEACTIVATION
(
btree
);
if
(
Bucket_Check
(
d
->
value
))
{
PER_USE_OR_RETURN
((
Bucket
*
)(
d
->
value
),
NULL
);
switch
(
kind
)
{
case
'k'
:
#ifdef INTKEY
r
=
PyInt_FromLong
((
BUCKET
(
d
->
value
)
->
data
[
i
].
key
));
#else
r
=
(
BUCKET
(
d
->
value
)
->
data
[
i
].
key
);
Py_INCREF
(
r
);
#endif
break
;
case
'v'
:
#ifdef INTVAL
r
=
PyInt_FromLong
((
BUCKET
(
d
->
value
)
->
data
[
i
].
value
));
#else
r
=
(
BUCKET
(
d
->
value
)
->
data
[
i
].
value
);
Py_INCREF
(
r
);
#endif
break
;
default:
r
=
Py_BuildValue
(
KEY_PARSE
VALUE_PARSE
,
BUCKET
(
d
->
value
)
->
data
[
i
].
key
,
BUCKET
(
d
->
value
)
->
data
[
i
].
value
);
}
PER_ALLOW_DEACTIVATION
(
BUCKET
(
d
->
value
));
return
r
;
}
return
BTreeItems_item_BTree
(
kind
,
i
,
BTREE
(
d
->
value
));
}
static
PyObject
*
BTreeItems_item
(
BTreeItems
*
self
,
int
i
)
{
int
j
,
l
;
j
=
i
;
l
=
self
->
len
;
if
(
j
<
0
)
j
+=
l
;
if
(
j
<
0
||
j
>=
l
)
{
PyObject
*
v
;
v
=
PyInt_FromLong
(
i
);
UNLESS
(
v
)
{
v
=
Py_None
;
Py_INCREF
(
v
);
}
PyErr_SetObject
(
PyExc_IndexError
,
v
);
Py_DECREF
(
v
);
return
NULL
;
}
i
=
j
+
self
->
first
;
return
BTreeItems_item_BTree
(
self
->
kind
,
i
,
self
->
data
);
}
static
PyObject
*
BTreeItems_slice
(
BTreeItems
*
self
,
int
ilow
,
int
ihigh
)
{
if
(
ihigh
>
self
->
len
)
ihigh
=
self
->
len
;
ilow
+=
self
->
first
;
ihigh
+=
self
->
first
;
return
newBTreeItems
(
self
->
data
,
self
->
kind
,
ilow
,
ihigh
);
}
static
int
BTreeItems_ass_item
(
BTreeItems
*
self
,
int
i
,
PyObject
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"BTreeItems objects do not support item assignment"
);
return
-
1
;
}
static
int
BTreeItems_ass_slice
(
PyListObject
*
self
,
int
ilow
,
int
ihigh
,
PyObject
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"BTreeItems objects do not support slice assignment"
);
return
-
1
;
}
static
PySequenceMethods
BTreeItems_as_sequence
=
{
(
inquiry
)
BTreeItems_length
,
/*sq_length*/
(
binaryfunc
)
BTreeItems_concat
,
/*sq_concat*/
(
intargfunc
)
BTreeItems_repeat
,
/*sq_repeat*/
(
intargfunc
)
BTreeItems_item
,
/*sq_item*/
(
intintargfunc
)
BTreeItems_slice
,
/*sq_slice*/
(
intobjargproc
)
BTreeItems_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
BTreeItems_ass_slice
,
/*sq_ass_slice*/
};
/* -------------------------------------------------------------- */
static
PyTypeObject
BTreeItemsType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"BTreeItems"
,
/*tp_name*/
sizeof
(
BTreeItems
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
BTreeItems_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
&
BTreeItems_as_sequence
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
0
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"Sequence type used to iterate over BTree items."
/* Documentation string */
};
/************************************************************************/
static
void
*
PyMalloc
(
size_t
sz
)
{
void
*
r
;
if
(
r
=
malloc
(
sz
))
return
r
;
PyErr_NoMemory
();
return
NULL
;
}
static
void
*
PyRealloc
(
void
*
p
,
size_t
sz
)
{
void
*
r
;
if
(
r
=
realloc
(
p
,
sz
))
return
r
;
PyErr_NoMemory
();
return
NULL
;
}
static
PyObject
*
Twople
(
PyObject
*
i1
,
PyObject
*
i2
)
{
PyObject
*
t
;
if
(
t
=
PyTuple_New
(
2
))
{
Py_INCREF
(
i1
);
PyTuple_SET_ITEM
(
t
,
0
,
i1
);
Py_INCREF
(
i2
);
PyTuple_SET_ITEM
(
t
,
1
,
i2
);
}
return
t
;
}
static
int
BTree_ini
(
BTree
*
self
)
{
PyObject
*
b
;
UNLESS
(
b
=
PyObject_CallObject
(
OBJECT
(
&
BucketType
),
NULL
))
return
-
1
;
#ifndef INTKEY
Py_INCREF
(
Py_None
);
self
->
data
->
key
=
Py_None
;
#endif
self
->
data
->
value
=
b
;
self
->
data
->
count
=
0
;
self
->
len
=
1
;
self
->
count
=
0
;
return
0
;
}
static
int
BTree_init
(
BTree
*
self
)
{
UNLESS
(
self
->
data
=
PyMalloc
(
sizeof
(
BTreeItem
)
*
2
))
return
-
1
;
self
->
size
=
2
;
return
BTree_ini
(
self
);
}
static
int
bucket_index
(
Bucket
*
self
,
PyObject
*
key
,
int
less
)
{
/*
If less, return the index of the largest key that is less than or
equall to key. Otherwise return the index of the smallest key
that is greater than or equal to key.
*/
int
min
,
max
,
i
,
l
,
cmp
;
#ifdef INTKEY
int
ikey
;
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
-
9
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
,
l
=
max
;
i
!=
l
;
l
=
i
,
i
=
(
min
+
max
)
/
2
)
{
cmp
=
TEST_KEY
(
self
->
data
[
i
].
key
);
if
(
cmp
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
PER_ALLOW_DEACTIVATION
(
self
);
return
i
;
}
else
max
=
i
;
}
PER_ALLOW_DEACTIVATION
(
self
);
if
(
less
)
return
max
-
1
;
if
(
max
==
min
)
return
min
;
return
min
+
1
;
}
static
PyObject
*
_bucket_get
(
Bucket
*
self
,
PyObject
*
key
,
int
has_key
)
{
int
min
,
max
,
i
,
l
,
cmp
;
PyObject
*
r
;
#ifdef INTKEY
int
ikey
;
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
NULL
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
PER_USE_OR_RETURN
(
self
,
NULL
);
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
,
l
=
max
;
i
!=
l
;
l
=
i
,
i
=
(
min
+
max
)
/
2
)
{
cmp
=
TEST_KEY
(
self
->
data
[
i
].
key
);
if
(
cmp
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
if
(
has_key
)
r
=
PyInt_FromLong
(
1
);
else
{
#ifdef INTVAL
r
=
PyInt_FromLong
(
self
->
data
[
i
].
value
);
#else
r
=
self
->
data
[
i
].
value
;
Py_INCREF
(
r
);
#endif
}
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
else
max
=
i
;
}
PER_ALLOW_DEACTIVATION
(
self
);
if
(
has_key
)
return
PyInt_FromLong
(
0
);
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
PyObject
*
bucket_get
(
Bucket
*
self
,
PyObject
*
key
)
{
return
_bucket_get
(
self
,
key
,
0
);
}
static
PyObject
*
bucket_map
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
keys
,
*
key
,
*
r
;
int
l
,
i
,
a
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
keys
))
return
NULL
;
if
((
l
=
PyObject_Length
(
keys
))
<
0
)
return
NULL
;
UNLESS
(
r
=
PyList_New
(
0
))
return
NULL
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
UNLESS
(
key
=
PySequence_GetItem
(
keys
,
i
))
goto
err
;
ASSIGN
(
key
,
_bucket_get
(
self
,
key
,
0
));
if
(
key
)
{
a
=
PyList_Append
(
r
,
key
);
Py_DECREF
(
key
);
if
(
a
<
0
)
goto
err
;
}
else
PyErr_Clear
();
}
return
r
;
err:
Py_DECREF
(
r
);
return
NULL
;
}
static
int
BTree_index
(
BTree
*
self
,
PyObject
*
key
,
int
less
)
{
/*
If less, return the index of the largest key that is less than or
equall to key. Otherwise return the index of the smallest key
that is greater than or equal to key.
*/
int
min
,
max
,
i
,
cmp
;
#ifdef INTKEY
int
ikey
;
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
-
9
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
UNLESS
(
self
->
data
)
if
(
BTree_init
(
self
)
<
0
)
goto
err
;
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
;
max
-
min
>
1
;
i
=
(
min
+
max
)
/
2
)
{
cmp
=
TEST_KEY
(
self
->
data
[
i
].
key
);
if
(
cmp
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
min
=
i
;
break
;
}
else
max
=
i
;
}
if
(
Bucket_Check
(
self
->
data
[
min
].
value
))
i
=
bucket_index
(
BUCKET
(
self
->
data
[
min
].
value
),
key
,
less
);
else
i
=
BTree_index
(
BTREE
(
self
->
data
[
min
].
value
),
key
,
less
);
if
(
i
==-
9
)
goto
err
;
while
(
--
min
>=
0
)
i
+=
self
->
data
[
min
].
count
;
PER_ALLOW_DEACTIVATION
(
self
);
return
i
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
-
9
;
}
static
PyObject
*
_BTree_get
(
BTree
*
self
,
PyObject
*
key
,
int
has_key
)
{
int
min
,
max
,
i
,
cmp
;
PyObject
*
r
;
#ifdef INTKEY
int
ikey
;
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
NULL
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
PER_USE_OR_RETURN
(
self
,
NULL
);
UNLESS
(
self
->
data
)
if
(
BTree_init
(
self
)
<
0
)
goto
err
;
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
;
max
-
min
>
1
;
i
=
(
min
+
max
)
/
2
)
{
cmp
=
TEST_KEY
(
self
->
data
[
i
].
key
);
if
(
cmp
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
min
=
i
;
break
;
}
else
max
=
i
;
}
if
(
Bucket_Check
(
self
->
data
[
min
].
value
))
r
=
_bucket_get
(
BUCKET
(
self
->
data
[
min
].
value
),
key
,
has_key
);
else
r
=
_BTree_get
(
BTREE
(
self
->
data
[
min
].
value
),
key
,
has_key
);
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
PyObject
*
BTree_get
(
BTree
*
self
,
PyObject
*
key
)
{
return
_BTree_get
(
self
,
key
,
0
);
}
static
PyObject
*
BTree_map
(
BTree
*
self
,
PyObject
*
args
)
{
PyObject
*
keys
,
*
key
,
*
r
;
int
l
,
i
,
a
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
keys
))
return
NULL
;
if
((
l
=
PyObject_Length
(
keys
))
<
0
)
return
NULL
;
UNLESS
(
r
=
PyList_New
(
0
))
return
NULL
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
UNLESS
(
key
=
PySequence_GetItem
(
keys
,
i
))
goto
err
;
ASSIGN
(
key
,
_BTree_get
(
self
,
key
,
0
));
if
(
key
)
{
a
=
PyList_Append
(
r
,
key
);
Py_DECREF
(
key
);
if
(
a
<
0
)
goto
err
;
}
else
PyErr_Clear
();
}
return
r
;
err:
Py_DECREF
(
r
);
return
NULL
;
}
static
int
_bucket_set
(
Bucket
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
int
min
,
max
,
i
,
l
,
cmp
;
Item
*
d
;
#ifdef INTKEY
int
ikey
;
#endif
#ifdef INTVAL
int
iv
;
#endif
#ifdef INTKEY
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __setitem__ expected integer value"
);
return
-
1
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
#ifdef INTVAL
if
(
v
)
{
UNLESS
(
PyInt_Check
(
v
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
-
1
;
}
iv
=
PyInt_AsLong
(
v
);
}
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
for
(
min
=
0
,
max
=
l
=
self
->
len
,
i
=
max
/
2
;
i
!=
l
;
l
=
i
,
i
=
(
min
+
max
)
/
2
)
{
if
((
cmp
=
TEST_KEY
(
self
->
data
[
i
].
key
))
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
if
(
v
)
{
#ifdef INTVAL
self
->
data
[
i
].
value
=
iv
;
#else
Py_INCREF
(
v
);
ASSIGN
(
self
->
data
[
i
].
value
,
v
);
#endif
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
return
0
;
}
else
{
self
->
len
--
;
d
=
self
->
data
+
i
;
DECREF_KEY
(
d
->
key
);
DECREF_VALUE
(
d
->
value
);
if
(
i
<
self
->
len
)
memmove
(
d
,
d
+
1
,
sizeof
(
Item
)
*
(
self
->
len
-
i
));
else
if
(
!
self
->
len
)
{
self
->
size
=
0
;
free
(
self
->
data
);
self
->
data
=
NULL
;
}
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
return
1
;
}
}
else
max
=
i
;
}
if
(
!
v
)
{
PyErr_SetObject
(
PyExc_KeyError
,
key
);
goto
err
;
}
if
(
self
->
len
==
self
->
size
)
{
if
(
self
->
data
)
{
UNLESS
(
d
=
PyRealloc
(
self
->
data
,
sizeof
(
Item
)
*
self
->
size
*
2
))
goto
err
;
self
->
data
=
d
;
self
->
size
*=
2
;
}
else
{
UNLESS
(
self
->
data
=
PyMalloc
(
sizeof
(
Item
)
*
MIN_BUCKET_ALLOC
))
goto
err
;
self
->
size
=
MIN_BUCKET_ALLOC
;
}
}
if
(
max
!=
i
)
i
++
;
d
=
self
->
data
+
i
;
if
(
self
->
len
>
i
)
memmove
(
d
+
1
,
d
,
sizeof
(
Item
)
*
(
self
->
len
-
i
));
#ifdef INTKEY
d
->
key
=
ikey
;
#else
d
->
key
=
key
;
Py_INCREF
(
key
);
#endif
#ifdef INTVAL
d
->
value
=
iv
;
#else
d
->
value
=
v
;
Py_INCREF
(
v
);
#endif
self
->
len
++
;
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
return
1
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
-
1
;
}
static
int
bucket_setitem
(
Bucket
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
if
(
_bucket_set
(
self
,
key
,
v
)
<
0
)
return
-
1
;
return
0
;
}
static
int
bucket_split
(
Bucket
*
self
,
int
index
,
Bucket
*
next
)
{
if
(
index
<
0
||
index
>=
self
->
len
)
index
=
self
->
len
/
2
;
UNLESS
(
next
->
data
=
PyMalloc
(
sizeof
(
Item
)
*
(
self
->
len
-
index
)))
return
-
1
;
next
->
len
=
self
->
len
-
index
;
next
->
size
=
next
->
len
;
memcpy
(
next
->
data
,
self
->
data
+
index
,
sizeof
(
Item
)
*
next
->
size
);
self
->
len
=
index
;
return
0
;
}
static
int
BTree_count
(
BTree
*
self
)
{
int
i
,
c
=
0
;
BTreeItem
*
d
;
for
(
i
=
self
->
len
,
d
=
self
->
data
;
--
i
>=
0
;
d
++
)
c
+=
d
->
count
;
return
c
;
}
static
int
BTree_split
(
BTree
*
self
,
int
index
,
BTree
*
next
)
{
if
(
index
<
0
||
index
>=
self
->
len
)
index
=
self
->
len
/
2
;
UNLESS
(
next
->
data
=
PyMalloc
(
sizeof
(
BTreeItem
)
*
(
self
->
len
-
index
)))
return
-
1
;
next
->
len
=
self
->
len
-
index
;
next
->
size
=
next
->
len
;
memcpy
(
next
->
data
,
self
->
data
+
index
,
sizeof
(
BTreeItem
)
*
next
->
size
);
if
((
next
->
count
=
BTree_count
(
next
))
<
0
)
return
-
1
;
self
->
len
=
index
;
self
->
count
-=
next
->
count
;
return
0
;
}
static
int
BTree_clone
(
BTree
*
self
)
{
/* We've grown really big without anybody splitting us.
We should split ourselves.
*/
BTree
*
n1
=
0
,
*
n2
=
0
;
BTreeItem
*
d
=
0
;
int
count
;
/* Create two BTrees to hold ourselves after split */
UNLESS
(
n1
=
BTREE
(
PyObject_CallObject
(
OBJECT
(
self
->
ob_type
),
NULL
)))
return
-
1
;
UNLESS
(
n2
=
BTREE
(
PyObject_CallObject
(
OBJECT
(
self
->
ob_type
),
NULL
)))
goto
err
;
/* Create a new data buffer to hold two BTrees */
UNLESS
(
d
=
PyMalloc
(
sizeof
(
BTreeItem
)
*
2
))
goto
err
;
count
=
self
->
count
;
/* Split ourself */
if
(
BTree_split
(
self
,
-
1
,
n2
)
<
0
)
goto
err
;
/* Move our data to new BTree */
n1
->
size
=
self
->
size
;
n1
->
len
=
self
->
len
;
n1
->
count
=
self
->
count
;
n1
->
data
=
self
->
data
;
/* Initialize our data to hold split data */
self
->
data
=
d
;
Py_INCREF
(
Py_None
);
#ifndef INTKEY
self
->
data
->
key
=
Py_None
;
#endif
self
->
len
=
2
;
self
->
size
=
2
;
self
->
data
->
value
=
OBJECT
(
n1
);
self
->
data
->
count
=
n1
->
count
;
#ifndef INTKEY
Py_INCREF
(
n2
->
data
->
key
);
#endif
self
->
data
[
1
].
key
=
n2
->
data
->
key
;
self
->
data
[
1
].
value
=
OBJECT
(
n2
);
self
->
data
[
1
].
count
=
n2
->
count
;
self
->
count
=
count
;
return
0
;
err:
Py_XDECREF
(
n1
);
Py_XDECREF
(
n2
);
free
(
d
);
return
-
1
;
}
static
int
BTree_grow
(
BTree
*
self
,
int
index
)
{
int
i
;
PyObject
*
v
,
*
e
=
0
;
BTreeItem
*
d
;
if
(
self
->
len
==
self
->
size
)
{
UNLESS
(
d
=
PyRealloc
(
self
->
data
,
sizeof
(
BTreeItem
)
*
self
->
size
*
2
))
return
-
1
;
self
->
data
=
d
;
self
->
size
*=
2
;
}
d
=
self
->
data
+
index
;
v
=
d
->
value
;
UNLESS
(
e
=
PyObject_CallObject
(
OBJECT
(
v
->
ob_type
),
NULL
))
return
-
1
;
PER_USE_OR_RETURN
((
Bucket
*
)
v
,
-
1
);
if
(
Bucket_Check
(
v
))
{
i
=
bucket_split
(
BUCKET
(
v
),
-
1
,
BUCKET
(
e
));
d
->
count
=
BUCKET
(
v
)
->
len
;
}
else
{
i
=
BTree_split
(
BTREE
(
v
),
-
1
,
BTREE
(
e
));
d
->
count
=
BTREE
(
v
)
->
count
;
}
PER_ALLOW_DEACTIVATION
(
BUCKET
(
v
));
if
(
i
<
0
)
{
Py_DECREF
(
e
);
return
-
1
;
}
index
++
;
d
++
;
if
(
self
->
len
>
index
)
memmove
(
d
+
1
,
d
,
sizeof
(
BTreeItem
)
*
(
self
->
len
-
index
));
if
(
Bucket_Check
(
v
))
{
d
->
key
=
BUCKET
(
e
)
->
data
->
key
;
d
->
count
=
BUCKET
(
e
)
->
len
;
}
else
{
d
->
key
=
BTREE
(
e
)
->
data
->
key
;
d
->
count
=
BTREE
(
e
)
->
count
;
}
#ifndef INTKEY
Py_INCREF
(
d
->
key
);
#endif
d
->
value
=
e
;
self
->
len
++
;
if
(
self
->
len
>=
MAX_SIZE
(
self
)
*
2
)
return
BTree_clone
(
self
);
return
0
;
}
static
int
_BTree_set
(
BTree
*
self
,
PyObject
*
key
,
PyObject
*
value
)
{
int
i
,
min
,
max
,
cmp
,
grew
;
BTreeItem
*
d
;
#ifdef INTKEY
int
ikey
;
#endif
#ifdef INTKEY
UNLESS
(
PyInt_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __setitem__ expected integer value"
);
return
-
1
;
}
ikey
=
PyInt_AsLong
(
key
);
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
UNLESS
(
self
->
data
)
if
(
BTree_init
(
self
)
<
0
)
goto
err
;
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
;
max
-
min
>
1
;
i
=
(
max
+
min
)
/
2
)
{
d
=
self
->
data
+
i
;
cmp
=
TEST_KEY
(
d
->
key
);
if
(
cmp
<
0
)
min
=
i
;
else
if
(
cmp
==
0
)
{
min
=
i
;
break
;
}
else
max
=
i
;
}
d
=
self
->
data
+
min
;
if
(
Bucket_Check
(
d
->
value
))
grew
=
_bucket_set
(
BUCKET
(
d
->
value
),
key
,
value
);
else
grew
=
_BTree_set
(
BTREE
(
d
->
value
),
key
,
value
);
if
(
grew
<
0
)
goto
err
;
if
(
grew
)
{
if
(
value
)
/* got bigger */
{
d
->
count
++
;
self
->
count
++
;
if
(
BUCKET
(
d
->
value
)
->
len
>
MAX_SIZE
(
self
)
&&
BTree_grow
(
self
,
min
)
<
0
)
goto
err
;
}
else
/* got smaller */
{
d
->
count
--
;
self
->
count
--
;
if
(
!
d
->
count
&&
self
->
len
>
1
)
{
self
->
len
--
;
Py_DECREF
(
d
->
value
);
DECREF_KEY
(
d
->
key
);
if
(
min
<
self
->
len
)
memmove
(
d
,
d
+
1
,
(
self
->
len
-
min
)
*
sizeof
(
BTreeItem
));
}
}
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
}
PER_ALLOW_DEACTIVATION
(
self
);
return
grew
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
-
1
;
}
static
int
BTree_setitem
(
BTree
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
if
(
_BTree_set
(
self
,
key
,
v
)
<
0
)
return
-
1
;
return
0
;
}
static
PyObject
*
bucket_keys
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
r
=
0
,
*
key
;
int
i
;
PER_USE_OR_RETURN
(
self
,
NULL
);
UNLESS
(
r
=
PyList_New
(
self
->
len
))
goto
err
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
#ifdef INTKEY
UNLESS
(
key
=
PyInt_FromLong
(
self
->
data
[
i
].
key
))
goto
err
;
#else
key
=
self
->
data
[
i
].
key
;
Py_INCREF
(
key
);
#endif
if
(
PyList_SetItem
(
r
,
i
,
key
)
<
0
)
goto
err
;
}
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
bucket_values
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
r
=
0
,
*
v
;
int
i
;
PER_USE_OR_RETURN
(
self
,
NULL
);
UNLESS
(
r
=
PyList_New
(
self
->
len
))
goto
err
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
#ifdef INTVAL
UNLESS
(
v
=
PyInt_FromLong
(
self
->
data
[
i
].
value
))
goto
err
;
#else
v
=
self
->
data
[
i
].
value
;
Py_INCREF
(
v
);
#endif
if
(
PyList_SetItem
(
r
,
i
,
v
)
<
0
)
goto
err
;
}
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
bucket_items
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
r
,
*
item
;
int
i
;
PER_USE_OR_RETURN
(
self
,
NULL
);
UNLESS
(
r
=
PyList_New
(
self
->
len
))
goto
err
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
UNLESS
(
item
=
Py_BuildValue
(
KEY_PARSE
VALUE_PARSE
,
self
->
data
[
i
].
key
,
self
->
data
[
i
].
value
))
goto
err
;
if
(
PyList_SetItem
(
r
,
i
,
item
)
<
0
)
goto
err
;
}
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
r
);
return
NULL
;
}
#ifdef PERSISTENT
static
PyObject
*
bucket__p___reinit__
(
Bucket
*
self
,
PyObject
*
args
)
{
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
)
{
int
i
;
PyObject
*
dict
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
DECREF_VALUE
(
self
->
data
[
i
].
value
);
}
if
(
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
PyDict_Clear
(
dict
);
self
->
len
=
0
;
self
->
state
=
cPersistent_GHOST_STATE
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
static
PyObject
*
bucket_clear
(
Bucket
*
self
,
PyObject
*
args
)
{
int
i
;
PER_USE_OR_RETURN
(
self
,
NULL
);
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
DECREF_VALUE
(
self
->
data
[
i
].
value
);
}
self
->
len
=
0
;
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
RETURN_NONE
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
int
_BTree_clear
(
BTree
*
self
)
{
int
i
;
UNLESS
(
self
->
data
)
return
0
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
Py_DECREF
(
self
->
data
[
i
].
value
);
}
i
=
BTree_ini
(
self
);
return
i
;
}
#ifdef PERSISTENT
static
PyObject
*
BTree__p___reinit__
(
BTree
*
self
,
PyObject
*
args
)
{
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
)
{
PyObject
*
dict
;
if
(
_BTree_clear
(
self
)
<
0
)
return
NULL
;
if
(
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
PyDict_Clear
(
dict
);
self
->
state
=
cPersistent_GHOST_STATE
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
static
PyObject
*
BTree_clear
(
BTree
*
self
,
PyObject
*
args
)
{
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
_BTree_clear
(
self
)
<
0
)
goto
err
;
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
RETURN_NONE
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
PyObject
*
bucket_getstate
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
r
,
*
keys
=
0
,
*
values
=
0
;
int
i
,
l
;
#ifdef INTKEY
int
v
;
char
*
c
;
#else
#ifdef INTVAL
int
v
;
char
*
c
;
#endif
#endif
PER_USE_OR_RETURN
(
self
,
NULL
);
l
=
self
->
len
;
#ifdef INTKEY
UNLESS
(
keys
=
PyString_FromStringAndSize
(
NULL
,
l
*
sizeof
(
int
)))
goto
err
;
UNLESS
(
c
=
PyString_AsString
(
keys
))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
v
=
self
->
data
[
i
].
key
;
*
c
++
=
(
int
)(
v
&
0xff
);
*
c
++
=
(
int
)((
v
>>
8
)
&
0xff
);
*
c
++
=
(
int
)((
v
>>
16
)
&
0xff
);
*
c
++
=
(
int
)((
v
>>
24
)
&
0xff
);
}
#else
UNLESS
(
keys
=
PyTuple_New
(
self
->
len
))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
r
=
self
->
data
[
i
].
key
;
Py_INCREF
(
r
);
PyTuple_SET_ITEM
(
keys
,
i
,
r
);
}
#endif
#ifdef INTVAL
UNLESS
(
values
=
PyString_FromStringAndSize
(
NULL
,
l
*
sizeof
(
int
)))
goto
err
;
UNLESS
(
c
=
PyString_AsString
(
values
))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
v
=
self
->
data
[
i
].
value
;
*
c
++
=
(
int
)(
v
&
0xff
);
*
c
++
=
(
int
)((
v
>>
8
)
&
0xff
);
*
c
++
=
(
int
)((
v
>>
16
)
&
0xff
);
*
c
++
=
(
int
)((
v
>>
24
)
&
0xff
);
}
#else
UNLESS
(
values
=
PyTuple_New
(
self
->
len
))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
r
=
self
->
data
[
i
].
value
;
Py_INCREF
(
r
);
PyTuple_SET_ITEM
(
values
,
i
,
r
);
}
#endif
PER_ALLOW_DEACTIVATION
(
self
);
r
=
Py_BuildValue
(
"OO"
,
keys
,
values
);
Py_DECREF
(
keys
);
Py_DECREF
(
values
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
Py_XDECREF
(
keys
);
Py_XDECREF
(
values
);
return
NULL
;
}
static
PyObject
*
bucket_setstate
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
r
,
*
keys
=
0
,
*
values
=
0
;
int
i
,
l
,
v
;
Item
*
d
;
#ifdef INTKEY
char
*
ck
;
#endif
#ifdef INTVAL
char
*
cv
;
#endif
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
r
))
goto
err
;
UNLESS
(
PyArg_ParseTuple
(
r
,
"OO"
,
&
keys
,
&
values
))
goto
err
;
if
((
l
=
PyObject_Length
(
keys
))
<
0
)
goto
err
;
#ifdef INTKEY
l
/=
4
;
UNLESS
(
ck
=
PyString_AsString
(
keys
))
goto
err
;
#endif
if
((
v
=
PyObject_Length
(
values
))
<
0
)
goto
err
;
#ifdef INTVAL
v
/=
4
;
UNLESS
(
cv
=
PyString_AsString
(
values
))
goto
err
;
#endif
if
(
l
!=
v
)
{
PyErr_SetString
(
PyExc_ValueError
,
"number of keys differs from number of values"
);
goto
err
;
}
if
(
l
>
self
->
size
)
if
(
self
->
data
)
{
UNLESS
(
d
=
PyRealloc
(
self
->
data
,
sizeof
(
Item
)
*
l
))
goto
err
;
self
->
data
=
d
;
self
->
size
=
l
;
}
else
{
UNLESS
(
d
=
PyMalloc
(
sizeof
(
Item
)
*
l
))
goto
err
;
self
->
data
=
d
;
self
->
size
=
l
;
}
else
d
=
self
->
data
;
#ifdef INTKEY
for
(
i
=
l
;
--
i
>=
0
;
d
++
)
{
v
=
((
int
)(
unsigned
char
)
*
ck
++
)
;
v
|=
((
int
)(
unsigned
char
)
*
ck
++
)
<<
8
;
v
|=
((
int
)(
unsigned
char
)
*
ck
++
)
<<
16
;
v
|=
((
int
)(
unsigned
char
)
*
ck
++
)
<<
24
;
d
->
key
=
v
;
}
#else
for
(
i
=
0
;
i
<
l
;
i
++
,
d
++
)
{
UNLESS
(
r
=
PySequence_GetItem
(
keys
,
i
))
goto
err
;
if
(
i
<
self
->
len
)
Py_DECREF
(
d
->
key
);
d
->
key
=
r
;
}
#endif
d
=
self
->
data
;
#ifdef INTVAL
for
(
i
=
l
;
--
i
>=
0
;
d
++
)
{
v
=
((
int
)(
unsigned
char
)
*
cv
++
)
;
v
|=
((
int
)(
unsigned
char
)
*
cv
++
)
<<
8
;
v
|=
((
int
)(
unsigned
char
)
*
cv
++
)
<<
16
;
v
|=
((
int
)(
unsigned
char
)
*
cv
++
)
<<
24
;
d
->
value
=
v
;
}
#else
for
(
i
=
0
;
i
<
l
;
i
++
,
d
++
)
{
UNLESS
(
r
=
PySequence_GetItem
(
values
,
i
))
goto
err
;
if
(
i
<
self
->
len
)
Py_DECREF
(
d
->
value
);
d
->
value
=
r
;
}
#endif
self
->
len
=
l
;
PER_ALLOW_DEACTIVATION
(
self
);
Py_INCREF
(
Py_None
);
return
Py_None
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
PyObject
*
bucket_has_key
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
key
))
return
NULL
;
return
_bucket_get
(
self
,
key
,
1
);
}
static
PyObject
*
bucket_getm
(
Bucket
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
d
=
Py_None
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|O"
,
&
key
,
&
d
))
return
NULL
;
if
((
r
=
_bucket_get
(
self
,
key
,
0
)))
return
r
;
PyErr_Clear
();
Py_INCREF
(
d
);
return
d
;
}
static
struct
PyMethodDef
Bucket_methods
[]
=
{
{
"__getstate__"
,
(
PyCFunction
)
bucket_getstate
,
METH_VARARGS
,
"__getstate__() -- Return the picklable state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
bucket_setstate
,
METH_VARARGS
,
"__setstate__() -- Set the state of the object"
},
{
"keys"
,
(
PyCFunction
)
bucket_keys
,
METH_VARARGS
,
"keys() -- Return the keys"
},
{
"has_key"
,
(
PyCFunction
)
bucket_has_key
,
METH_VARARGS
,
"has_key(key) -- Test whether the bucket contains the given key"
},
{
"values"
,
(
PyCFunction
)
bucket_values
,
METH_VARARGS
,
"values() -- Return the values"
},
{
"items"
,
(
PyCFunction
)
bucket_items
,
METH_VARARGS
,
"items() -- Return the items"
},
{
"clear"
,
(
PyCFunction
)
bucket_clear
,
METH_VARARGS
,
"clear() -- Remove all of the items from the bucket"
},
{
"map"
,
(
PyCFunction
)
bucket_map
,
METH_VARARGS
,
"map(keys) -- map a sorted sequence of keys into values
\n\n
"
"Invalid keys are skipped"
},
{
"get"
,
(
PyCFunction
)
bucket_getm
,
METH_VARARGS
,
"get(key[,default]) -- Look up a value
\n\n
"
"Return the default (or None) if the key is not found."
},
#ifdef PERSISTENT
{
"_p___reinit__"
,
(
PyCFunction
)
bucket__p___reinit__
,
METH_VARARGS
,
"_p___reinit__() -- Reinitialize from a newly created copy"
},
{
"_p_deactivate"
,
(
PyCFunction
)
bucket__p___reinit__
,
METH_VARARGS
,
"_p_deactivate() -- Reinitialize from a newly created copy"
},
#endif
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
BTree_getstate
(
BTree
*
self
,
PyObject
*
args
)
{
PyObject
*
r
=
0
,
*
item
;
int
i
;
PER_USE_OR_RETURN
(
self
,
NULL
);
UNLESS
(
r
=
PyTuple_New
(
self
->
len
))
goto
err
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
UNLESS
(
item
=
Py_BuildValue
(
KEY_PARSE
"Oi"
,
self
->
data
[
i
].
key
,
self
->
data
[
i
].
value
,
self
->
data
[
i
].
count
))
goto
err
;
PyTuple_SET_ITEM
(
r
,
i
,
item
);
}
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
BTree_setstate
(
BTree
*
self
,
PyObject
*
args
)
{
PyObject
*
state
,
*
v
=
0
;
BTreeItem
*
d
;
int
l
,
i
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
state
))
return
NULL
;
if
((
l
=
PyTuple_Size
(
state
))
<
0
)
return
NULL
;
if
(
l
>
self
->
size
)
{
if
(
self
->
data
)
{
UNLESS
(
d
=
PyRealloc
(
self
->
data
,
sizeof
(
BTreeItem
)
*
l
))
goto
err
;
self
->
data
=
d
;
self
->
size
=
l
;
}
else
{
UNLESS
(
self
->
data
=
PyMalloc
(
sizeof
(
BTreeItem
)
*
l
))
goto
err
;
self
->
size
=
l
;
}
}
for
(
i
=
self
->
len
,
d
=
self
->
data
;
--
i
>=
0
;
d
++
)
{
DECREF_KEY
(
d
->
key
);
Py_DECREF
(
d
->
value
);
}
for
(
self
->
len
=
0
,
self
->
count
=
0
,
i
=
0
,
d
=
self
->
data
;
i
<
l
;
i
++
,
d
++
,
self
->
len
++
)
{
UNLESS
(
PyArg_ParseTuple
(
PyTuple_GET_ITEM
(
state
,
i
),
KEY_PARSE
"Oi"
,
&
(
d
->
key
),
&
(
d
->
value
),
&
(
d
->
count
)))
goto
err
;
#ifndef INTKEY
Py_INCREF
(
d
->
key
);
#endif
Py_INCREF
(
d
->
value
);
self
->
count
+=
d
->
count
;
}
PER_ALLOW_DEACTIVATION
(
self
);
Py_INCREF
(
Py_None
);
return
Py_None
;
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
PyObject
*
BTree_elements
(
BTree
*
self
,
PyObject
*
args
,
char
type
)
{
PyObject
*
f
=
0
,
*
l
=
0
;
int
fi
,
li
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|OO"
,
&
f
,
&
l
))
return
NULL
;
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
f
&&
f
!=
Py_None
)
{
fi
=
BTree_index
(
self
,
f
,
0
);
if
(
fi
==-
9
)
goto
err
;
}
else
fi
=
0
;
if
(
l
)
{
li
=
BTree_index
(
self
,
l
,
1
);
if
(
li
==-
9
)
goto
err
;
li
++
;
}
else
li
=
self
->
count
;
PER_ALLOW_DEACTIVATION
(
self
);
return
newBTreeItems
(
self
,
type
,
fi
,
li
);
err:
PER_ALLOW_DEACTIVATION
(
self
);
return
NULL
;
}
static
PyObject
*
BTree_keys
(
BTree
*
self
,
PyObject
*
args
)
{
return
BTree_elements
(
self
,
args
,
'k'
);
}
static
PyObject
*
BTree_values
(
BTree
*
self
,
PyObject
*
args
)
{
return
BTree_elements
(
self
,
args
,
'v'
);
}
static
PyObject
*
BTree_items
(
BTree
*
self
,
PyObject
*
args
)
{
return
BTree_elements
(
self
,
args
,
'i'
);
}
static
PyObject
*
BTree_has_key
(
BTree
*
self
,
PyObject
*
args
)
{
PyObject
*
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
key
))
return
NULL
;
return
_BTree_get
(
self
,
key
,
1
);
}
static
PyObject
*
BTree_getm
(
BTree
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
d
=
Py_None
,
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|O"
,
&
key
,
&
d
))
return
NULL
;
if
((
r
=
_BTree_get
(
self
,
key
,
0
)))
return
r
;
PyErr_Clear
();
Py_INCREF
(
d
);
return
d
;
}
static
struct
PyMethodDef
BTree_methods
[]
=
{
{
"__getstate__"
,
(
PyCFunction
)
BTree_getstate
,
METH_VARARGS
,
"__getstate__() -- Return the picklable state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
BTree_setstate
,
METH_VARARGS
,
"__setstate__() -- Set the state of the object"
},
{
"has_key"
,
(
PyCFunction
)
BTree_has_key
,
METH_VARARGS
,
"has_key(key) -- Test whether the bucket contains the given key"
},
{
"keys"
,
(
PyCFunction
)
BTree_keys
,
METH_VARARGS
,
"keys() -- Return the keys"
},
{
"values"
,
(
PyCFunction
)
BTree_values
,
METH_VARARGS
,
"values() -- Return the values"
},
{
"items"
,
(
PyCFunction
)
BTree_items
,
METH_VARARGS
,
"items() -- Return the items"
},
{
"clear"
,
(
PyCFunction
)
BTree_clear
,
METH_VARARGS
,
"clear() -- Remove all of the items from the BTree"
},
{
"map"
,
(
PyCFunction
)
BTree_map
,
METH_VARARGS
,
"map(keys) -- map a sorted sequence of keys into values
\n\n
"
"Invalid keys are skipped"
},
{
"get"
,
(
PyCFunction
)
BTree_getm
,
METH_VARARGS
,
"get(key[,default]) -- Look up a value
\n\n
"
"Return the default (or None) if the key is not found."
},
#ifdef PERSISTENT
{
"_p___reinit__"
,
(
PyCFunction
)
BTree__p___reinit__
,
METH_VARARGS
,
"_p___reinit__() -- Reinitialize from a newly created copy"
},
{
"_p_deactivate"
,
(
PyCFunction
)
BTree__p___reinit__
,
METH_VARARGS
,
"_p_deactivate() -- Reinitialize from a newly created copy"
},
#endif
{
NULL
,
NULL
}
/* sentinel */
};
static
void
Bucket_dealloc
(
Bucket
*
self
)
{
int
i
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
DECREF_VALUE
(
self
->
data
[
i
].
value
);
}
free
(
self
->
data
);
PER_DEL
(
self
);
PyMem_DEL
(
self
);
}
static
void
BTree_dealloc
(
BTree
*
self
)
{
int
i
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
Py_DECREF
(
self
->
data
[
i
].
value
);
}
free
(
self
->
data
);
PER_DEL
(
self
);
PyMem_DEL
(
self
);
}
/* Code to access Bucket objects as mappings */
static
int
Bucket_length
(
Bucket
*
self
)
{
int
r
;
PER_USE_OR_RETURN
(
self
,
-
1
);
r
=
self
->
len
;
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
static
PyMappingMethods
Bucket_as_mapping
=
{
(
inquiry
)
Bucket_length
,
/*mp_length*/
(
binaryfunc
)
bucket_get
,
/*mp_subscript*/
(
objobjargproc
)
bucket_setitem
,
/*mp_ass_subscript*/
};
static
int
BTree_length
(
BTree
*
self
)
{
int
r
;
PER_USE_OR_RETURN
(
self
,
-
1
);
r
=
self
->
count
;
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
static
PyMappingMethods
BTree_as_mapping
=
{
(
inquiry
)
BTree_length
,
/*mp_length*/
(
binaryfunc
)
BTree_get
,
/*mp_subscript*/
(
objobjargproc
)
BTree_setitem
,
/*mp_ass_subscript*/
};
static
PyObject
*
bucket_repr
(
Bucket
*
self
)
{
static
PyObject
*
format
;
PyObject
*
r
,
*
t
;
UNLESS
(
format
)
UNLESS
(
format
=
PyString_FromString
(
"Bucket(%s)"
))
return
NULL
;
UNLESS
(
t
=
PyTuple_New
(
1
))
return
NULL
;
UNLESS
(
r
=
bucket_items
(
self
,
NULL
))
goto
err
;
PyTuple_SET_ITEM
(
t
,
0
,
r
);
r
=
t
;
ASSIGN
(
r
,
PyString_Format
(
format
,
r
));
return
r
;
err:
Py_DECREF
(
t
);
return
NULL
;
}
static
PyExtensionClass
BucketType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Bucket"
,
/*tp_name*/
sizeof
(
Bucket
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/*********** methods ***********************/
(
destructor
)
Bucket_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
bucket_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
Bucket_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
0
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"Mapping type implemented as sorted list of items"
,
METHOD_CHAIN
(
Bucket_methods
),
EXTENSIONCLASS_BASICNEW_FLAG
,
};
static
PyExtensionClass
BTreeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"BTree"
,
/*tp_name*/
sizeof
(
BTree
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/************* methods ********************/
(
destructor
)
BTree_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
BTree_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
0
,
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"Mapping type implemented as sorted list of items"
,
METHOD_CHAIN
(
BTree_methods
),
EXTENSIONCLASS_BASICNEW_FLAG
,
};
static
struct
PyMethodDef
module_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
void
#ifdef INTKEY
#ifdef INTVAL
initIIBTree
()
#define MODNAME "IIBTree"
#else
initIOBTree
()
#define MODNAME "IOBTree"
#endif
#else
#ifdef INTVAL
initOIBTree
()
#define MODNAME "OIBTree"
#else
initBTree
()
#define MODNAME "BTree"
#endif
#endif
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.17 $"
;
UNLESS
(
PyExtensionClassCAPI
=
PyCObject_Import
(
"ExtensionClass"
,
"CAPI"
))
return
;
#ifdef PERSISTENT
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
BucketType
.
methods
.
link
=
cPersistenceCAPI
->
methods
;
BucketType
.
tp_getattro
=
cPersistenceCAPI
->
getattro
;
BucketType
.
tp_setattro
=
cPersistenceCAPI
->
setattro
;
BTreeType
.
methods
.
link
=
cPersistenceCAPI
->
methods
;
BTreeType
.
tp_getattro
=
cPersistenceCAPI
->
getattro
;
BTreeType
.
tp_setattro
=
cPersistenceCAPI
->
setattro
;
}
else
return
;
#else
BucketType
.
tp_getattro
=
PyExtensionClassCAPI
->
getattro
;
BTreeType
.
tp_getattro
=
PyExtensionClassCAPI
->
getattro
;
#endif
/* Create the module and add the functions */
m
=
Py_InitModule4
(
MODNAME
,
module_methods
,
BTree_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"Bucket"
,
BucketType
);
PyExtensionClass_Export
(
d
,
"BTree"
,
BTreeType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module BTree"
);
}
trunk/src/ZODB/Connection.py
View file @
69c8c4a9
...
@@ -47,10 +47,10 @@
...
@@ -47,10 +47,10 @@
##############################################################################
##############################################################################
"""Database connection support
"""Database connection support
$Id: Connection.py,v 1.
2 1999/04/28 11:10:48
jim Exp $"""
$Id: Connection.py,v 1.
3 1999/05/07 01:03:02
jim Exp $"""
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
from
PickleCache
import
PickleCache
from
c
PickleCache
import
PickleCache
from
bpthread
import
allocate_lock
from
bpthread
import
allocate_lock
from
POSException
import
ConflictError
from
POSException
import
ConflictError
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
...
@@ -75,7 +75,7 @@ class Connection:
...
@@ -75,7 +75,7 @@ class Connection:
self
.
_storage
=
storage
self
.
_storage
=
storage
self
.
new_oid
=
storage
.
new_oid
self
.
new_oid
=
storage
.
new_oid
self
.
_version
=
version
self
.
_version
=
version
self
.
_cache
=
cache
=
PickleCache
(
cache_size
,
cache_deactivate_after
)
self
.
_cache
=
cache
=
PickleCache
(
self
,
cache_size
,
cache_deactivate_after
)
self
.
_incrgc
=
cache
.
incrgc
self
.
_incrgc
=
cache
.
incrgc
self
.
_invalidated
=
{}
self
.
_invalidated
=
{}
lock
=
allocate_lock
()
lock
=
allocate_lock
()
...
@@ -94,38 +94,25 @@ class Connection:
...
@@ -94,38 +94,25 @@ class Connection:
if
cache
.
has_key
(
oid
):
return
cache
[
oid
]
if
cache
.
has_key
(
oid
):
return
cache
[
oid
]
__traceback_info__
=
oid
__traceback_info__
=
oid
p
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
p
,
serial
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
file
=
StringIO
(
p
)
file
=
StringIO
(
p
)
unpickler
=
Unpickler
(
file
)
unpickler
=
Unpickler
(
file
)
unpickler
.
persistent_load
=
self
.
_persistent_load
unpickler
.
persistent_load
=
self
.
_persistent_load
object
=
unpickler
.
load
()
object
=
unpickler
.
load
()
if
type
(
object
)
is
tt
:
klass
,
args
=
object
klass
,
args
=
object
if
(
args
is
None
or
if
(
args
is
None
or
not
args
and
not
hasattr
(
klass
,
'__getinitargs__'
)):
not
args
and
not
hasattr
(
klass
,
'__getinitargs__'
)):
object
=
klass
.
__basicnew__
()
if
type
(
klass
)
is
ct
:
object
=
HelperClass
()
object
.
__class__
=
klass
else
:
object
=
klass
.
__basicnew__
()
else
:
object
=
apply
(
klass
,
args
)
object
.
__dict__
.
clear
()
else
:
else
:
object
=
apply
(
klass
,
args
)
object
.
__dict__
.
clear
()
object
.
__dict__
.
clear
()
klass
=
object
.
__class__
object
.
_p_oid
=
oid
if
type
(
klass
)
is
ct
:
object
.
_p_jar
=
self
d
=
object
.
__dict__
object
.
_p_changed
=
None
d
[
'_p_oid'
]
=
oid
object
.
_p_serial
=
serial
d
[
'_p_jar'
]
=
self
d
[
'_p_changed'
]
=
None
else
:
object
.
_p_oid
=
oid
object
.
_p_jar
=
self
object
.
_p_changed
=
None
cache
[
oid
]
=
object
cache
[
oid
]
=
object
return
object
return
object
...
@@ -143,18 +130,10 @@ class Connection:
...
@@ -143,18 +130,10 @@ class Connection:
# to create the instance wo hitting the db, so go for it!
# to create the instance wo hitting the db, so go for it!
oid
,
klass
=
oid
oid
,
klass
=
oid
if
cache
.
has_key
(
oid
):
return
cache
[
oid
]
if
cache
.
has_key
(
oid
):
return
cache
[
oid
]
if
type
(
klass
)
is
ct
:
object
=
klass
.
__basicnew__
()
object
=
HelperClass
()
object
.
_p_oid
=
oid
object
.
__class__
=
klass
object
.
_p_jar
=
self
d
=
object
.
__dict__
object
.
_p_changed
=
None
d
[
'_p_oid'
]
=
oid
d
[
'_p_jar'
]
=
self
d
[
'_p_changed'
]
=
None
else
:
object
=
klass
.
__basicnew__
()
object
.
_p_oid
=
oid
object
.
_p_jar
=
self
object
.
_p_changed
=
None
cache
[
oid
]
=
object
cache
[
oid
]
=
object
return
object
return
object
...
@@ -236,6 +215,7 @@ class Connection:
...
@@ -236,6 +215,7 @@ class Connection:
object
=
stack
[
-
1
]
object
=
stack
[
-
1
]
del
stack
[
-
1
]
del
stack
[
-
1
]
oid
=
object
.
_p_oid
oid
=
object
.
_p_oid
serial
=
object
.
_p_serial
if
self
.
_invalidated
.
has_key
(
oid
):
raise
ConflictError
,
oid
if
self
.
_invalidated
.
has_key
(
oid
):
raise
ConflictError
,
oid
cls
=
object
.
__class__
cls
=
object
.
__class__
if
hasattr
(
cls
,
'__getinitargs__'
):
if
hasattr
(
cls
,
'__getinitargs__'
):
...
@@ -249,7 +229,7 @@ class Connection:
...
@@ -249,7 +229,7 @@ class Connection:
state
=
object
.
__getstate__
()
state
=
object
.
__getstate__
()
dump
(
state
)
dump
(
state
)
p
=
file
()
p
=
file
()
dbstore
(
oid
,
p
,
version
,
transaction
)
object
.
_p_serial
=
dbstore
(
oid
,
serial
,
p
,
version
,
transaction
)
object
.
_p_changed
=
0
object
.
_p_changed
=
0
cache
[
oid
]
=
object
cache
[
oid
]
=
object
...
@@ -287,7 +267,7 @@ class Connection:
...
@@ -287,7 +267,7 @@ class Connection:
self
.
_r
()
self
.
_r
()
raise
ConflictError
,
oid
raise
ConflictError
,
oid
self
.
_r
()
self
.
_r
()
p
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
p
,
serial
=
self
.
_storage
.
load
(
oid
,
self
.
_version
)
file
=
StringIO
(
p
)
file
=
StringIO
(
p
)
unpickler
=
Unpickler
(
file
)
unpickler
=
Unpickler
(
file
)
unpickler
.
persistent_load
=
self
.
_persistent_load
unpickler
.
persistent_load
=
self
.
_persistent_load
...
@@ -298,6 +278,7 @@ class Connection:
...
@@ -298,6 +278,7 @@ class Connection:
else
:
else
:
d
=
object
.
__dict__
d
=
object
.
__dict__
for
k
,
v
in
state
.
items
():
d
[
k
]
=
v
for
k
,
v
in
state
.
items
():
d
[
k
]
=
v
object
.
_p_serial
=
serial
def
tpc_abort
(
self
,
transaction
):
def
tpc_abort
(
self
,
transaction
):
self
.
_storage
.
tpc_abort
(
transaction
)
self
.
_storage
.
tpc_abort
(
transaction
)
...
...
trunk/src/ZODB/DB.py
View file @
69c8c4a9
...
@@ -47,8 +47,8 @@
...
@@ -47,8 +47,8 @@
##############################################################################
##############################################################################
"""Database objects
"""Database objects
$Id: DB.py,v 1.
2 1999/04/28 11:10:48
jim Exp $"""
$Id: DB.py,v 1.
3 1999/05/07 01:03:02
jim Exp $"""
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
import
cPickle
,
cStringIO
,
sys
import
cPickle
,
cStringIO
,
sys
from
Connection
import
Connection
from
Connection
import
Connection
...
@@ -90,7 +90,7 @@ class DB:
...
@@ -90,7 +90,7 @@ class DB:
t
=
Transaction
()
t
=
Transaction
()
t
.
description
=
'initial database creation'
t
.
description
=
'initial database creation'
storage
.
tpc_begin
(
t
)
storage
.
tpc_begin
(
t
)
storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
file
.
getvalue
(),
''
,
t
)
storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
None
,
file
.
getvalue
(),
''
,
t
)
storage
.
tpc_finish
(
t
)
storage
.
tpc_finish
(
t
)
# Allocate locks:
# Allocate locks:
...
@@ -389,8 +389,8 @@ class DB:
...
@@ -389,8 +389,8 @@ class DB:
def
getCacheDeactivateAfter
(
self
):
return
self
.
_cache_deactivate_after
def
getCacheDeactivateAfter
(
self
):
return
self
.
_cache_deactivate_after
def
getCacheSize
(
self
):
return
self
.
_cache_size
def
getCacheSize
(
self
):
return
self
.
_cache_size
def
getPoolSize
(
self
):
return
self
.
_pool_size
def
getPoolSize
(
self
):
return
self
.
_pool_size
def
getVersionCacheDeactivateAfter
(
self
):
return
def
getVersionCacheDeactivateAfter
(
self
):
self
.
_version_cache_deactivate_after
return
self
.
_version_cache_deactivate_after
def
getVersionCacheSize
(
self
):
return
self
.
_version_cache_size
def
getVersionCacheSize
(
self
):
return
self
.
_version_cache_size
def
getVersionPoolSize
(
self
):
return
self
.
_version_pool_size
def
getVersionPoolSize
(
self
):
return
self
.
_version_pool_size
...
...
trunk/src/ZODB/FileStorage.py
View file @
69c8c4a9
##############################################################################
"""File-based ZODB storage
#
# Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
Files are arranged as follows.
# All rights reserved.
#
- The first 4 bytes are a file identifier.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
- The rest of the file consists of a sequence of transaction
# met:
"records".
#
# o Redistributions of source code must retain the above copyright
A transaction record consists of:
# notice, this list of conditions, and the disclaimer that follows.
#
- 8-byte transaction record, which is also a time stamp.
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
- 8-byte previous-transaction file position.
# the documentation and/or other materials provided with the
# distribution.
- 8-byte transaction record length - 8.
#
# o Neither the name of Digital Creations nor the names of its
- 1-byte status code
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
- 2-byte length of user name
#
#
- 2-byte length of description
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS IS*
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- 4-byte length of extension attributes
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
- user name
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- description
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* A sequence of data records
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- 8-byte redundant transaction length -8
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
A data record consists of
#
#
- 8-byte oid.
# If you have questions regarding this software, contact:
#
- 8-byte serial, which is a type stamp that matches the
# Digital Creations, L.C.
transaction timestamp.
# 910 Princess Ann Street
# Fredericksburge, Virginia 22401
- 8-byte previous-record file-position.
#
# info@digicool.com
- 8-byte beginning of transaction record file position.
#
# (540) 371-6909
- 2-byte version length
#
##############################################################################
- 8-byte data length
"""File-based BoboPOS3 storage
? 8-byte position of non-version data
(if version length > 0)
? 8-byte position of previous record in this version
(if version length > 0)
? version string
(if version length > 0)
? data
(data length > 0)
? 8-byte position of data record containing data
(data length > 0)
Note that the lengths and positions are all big-endian.
Also, the object ids time stamps are big-endian, so comparisons
are meaningful.
"""
"""
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
import
struct
,
time
,
os
,
bpthread
import
struct
,
time
,
os
,
bpthread
now
=
time
.
time
now
=
time
.
time
from
struct
import
pack
,
unpack
from
struct
import
pack
,
unpack
from
cPickle
import
dumps
import
POSException
import
POSException
from
TimeStamp
import
TimeStamp
t32
=
1L
<<
32
def
p64
(
v
,
pack
=
struct
.
pack
):
if
v
<
t32
:
h
=
0
else
:
h
=
v
/
t32
v
=
v
%
t32
return
pack
(
">II"
,
h
,
v
)
def
u64
(
v
,
unpack
=
struct
.
unpack
):
h
,
v
=
unpack
(
">ii"
,
v
)
if
v
<
0
:
v
=
t32
-
v
if
h
:
if
h
<
0
:
h
=
t32
-
h
v
=
h
*
t32
+
v
return
v
z64
=
'
\
0
'
*
8
def
cp
(
f1
,
f2
,
l
):
read
=
f1
.
read
write
=
f2
.
write
n
=
8192
while
l
>
0
:
if
n
>
l
:
n
=
l
d
=
read
(
n
)
write
(
d
)
l
=
l
-
len
(
d
)
def
warn
(
log
,
message
,
*
data
):
log
(
"%s warn: %s
\
n
"
%
(
packed_version
,
(
message
%
data
)))
def
error
(
log
,
message
,
*
data
):
log
(
"%s ERROR: %s
\
n
"
%
(
packed_version
,
(
message
%
data
)))
def
panic
(
log
,
message
,
*
data
):
message
=
message
%
data
log
(
"%s ERROR: %s
\
n
"
%
(
packed_version
,
message
))
raise
CorruptedTransactionRecordError
,
message
class
FileStorageError
:
pass
class
FileStorageError
:
pass
...
@@ -70,11 +134,24 @@ class CorruptedFileStorageError(FileStorageError,
...
@@ -70,11 +134,24 @@ class CorruptedFileStorageError(FileStorageError,
class
CorruptedTransactionError
(
CorruptedFileStorageError
):
pass
class
CorruptedTransactionError
(
CorruptedFileStorageError
):
pass
class
CorruptedDataError
(
CorruptedFileStorageError
):
pass
class
CorruptedDataError
(
CorruptedFileStorageError
):
pass
packed_version
=
'FS20'
class
FileStorage
:
class
FileStorage
:
_packt
=
0
_packt
=
0
_transaction
=
None
_transaction
=
None
_serial
=
z64
def
__init__
(
self
,
file_name
,
create
=
0
,
log
=
lambda
s
:
None
,
read_only
=
0
,
stop
=
None
):
def
__init__
(
self
,
file_name
,
create
=
0
):
if
read_only
:
if
create
:
raise
ValueError
,
"can
\
'
t create a read-only file"
elif
stop
is
not
None
:
raise
ValueError
,
"time-travel is only supported in read-only mode"
if
stop
is
None
:
stop
=
'
\
377
'
*
8
self
.
__name__
=
file_name
self
.
__name__
=
file_name
self
.
_tfile
=
open
(
file_name
+
'.tmp'
,
'w+b'
)
self
.
_tfile
=
open
(
file_name
+
'.tmp'
,
'w+b'
)
index
,
vindex
,
tindex
=
self
.
_newIndexes
()
index
,
vindex
,
tindex
=
self
.
_newIndexes
()
...
@@ -105,58 +182,87 @@ class FileStorage:
...
@@ -105,58 +182,87 @@ class FileStorage:
self
.
_oid
=
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
self
.
_oid
=
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
return
return
if
os
.
path
.
exists
(
file_name
):
file
=
open
(
file_name
,
'r+b'
)
if
os
.
path
.
exists
(
file_name
):
else
:
file
=
open
(
file_name
,
'w+b'
)
file
=
open
(
file_name
,
read_only
and
'rb'
or
'r+b'
)
else
:
if
read_only
:
raise
ValueError
,
"can
\
'
t create a read-only file"
file
=
open
(
file_name
,
'w+b'
)
self
.
_file
=
file
self
.
_file
=
file
self
.
_pos
,
self
.
_tpos
,
self
.
_oid
=
read_index
(
self
.
_pos
,
self
.
_tpos
,
self
.
_oid
,
tid
=
read_index
(
file
,
index
,
vindex
,
tindex
)
file
,
file_name
,
index
,
vindex
,
tindex
,
stop
,
log
)
self
.
_ts
=
tid
=
TimeStamp
(
tid
)
t
=
time
.
time
()
t
=
apply
(
TimeStamp
,(
time
.
gmtime
(
t
)[:
5
]
+
(
t
%
60
,)))
if
tid
>
t
:
warn
(
log
,
"%s Database records in the future"
,
file_name
);
def
__len__
(
self
):
return
len
(
self
.
_index
)
def
__len__
(
self
):
return
len
(
self
.
_index
)
def
_newIndexes
(
self
):
return
{},
{},
[]
def
_newIndexes
(
self
):
return
{},
{},
[]
def
abortVersion
(
self
,
version
):
def
abortVersion
(
self
,
version
,
transaction
):
if
transaction
is
not
self
.
_transaction
:
raise
POSException
.
StorageTransactionError
(
self
,
transaction
)
self
.
_a
()
self
.
_a
()
try
:
try
:
pos
=
self
.
_vindex
[
version
]
pos
=
self
.
_vindex
[
version
]
spos
=
p64
(
pos
)
file
=
self
.
_file
file
=
self
.
_file
seek
=
file
.
seek
seek
=
file
.
seek
read
=
file
.
read
read
=
file
.
read
file
=
self
.
_tfile
file
=
self
.
_tfile
write
=
file
.
write
write
=
file
.
write
tell
=
file
.
tell
tell
=
file
.
tell
tloc
=
self
.
_pos
tloc
=
p64
(
self
.
_pos
)
tappend
=
self
.
_tappend
tappend
=
self
.
_tappend
index
=
self
.
_index
index
=
self
.
_index
pack
=
struct
.
pack
pack
=
struct
.
pack
unpack
=
struct
.
unpack
unpack
=
struct
.
unpack
serial
=
self
.
_serial
while
pos
:
while
pos
:
seek
(
pos
)
seek
(
pos
)
h
=
read
(
30
)
h
=
read
(
58
)
oid
=
h
[:
8
]
oid
=
h
[:
8
]
if
index
[
oid
]
==
pos
:
if
index
[
oid
]
==
pos
:
tappend
(
oid
,
tell
())
tappend
(
oid
,
tell
())
pc
=
h
[
-
8
:
-
4
]
# Position of committed (non-version) data
pc
=
h
[
-
16
:
-
8
]
# Position of committed (non-version) data
write
(
pack
(
">8siiHi4s"
,
oid
,
pos
,
tloc
,
0
,
0
,
pc
))
write
(
pack
(
pos
=
unpack
(
">i"
,
h
[
-
4
:])[
0
]
">"
"8s"
"8s"
"8s"
"8s"
"H"
"8s"
"8s"
,
oid
,
serial
,
spos
,
tloc
,
0
,
z64
,
pc
))
spos
=
h
[
-
8
:]
pos
=
u64
(
spos
)
del
self
.
_vindex
[
version
]
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
close
(
self
):
def
close
(
self
):
self
.
_file
.
close
()
self
.
_file
.
close
()
# Eventuallly, we should save_index
# Eventuallly, we should save_index
def
commitVersion
(
self
,
src
,
dest
):
def
commitVersion
(
self
,
src
,
dest
,
transaction
):
if
transaction
is
not
self
.
_transaction
:
raise
POSException
.
StorageTransactionError
(
self
,
transaction
)
self
.
_a
()
self
.
_a
()
try
:
try
:
pos
=
self
.
_vindex
[
version
]
pos
=
self
.
_vindex
[
version
]
spos
=
p64
(
pos
)
file
=
self
.
_file
file
=
self
.
_file
seek
=
file
.
seek
seek
=
file
.
seek
read
=
file
.
read
read
=
file
.
read
file
=
self
.
_tfile
file
=
self
.
_tfile
write
=
file
.
write
write
=
file
.
write
tell
=
file
.
tell
tell
=
file
.
tell
tloc
=
self
.
_pos
tloc
=
p64
(
self
.
_pos
)
tappend
=
self
.
_tappend
tappend
=
self
.
_tappend
index
=
self
.
_index
index
=
self
.
_index
pack
=
struct
.
pack
pack
=
struct
.
pack
...
@@ -165,14 +271,20 @@ class FileStorage:
...
@@ -165,14 +271,20 @@ class FileStorage:
while
pos
:
while
pos
:
seek
(
pos
)
seek
(
pos
)
h
=
read
(
30
)
h
=
read
(
58
)
oid
=
h
[:
8
]
oid
=
h
[:
8
]
if
index
[
oid
]
==
pos
:
if
index
[
oid
]
==
pos
:
tappend
(
oid
,
tell
())
tappend
(
oid
,
tell
())
write
(
pack
(
">8siiHi4s"
,
oid
,
pos
,
tloc
,
destlen
,
0
,
h
[
-
8
:
-
4
]))
write
(
pack
(
">8s"
"8s"
"8s"
"H"
"8s"
"8s"
,
oid
,
spos
,
tloc
,
destlen
,
z64
,
h
[
-
16
:
-
8
]))
write
(
dest
)
write
(
dest
)
write
(
pack
(
">i"
,
pos
))
write
(
spos
)
pos
=
unpack
(
">i"
,
h
[
-
4
:])[
0
]
spos
=
h
[
-
8
:]
pos
=
u64
(
spos
)
del
self
.
_vindex
[
version
]
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
getName
(
self
):
return
self
.
__name__
def
getName
(
self
):
return
self
.
__name__
...
@@ -180,31 +292,8 @@ class FileStorage:
...
@@ -180,31 +292,8 @@ class FileStorage:
def
getSize
(
self
):
return
self
.
_pos
def
getSize
(
self
):
return
self
.
_pos
def
history
(
self
,
oid
,
version
,
length
=
1
):
def
history
(
self
,
oid
,
version
,
length
=
1
):
self
.
_a
()
# TBD
try
:
pass
# not done
index
=
self
.
_index
file
=
self
.
_file
seek
=
file
.
seek
read
=
file
.
read
hist
=
[]
pos
=
index
[
oid
]
while
length
:
seek
(
pos
)
h
=
read
(
22
)
doid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi"
,
h
)
if
vlen
and
not
hist
:
pnc
=
read
(
4
)
if
vlen
!=
len
(
version
)
or
read
(
vlen
)
!=
version
:
pos
=
unpack
(
">i"
,
pnc
)
contiue
pos
=
prev
seek
(
tloc
)
h
=
read
(
21
)
finally
:
self
.
_r
()
def
load
(
self
,
oid
,
version
,
_stuff
=
None
):
def
load
(
self
,
oid
,
version
,
_stuff
=
None
):
self
.
_a
()
self
.
_a
()
...
@@ -213,21 +302,21 @@ class FileStorage:
...
@@ -213,21 +302,21 @@ class FileStorage:
file
=
self
.
_file
file
=
self
.
_file
file
.
seek
(
pos
)
file
.
seek
(
pos
)
read
=
file
.
read
read
=
file
.
read
h
=
read
(
2
2
)
h
=
read
(
4
2
)
doid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi
"
,
h
)
doid
,
serial
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8s8s8s8sH8s
"
,
h
)
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
vlen
:
if
vlen
:
pnv
=
read
(
4
)
pnv
=
read
(
8
)
# Read location of non-version data
if
(
not
version
or
len
(
version
)
!=
vlen
or
if
(
not
version
or
len
(
version
)
!=
vlen
or
(
read
(
4
)
# skip past version link
(
read
(
8
)
# skip past version link
and
version
!=
read
(
vlen
))
and
version
!=
read
(
vlen
))
):
):
return
_loadBack
(
file
,
oid
,
pnv
)
return
_loadBack
(
file
,
oid
,
u64
(
pnv
)
)
# If we get here, then either this was not a version record,
# If we get here, then either this was not a version record,
# or we've already read past the version data!
# or we've already read past the version data!
if
plen
:
return
read
(
plen
)
if
plen
!=
z64
:
return
read
(
u64
(
plen
)),
serial
return
_loadBack
(
file
,
oid
,
pnv
)
return
_loadBack
(
file
,
oid
,
u64
(
pnv
)
)
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
modifiedInVersion
(
self
,
oid
):
def
modifiedInVersion
(
self
,
oid
):
...
@@ -236,10 +325,11 @@ class FileStorage:
...
@@ -236,10 +325,11 @@ class FileStorage:
pos
=
self
.
_index
[
oid
]
pos
=
self
.
_index
[
oid
]
file
=
self
.
_file
file
=
self
.
_file
file
.
seek
(
pos
)
file
.
seek
(
pos
)
doid
,
prev
,
tloc
,
vlen
=
unpack
(
">8siiH"
,
file
.
read
(
18
))
doid
,
serial
,
prev
,
tloc
,
vlen
=
unpack
(
">8s8s8s8sH"
,
file
.
read
(
34
))
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
vlen
:
if
vlen
:
seek
(
8
,
1
)
seek
(
16
,
1
)
return
read
(
vlen
)
return
read
(
vlen
)
return
''
return
''
finally
:
self
.
_r
()
finally
:
self
.
_r
()
...
@@ -261,121 +351,10 @@ class FileStorage:
...
@@ -261,121 +351,10 @@ class FileStorage:
else
:
return
self
.
new_oid
(
last
[:
-
1
])
else
:
return
self
.
new_oid
(
last
[:
-
1
])
def
pack
(
self
,
t
,
rf
):
def
pack
(
self
,
t
,
rf
):
self
.
_a
()
# TBD
try
:
pass
# we're going to leave this undone for a while!
# This is hellacious. Hold on to your butts!
# First, prevent undos before t:
self
.
_packt
=
t
index
,
vindex
,
tindex
=
self
.
_newIndexes
()
# Now we know the part of the file containing transactions
# written before t will not be touched. We are free to
# work on it.
self
.
_sync__lock
.
release
()
# Phase 1: pack the old records
ofile
=
open
(
self
.
__name__
,
'r+b'
)
import
Transaction
stop
=
Transaction
.
time2id
(
t
)
opos
,
otpos
,
maxoid
=
read_index
(
file
,
index
,
vindex
,
tindex
,
stop
)
read
=
ofile
.
read
seek
=
ofile
.
seek
pfile
=
open
(
self
.
__name__
+
'.pk'
,
'w+b'
)
write
=
pfile
.
write
unpack
=
struct
.
unpack
rootl
=
[
'
\
0
'
*
8
]
rootd
=
{}
inroot
=
rootd
.
has_key
while
rootl
:
oid
=
rootl
[
-
1
]
del
rootl
[
-
1
]
if
inroot
[
oid
]:
continue
pos
=
index
[
oid
]
seek
(
pos
)
h
=
read
(
22
)
doid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi"
,
h
)
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
vlen
:
pnv
=
read
(
4
)
return
_loadBack
(
file
,
oid
,
read
(
4
))
if
plen
:
return
read
(
plen
)
return
_loadBack
(
file
,
oid
,
pnv
)
for
oid
in
rootd
.
keys
():
del
index
[
oid
]
del
index
[
'
\
0
'
*
8
]
unreachable
=
index
.
has_key
seek
(
4
)
pos
=
4
tpos
=
0
while
1
:
# Read the transaction record
h
=
read
(
21
)
if
not
h
:
break
tid
,
prev
,
tl
,
status
,
ul
,
dl
=
unpack
(
">8siicHH"
,
h
)
if
tid
>=
stop
:
break
tpos
=
pos
tend
=
tpos
+
tl
if
status
==
'u'
:
# Undone transaction, skip it
pos
=
tpos
+
tl
+
4
seek
(
pos
)
continue
user
=
read
(
ul
)
desc
=
read
(
dl
)
pos
=
tpos
+
21
+
ul
+
dl
while
pos
<
tend
:
# Read the data records for this transaction
h
=
read
(
22
)
oid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi"
,
h
)
dlen
=
22
+
(
plen
or
4
)
+
vlen
if
vlen
:
dlen
=
vlen
+
8
seek
(
8
,
1
)
version
=
read
(
vlen
)
vindex
[
version
]
=
pos
pos
=
pos
+
dlen
if
pos
!=
tend
:
raise
CorruptedTransactionError
,
lastp
# Read the (intentionally redundant) transaction length
h
=
read
(
4
)
if
len
(
h
)
!=
4
:
raise
CorruptedTransactionError
,
h
if
unpack
(
">i"
,
h
)[
0
]
!=
tl
:
raise
CorruptedTransactionError
,
h
pos
=
pos
+
4
for
oid
,
p
in
tindex
:
index
[
oid
]
=
p
# Record the position
del
tindex
[:]
# Phase 2: copy the new records, adjusting all of the
# location pointers. We'll get the commit lock for this part.
finally
:
self
.
_r
()
def
store
(
self
,
oid
,
data
,
version
,
transaction
):
def
store
(
self
,
oid
,
serial
,
data
,
version
,
transaction
):
if
transaction
is
not
self
.
_transaction
:
if
transaction
is
not
self
.
_transaction
:
raise
POSException
.
StorageTransactionError
(
self
,
transaction
)
raise
POSException
.
StorageTransactionError
(
self
,
transaction
)
...
@@ -386,13 +365,14 @@ class FileStorage:
...
@@ -386,13 +365,14 @@ class FileStorage:
if
old
:
if
old
:
file
=
self
.
_file
file
=
self
.
_file
file
.
seek
(
old
)
file
.
seek
(
old
)
h
=
file
.
read
(
2
2
)
h
=
file
.
read
(
4
2
)
doid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi
"
,
h
)
doid
,
oserial
,
sprev
,
stloc
,
vlen
,
splen
=
unpack
(
">8s8s8s8sH8s
"
,
h
)
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
serial
!=
oserial
:
raise
POSException
.
ConflictError
if
vlen
:
if
vlen
:
pnv
=
read
(
4
)
pnv
=
read
(
8
)
# non-version data pointer
if
(
len
(
version
)
!=
vlen
or
if
(
len
(
version
)
!=
vlen
or
(
read
(
4
)
# skip past version link
(
read
(
8
)
# skip past version link
and
version
!=
read
(
vlen
))
and
version
!=
read
(
vlen
))
):
):
raise
POSException
.
VersionLockError
,
oid
raise
POSException
.
VersionLockError
,
oid
...
@@ -401,16 +381,24 @@ class FileStorage:
...
@@ -401,16 +381,24 @@ class FileStorage:
write
=
tfile
.
write
write
=
tfile
.
write
self
.
_tappend
(
oid
,
tfile
.
tell
())
self
.
_tappend
(
oid
,
tfile
.
tell
())
pos
=
self
.
_pos
pos
=
self
.
_pos
write
(
pack
(
">8siiHi"
,
oid
,
old
,
pos
,
len
(
version
),
len
(
data
)))
serial
=
self
.
_serial
write
(
pack
(
">8s8s8s8sH8s"
,
oid
,
serial
,
p64
(
old
),
p64
(
pos
),
len
(
version
),
p64
(
len
(
data
))
)
)
if
version
:
if
version
:
if
pnv
:
write
(
pnv
)
if
pnv
:
write
(
pnv
)
else
:
write
(
p
ack
(
">i"
,
old
))
else
:
write
(
p
64
(
old
))
# Link to last record for this version:
# Link to last record for this version:
vindex
=
self
.
_vindex
vindex
=
self
.
_vindex
write
(
p
ack
(
">i"
,
vindex
[
version
]))
write
(
p
64
(
vindex
[
version
]))
vindex
[
version
]
=
pos
vindex
[
version
]
=
pos
write
(
version
)
write
(
version
)
write
(
data
)
write
(
data
)
return
serial
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
supportsUndo
(
self
):
return
0
# for now
def
supportsUndo
(
self
):
return
0
# for now
...
@@ -435,6 +423,10 @@ class FileStorage:
...
@@ -435,6 +423,10 @@ class FileStorage:
self
.
_transaction
=
transaction
self
.
_transaction
=
transaction
del
self
.
_tindex
[:]
# Just to be sure!
del
self
.
_tindex
[:]
# Just to be sure!
self
.
_tfile
.
seek
(
0
)
self
.
_tfile
.
seek
(
0
)
t
=
time
.
time
()
t
=
apply
(
TimeStamp
,(
time
.
gmtime
(
t
)[:
5
]
+
(
t
%
60
,)))
self
.
_ts
=
t
=
t
.
laterThan
(
self
.
_ts
)
self
.
_serial
=
`t`
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
tpc_finish
(
self
,
transaction
,
f
=
None
):
def
tpc_finish
(
self
,
transaction
,
f
=
None
):
...
@@ -445,33 +437,35 @@ class FileStorage:
...
@@ -445,33 +437,35 @@ class FileStorage:
file
=
self
.
_file
file
=
self
.
_file
write
=
file
.
write
write
=
file
.
write
tfile
=
self
.
_tfile
tfile
=
self
.
_tfile
read
=
tfile
.
read
dlen
=
tfile
.
tell
()
dlen
=
tfile
.
tell
()
tfile
.
seek
(
0
)
tfile
.
seek
(
0
)
id
=
transaction
.
id
id
=
self
.
_serial
user
=
transaction
.
user
user
=
transaction
.
user
desc
=
transaction
.
description
desc
=
transaction
.
description
tlen
=
21
+
len
(
user
)
+
len
(
desc
)
ext
=
transaction
.
_extension
if
ext
:
ext
=
dumps
(
ext
,
1
)
else
:
ext
=
""
tlen
=
33
+
len
(
user
)
+
len
(
desc
)
+
len
(
ext
)
pos
=
self
.
_pos
pos
=
self
.
_pos
file
.
seek
(
pos
)
file
.
seek
(
pos
)
stpos
=
p64
(
self
.
_tpos
)
tl
=
tlen
+
dlen
tl
=
tlen
+
dlen
write
(
pack
(
">8siicHH"
,
stl
=
p64
(
tl
)
id
,
self
.
_tpos
,
tl
,
' '
,
len
(
user
),
len
(
desc
)))
write
(
pack
(
write
(
user
)
">8s"
"8s"
"8s"
"c"
"H"
"H"
"I"
write
(
desc
)
,
id
,
stpos
,
stl
,
' '
,
len
(
user
),
len
(
desc
),
len
(
ext
),
))
if
user
:
write
(
user
)
if
desc
:
write
(
desc
)
if
ext
:
write
(
ext
)
assert
dlen
>=
0
cp
(
tfile
,
file
,
dlen
)
while
dlen
>
0
:
d
=
read
(
min
(
dlen
,
8192
))
write
(
d
)
d
=
len
(
d
)
assert
dlen
>=
d
dlen
=
dlen
-
d
write
(
pack
(
">i"
,
tl
)
)
write
(
stl
)
file
.
flush
()
file
.
flush
()
self
.
_tpos
=
pos
self
.
_tpos
=
pos
self
.
_pos
=
pos
+
tl
+
4
self
.
_pos
=
pos
+
tl
+
8
index
=
self
.
_index
index
=
self
.
_index
dpos
=
pos
+
tlen
dpos
=
pos
+
tlen
...
@@ -483,29 +477,19 @@ class FileStorage:
...
@@ -483,29 +477,19 @@ class FileStorage:
finally
:
self
.
_r
()
finally
:
self
.
_r
()
def
undo
(
self
,
transaction_id
):
def
undo
(
self
,
transaction_id
):
# TBD
pass
pass
def
undoLog
(
self
,
version
,
first
,
last
,
path
):
def
undoLog
(
self
,
version
,
first
,
last
,
path
):
# TBD
return
[]
return
[]
def
versionEmpty
(
self
,
version
):
def
versionEmpty
(
self
,
version
):
self
.
_a
()
return
not
self
.
_vindex
.
has_key
(
version
)
try
:
pos
=
self
.
_index
[
oid
]
file
=
self
.
_file
file
.
seek
(
pos
)
doid
,
prev
,
tloc
,
vlen
=
unpack
(
">8siiH"
,
file
.
read
(
18
))
if
doid
!=
oid
:
raise
CorruptedDataError
,
h
if
not
vlen
or
vlen
!=
len
(
version
):
return
1
seek
(
4
,
1
)
return
read
(
vlen
)
!=
version
finally
:
self
.
_r
()
packed_version
=
'FS10'
def
read_index
(
file
,
name
,
index
,
vindex
,
tindex
,
stop
=
'
\
377
'
*
8
,
def
read_index
(
file
,
index
,
vindex
,
tindex
,
stop
=
'
\
377
'
*
8
):
log
=
lambda
s
:
None
):
indexpos
=
index
.
get
indexpos
=
index
.
get
vndexpos
=
vindex
.
get
vndexpos
=
vindex
.
get
tappend
=
tindex
.
append
tappend
=
tindex
.
append
...
@@ -524,19 +508,62 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
...
@@ -524,19 +508,62 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
pos
=
4
pos
=
4
unpack
=
struct
.
unpack
unpack
=
struct
.
unpack
tpos
=
0
tpos
=
0
maxoid
=
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
maxoid
=
ltid
=
z64
tid
=
'
\
0
'
*
7
+
'
\
1
'
while
1
:
while
1
:
# Read the transaction record
# Read the transaction record
h
=
read
(
21
)
h
=
read
(
33
)
if
not
h
:
break
if
not
h
:
break
if
len
(
h
)
!=
21
:
raise
CorruptedTransactionError
,
h
if
len
(
h
)
!=
33
:
tid
,
prev
,
tl
,
status
,
ul
,
dl
=
unpack
(
">8siicHH"
,
h
)
warn
(
log
,
'%s truncated at %s'
,
name
,
pos
)
if
(
prev
!=
tpos
seek
(
pos
)
or
status
not
in
' up'
or
ul
>
tl
or
dl
>
tl
file
.
truncate
()
or
tl
>
file_size
or
tl
+
pos
>=
file_size
):
break
raise
CorruptedTransactionRecordError
,
h
tid
,
sprev
,
stl
,
status
,
ul
,
dl
,
el
=
unpack
(
">8s8s8scHHi"
,
h
)
if
el
<
0
:
el
=
t32
-
el
if
tid
<=
ltid
:
warn
(
log
,
"%s time-stamp reduction at %s"
,
name
,
pos
)
ltid
=
tid
prev
=
u64
(
sprev
)
tl
=
u64
(
stl
)
if
tl
+
pos
+
8
>
file_size
:
# Hm, the data were truncated. They may also be corrupted,
# in which case, we don't want to totally lose the data.
warn
(
log
,
"%s truncated, possibly due to damaged records at %s"
,
name
,
pos
)
try
:
i
=
0
while
1
:
if
os
.
path
.
exists
(
'%s.tr%s'
%
(
name
,
i
)):
i
=
i
+
1
else
:
o
=
open
(
'%s.tr%s'
%
(
name
,
i
),
'wb'
)
seek
(
pos
)
cp
(
file
,
o
,
file_size
-
pos
)
o
.
close
()
break
except
:
error
(
log
,
"couldn
\
'
t write truncated data for %s"
,
name
)
raise
POSException
.
StorageSystemError
,
(
"Couldn't save truncated data"
)
seek
(
pos
)
file
.
truncate
()
break
if
status
not
in
' up'
:
warn
(
log
,
'%s has invalid status, %s, at %s'
,
name
,
status
,
pos
)
if
prev
!=
tpos
or
ul
>
tl
or
dl
>
tl
or
el
>
tl
:
panic
(
log
,
'%s has invalid transaction header at %s'
,
name
,
pos
)
if
tid
>=
stop
:
break
if
tid
>=
stop
:
break
tpos
=
pos
tpos
=
pos
tend
=
tpos
+
tl
tend
=
tpos
+
tl
...
@@ -544,45 +571,56 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
...
@@ -544,45 +571,56 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
# Undone transaction, skip it
# Undone transaction, skip it
pos
=
tpos
+
tl
pos
=
tpos
+
tl
seek
(
pos
)
seek
(
pos
)
h
=
read
(
4
)
h
=
read
(
8
)
if
len
(
h
)
!=
4
:
raise
CorruptedTransactionError
,
h
if
h
!=
stl
:
if
unpack
(
">i"
,
h
)[
0
]
!=
tl
:
panic
(
log
,
'%s has inconsistent transaction length at %s'
,
raise
CorruptedTransactionError
,
h
name
,
pos
)
pos
=
pos
+
4
pos
=
pos
+
8
continue
continue
pos
=
tpos
+
21
+
ul
+
dl
pos
=
tpos
+
33
+
ul
+
dl
while
pos
<
tend
:
while
pos
<
tend
:
# Read the data records for this transaction
# Read the data records for this transaction
seek
(
pos
)
seek
(
pos
)
h
=
read
(
2
2
)
h
=
read
(
4
2
)
oid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi
"
,
h
)
oid
,
serial
,
sprev
,
stloc
,
vlen
,
splen
=
unpack
(
">8s8s8s8sH8s
"
,
h
)
dlen
=
22
+
(
plen
or
4
)
+
vlen
prev
=
u64
(
sprev
)
if
pos
+
dlen
>
tend
or
tloc
!=
tpos
:
tloc
=
u64
(
stloc
)
raise
CorruptedDataError
,
h
plen
=
u64
(
splen
)
if
indexpos
(
oid
,
0
)
!=
prev
:
raise
CorruptedDataError
,
h
dlen
=
42
+
(
plen
or
8
)
+
vlen
tappend
((
oid
,
pos
))
tappend
((
oid
,
pos
))
if
vlen
:
if
vlen
:
dlen
=
vlen
+
8
dlen
=
vlen
+
16
seek
(
8
,
1
)
seek
(
8
,
1
)
pv
=
u64
(
read
(
8
))
version
=
read
(
vlen
)
version
=
read
(
vlen
)
if
vndexpos
(
version
,
0
)
!=
pv
:
panic
(
log
,
"%s incorrect previous version pointer at %s"
,
name
,
pos
)
vindex
[
version
]
=
pos
vindex
[
version
]
=
pos
if
pos
+
dlen
>
tend
or
tloc
!=
tpos
:
panic
(
log
,
"%s data record exceeds transaction record at %s"
,
name
,
pos
)
if
indexpos
(
oid
,
0
)
!=
prev
:
panic
(
log
,
"%s incorrect previous pointer at %s"
,
name
,
pos
)
pos
=
pos
+
dlen
pos
=
pos
+
dlen
if
pos
!=
tend
:
if
pos
!=
tend
:
raise
CorruptedTransactionError
,
lastp
panic
(
log
,
"%s data records don't add up at %s"
,
name
,
tpos
)
# Read the (intentionally redundant) transaction length
# Read the (intentionally redundant) transaction length
seek
(
pos
)
seek
(
pos
)
h
=
read
(
4
)
h
=
read
(
8
)
if
len
(
h
)
!=
4
:
raise
CorruptedTransactionError
,
h
if
h
!=
stl
:
if
unpack
(
">i"
,
h
)[
0
]
!=
tl
:
panic
(
log
,
"%s redundant transaction length check failed at %s"
,
raise
CorruptedTransactionError
,
h
name
,
pos
)
pos
=
pos
+
4
pos
=
pos
+
8
for
oid
,
p
in
tindex
:
for
oid
,
p
in
tindex
:
maxoid
=
max
(
maxoid
,
oid
)
maxoid
=
max
(
maxoid
,
oid
)
...
@@ -590,7 +628,7 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
...
@@ -590,7 +628,7 @@ def read_index(file, index, vindex, tindex, stop='\377'*8):
del
tindex
[:]
del
tindex
[:]
return
pos
,
tpos
,
maxoid
return
pos
,
tpos
,
maxoid
,
ltid
def
_loadBack
(
file
,
oid
,
back
):
def
_loadBack
(
file
,
oid
,
back
):
...
@@ -598,8 +636,12 @@ def _loadBack(file, oid, back):
...
@@ -598,8 +636,12 @@ def _loadBack(file, oid, back):
old
=
unpack
(
">i"
,
back
)[
0
]
old
=
unpack
(
">i"
,
back
)[
0
]
if
not
old
:
raise
KeyError
,
oid
if
not
old
:
raise
KeyError
,
oid
file
.
seek
(
old
)
file
.
seek
(
old
)
h
=
file
.
read
(
22
)
h
=
file
.
read
(
42
)
doid
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8siiHi"
,
h
)
doid
,
serial
,
prev
,
tloc
,
vlen
,
plen
=
unpack
(
">8s8s8s8sH8s"
,
h
)
if
doid
!=
oid
or
vlen
:
raise
CorruptedDataError
,
h
if
doid
!=
oid
or
vlen
:
if
plen
:
return
read
(
plen
)
panic
(
lambda
x
:
None
,
"%s version record back pointer points to "
"invalid record as %s"
,
name
,
back
)
if
plen
:
return
read
(
plen
),
serial
back
=
read
(
4
)
# We got a back pointer!
back
=
read
(
4
)
# We got a back pointer!
trunk/src/ZODB/IIBTree.c
deleted
100755 → 0
View file @
77e0ce28
/* $Id: IIBTree.c,v 1.4 1997/10/10 18:23:37 jim Exp $ */
#define INTKEY int
#define INTVAL int
static
char
*
needed_to_make_release_happy
=
"$Id: IIBTree.c,v 1.4 1997/10/10 18:23:37 jim Exp $"
;
#include "BTree.c"
trunk/src/ZODB/IOBTree.c
deleted
100755 → 0
View file @
77e0ce28
/* $Id: IOBTree.c,v 1.4 1997/10/10 18:24:11 jim Exp $ */
static
char
*
needed_to_make_release_happy
=
"$Id: IOBTree.c,v 1.4 1997/10/10 18:24:11 jim Exp $"
;
#define INTKEY int
#include "BTree.c"
trunk/src/ZODB/OIBTree.c
deleted
100755 → 0
View file @
77e0ce28
/* $Id: OIBTree.c,v 1.4 1997/10/10 18:24:35 jim Exp $ */
static
char
*
needed_to_make_release_happy
=
"$Id: OIBTree.c,v 1.4 1997/10/10 18:24:35 jim Exp $"
;
#define INTVAL int
#include "BTree.c"
trunk/src/ZODB/Persistence.py
deleted
100644 → 0
View file @
77e0ce28
##############################################################################
#
# Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS IS*
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
#
# If you have questions regarding this software, contact:
#
# Digital Creations, L.C.
# 910 Princess Ann Street
# Fredericksburge, Virginia 22401
#
# info@digicool.com
#
# (540) 371-6909
#
##############################################################################
'''Python implementation of a persistent base types
$Id: Persistence.py,v 1.17 1998/11/11 02:00:56 jim Exp $'''
__version__
=
'$Revision: 1.17 $'
[
11
:
-
2
]
_marker
=
[]
class
Persistent
:
"""
\
Persistent object support mix-in class
When a persistent object is loaded from a database, the object's
data is not immediately loaded. Loading of the objects data is
defered until an attempt is made to access an attribute of the
object.
The object also tries to keep track of whether it has changed. It
is easy for this to be done incorrectly. For this reason, methods
of subclasses that change state other than by setting attributes
should: 'self.__changed__(1)' to flag instances as changed.
You must not override the object's '__getattr__' and '__setattr__'
methods. If you override the objects '__getstate__' method, then
you must be careful not to include any attributes with names
starting with '_p_' or '_v_' in the state.
"""
_p_oid
=
None
# A Persistent object-id, unique within a jar
_p_changed
=
0
# The object state: None=ghost, 0=normal, 1=changed
_p_jar
=
None
# The last jar that this object was stored in.
def
_p_deactivate
(
self
):
d
=
self
.
__dict__
oid
=
d
[
'_p_oid'
]
jar
=
d
[
'_p_jar'
]
d
.
clear
()
d
[
'_p_oid'
]
=
oid
d
[
'_p_jar'
]
=
jar
d
[
'_p_changed'
]
=
None
def
__getattr__
(
self
,
key
):
'Get an item'
if
self
.
_p_changed
is
None
and
key
[:
3
]
!=
'_p_'
:
self
.
_p_jar
.
setstate
(
self
)
if
self
.
__dict__
.
has_key
(
key
):
return
self
.
__dict__
[
key
]
raise
AttributeError
,
key
def
__setattr__
(
self
,
key
,
value
):
' '
changed
=
self
.
_p_changed
if
changed
:
self
.
__dict__
[
key
]
=
value
return
k
=
key
[:
3
]
if
k
==
'_p_'
or
k
==
'_v_'
:
if
key
==
'_p_changed'
:
if
changed
==
value
:
return
if
value
:
if
changed
:
return
try
:
if
self
.
_p_jar
and
self
.
_p_oid
:
get_transaction
().
register
(
self
)
except
:
pass
elif
value
is
None
:
if
self
.
_p_jar
and
self
.
_p_oid
:
return
self
.
_p_deactivate
()
return
value
=
not
not
value
self
.
__dict__
[
key
]
=
value
return
jar
=
self
.
_p_jar
if
jar
is
None
:
self
.
__dict__
[
key
]
=
value
return
d
=
self
.
__dict__
if
changed
is
None
:
d
[
'_p_changed'
]
=
1
jar
.
setstate
(
self
)
d
[
key
]
=
value
try
:
get_transaction
().
register
(
self
)
d
[
'_p_changed'
]
=
1
except
:
pass
def
__changed__
(
self
,
v
=
_marker
):
if
v
is
_marker
:
return
not
not
self
.
_p_changed
self
.
_p_changed
=
not
not
v
def
__getstate__
(
self
):
# First, update my state, if necessary:
if
self
.
_p_changed
is
None
:
self
.
_p_jar
.
setstate
(
self
)
state
=
{}
d
=
self
.
__dict__
for
k
,
v
in
d
.
items
():
if
k
[:
3
]
!=
'_p_'
and
k
[:
3
]
!=
'_v_'
:
state
[
k
]
=
v
return
state
def
__setstate__
(
self
,
state
):
self
.
__dict__
.
update
(
state
)
def
__repr__
(
self
):
' '
return
'<%s instance at %s>'
%
(
self
.
__class__
.
__name__
,
hex
(
id
(
self
)))
trunk/src/ZODB/PersistentMapping.py
View file @
69c8c4a9
...
@@ -48,12 +48,12 @@
...
@@ -48,12 +48,12 @@
__doc__
=
'''Python implementation of persistent base types
__doc__
=
'''Python implementation of persistent base types
$Id: PersistentMapping.py,v 1.
3 1998/11/11 02:00:56
jim Exp $'''
$Id: PersistentMapping.py,v 1.
4 1999/05/07 01:03:03
jim Exp $'''
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
4
$'
[
11
:
-
2
]
import
Persistence
import
Persistence
class
P
M
(
Persistence
.
Persistent
):
class
P
ersistentMapping
(
Persistence
.
Persistent
):
"""A persistent wrapper for mapping objects.
"""A persistent wrapper for mapping objects.
This class allows wrapping of mapping objects so that
This class allows wrapping of mapping objects so that
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
def
values
(
self
):
def
values
(
self
):
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
PersistentMapping
=
PM
trunk/src/ZODB/PickleCache.py
deleted
100644 → 0
View file @
77e0ce28
##############################################################################
#
# Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS IS*
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
#
# If you have questions regarding this software, contact:
#
# Digital Creations, L.C.
# 910 Princess Ann Street
# Fredericksburge, Virginia 22401
#
# info@digicool.com
#
# (540) 371-6909
#
##############################################################################
__doc__
=
'''PickleJar Object Cache
$Id: PickleCache.py,v 1.5 1998/11/11 02:00:56 jim Exp $'''
__version__
=
'$Revision: 1.5 $'
[
11
:
-
2
]
from
sys
import
getrefcount
class
PickleCache
:
def
__init__
(
self
,
cache_size
,
cache_age
=
1000
):
if
cache_size
<
1
:
cache_size
=
1
self
.
cache_size
=
cache_size
self
.
data
,
self
.
cache_ids
,
self
.
cache_location
=
{},
[],
0
for
a
in
'keys'
,
'items'
,
'values'
,
'has_key'
:
setattr
(
self
,
a
,
getattr
(
self
.
data
,
a
))
def
__getitem__
(
self
,
key
):
v
=
self
.
data
[
key
]
self
.
incrgc
()
return
v
def
incrgc
(
self
):
# Do cache GC
cache
=
self
.
data
n
=
min
(
len
(
cache
)
/
self
.
cache_size
,
10
)
if
n
:
l
=
self
.
cache_location
ids
=
self
.
cache_ids
while
n
:
if
not
l
:
ids
=
self
.
cache_ids
=
cache
.
keys
()
l
=
len
(
ids
)
l
=
l
-
1
n
=
n
-
1
id
=
ids
[
l
]
if
getrefcount
(
cache
[
id
])
<=
2
:
del
cache
[
id
]
self
.
cache_location
=
l
def
__setitem__
(
self
,
key
,
v
):
self
.
data
[
key
]
=
v
self
.
incrgc
()
def
__delitem__
(
self
,
key
):
del
self
.
data
[
key
]
self
.
incrgc
()
def
__len__
(
self
):
return
len
(
self
.
data
)
def
values
(
self
):
return
self
.
data
.
values
()
def
full_sweep
(
self
):
cache
=
self
.
data
for
id
in
cache
.
keys
():
if
getrefcount
(
cache
[
id
])
<=
2
:
del
cache
[
id
]
def
minimize
(
self
):
cache
=
self
.
data
keys
=
cache
.
keys
()
rc
=
getrefcount
last
=
None
l
=
len
(
cache
)
while
l
!=
last
:
for
id
in
keys
():
if
rc
(
cache
[
id
])
<=
2
:
del
cache
[
id
]
cache
[
id
].
_p_deactivate
()
l
=
len
(
cache
)
trunk/src/ZODB/Setup
View file @
69c8c4a9
*shared*
*shared*
cPersistence cPersistence.c -I../ExtensionClass -I../python
cPersistence cPersistence.c -I../../Components/ExtensionClass
cPickleCache cPickleCache.c -I../ExtensionClass -I../python
cPickleCache cPickleCache.c -I../../Components/ExtensionClass
cPickleJar ./cPickleJar.c -I../ExtensionClass
iTree ./iTree.c -I../ExtensionClass
intSet ./intSet.c -I/projects/_/ExtensionClass -I/projects/_/cPersistence -I/projects/_/python
BTree ./BTree.c -I/projects/_/ExtensionClass -I/projects/_/cPersistence -I/projects/_/python
IIBTree ./IIBTree.c -I/projects/_/ExtensionClass -I/projects/_/cPersistence -I/projects/_/python
IOBTree ./IOBTree.c -I/projects/_/ExtensionClass -I/projects/_/cPersistence -I/projects/_/python
OIBTree ./OIBTree.c -I/projects/_/ExtensionClass -I/projects/_/cPersistence -I/projects/_/python
#cPickleJar cPickleJar.c -I../../Components/ExtensionClass
#iTree iTree.c -I../../Components/ExtensionClass
trunk/src/ZODB/Transaction.py
View file @
69c8c4a9
...
@@ -47,29 +47,26 @@
...
@@ -47,29 +47,26 @@
##############################################################################
##############################################################################
"""Transaction management
"""Transaction management
$Id: Transaction.py,v 1.
3 1998/11/11 02:00:56
jim Exp $"""
$Id: Transaction.py,v 1.
4 1999/05/07 01:03:03
jim Exp $"""
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
4
$'
[
11
:
-
2
]
import
time
,
sys
,
struct
import
time
,
sys
,
struct
from
struct
import
pack
from
struct
import
pack
from
string
import
split
,
strip
,
join
from
string
import
split
,
strip
,
join
ConflictError
=
""
from
POSException
import
ConflictError
class
Transaction
:
class
Transaction
:
'Simple transaction objects for single-threaded applications.'
'Simple transaction objects for single-threaded applications.'
user
=
''
user
=
''
description
=
''
description
=
''
_connections
=
None
_connections
=
None
_extension
=
None
def
__init__
(
self
,
def
__init__
(
self
,
time
=
time
.
time
,
pack
=
struct
.
pack
,
gmtime
=
time
.
gmtime
):
time
=
time
.
time
,
pack
=
struct
.
pack
,
gmtime
=
time
.
gmtime
):
self
.
_objects
=
[]
self
.
_objects
=
[]
self
.
_append
=
self
.
_objects
.
append
self
.
_append
=
self
.
_objects
.
append
self
.
time
=
now
=
time
()
y
,
mo
,
d
,
h
,
m
=
gmtime
(
now
)[:
5
]
s
=
int
((
now
%
60
)
*
1000000
)
self
.
id
=
pack
(
"<II"
,
(((
y
*
12
+
mo
)
*
31
+
d
)
*
24
+
h
)
*
60
+
m
,
s
)
self
.
_note
=
self
.
_user
=
self
.
_description
=
''
self
.
_note
=
self
.
_user
=
self
.
_description
=
''
if
self
.
_connections
:
if
self
.
_connections
:
for
c
in
self
.
_connections
.
values
():
c
.
close
()
for
c
in
self
.
_connections
.
values
():
c
.
close
()
...
@@ -136,15 +133,20 @@ class Transaction:
...
@@ -136,15 +133,20 @@ class Transaction:
'Register the given object for transaction control.'
'Register the given object for transaction control.'
self
.
_append
(
object
)
self
.
_append
(
object
)
def
remark
(
self
,
text
):
def
note
(
self
,
text
):
if
self
.
description
:
if
self
.
description
:
self
.
description
=
"%s
\
n
\
n
%s"
%
(
self
.
description
,
strip
(
text
))
self
.
description
=
"%s
\
n
\
n
%s"
%
(
self
.
description
,
strip
(
text
))
else
:
else
:
self
.
description
=
strip
(
text
)
self
.
description
=
strip
(
text
)
def
setUser
(
self
,
user_name
,
path
=
'/'
):
def
setUser
(
self
,
user_name
,
path
=
'/'
):
self
.
user
=
"%s %s"
%
(
path
,
user_name
)
self
.
user
=
"%s %s"
%
(
path
,
user_name
)
def
setExtendedInfo
(
self
,
name
,
value
):
ext
=
self
.
_extension
if
ext
is
None
:
ext
=
self
.
_extension
=
{}
ext
[
name
]
=
value
############################################################################
############################################################################
...
@@ -175,9 +177,4 @@ del _t
...
@@ -175,9 +177,4 @@ del _t
import
__main__
import
__main__
__main__
.
__builtins__
.
get_transaction
=
get_transaction
__main__
.
__builtins__
.
get_transaction
=
get_transaction
def
time2id
(
now
,
gmtime
=
time
.
gmtime
,
pack
=
struct
.
pack
):
y
,
m
,
d
,
h
,
m
=
gmtime
(
now
)[:
5
]
s
=
int
((
now
%
60
)
*
1000000
)
return
pack
(
"<II"
,
((
y
*
12
+
m
)
*
31
+
d
)
*
24
,
s
)
trunk/src/ZODB/ZApplication.py
View file @
69c8c4a9
...
@@ -50,9 +50,9 @@
...
@@ -50,9 +50,9 @@
This module provides a wrapper that causes a database connection to be created
This module provides a wrapper that causes a database connection to be created
and used when bobo publishes a bobo_application object.
and used when bobo publishes a bobo_application object.
"""
"""
__version__
=
'$Revision: 1.
1
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
class
BoboApplication
:
class
ZApplicationWrapper
:
def
__init__
(
self
,
db
,
name
,
klass
=
None
,
klass_args
=
(),
def
__init__
(
self
,
db
,
name
,
klass
=
None
,
klass_args
=
(),
version_cookie_name
=
None
):
version_cookie_name
=
None
):
...
@@ -94,8 +94,14 @@ class BoboApplication:
...
@@ -94,8 +94,14 @@ class BoboApplication:
return
v
return
v
__call__
=
__bobo_traverse__
# A convenience for command-line use
def
__call__
(
self
,
connection
=
None
):
db
,
aname
,
version_support
=
self
.
_stuff
if
connection
is
None
:
connection
=
db
.
open
()
return
connection
.
root
()[
aname
]
class
Cleanup
:
pass
class
Cleanup
:
pass
...
...
trunk/src/ZODB/__init__.py
View file @
69c8c4a9
...
@@ -45,7 +45,26 @@
...
@@ -45,7 +45,26 @@
# (540) 371-6909
# (540) 371-6909
#
#
##############################################################################
##############################################################################
import
sys
,
ExtensionClass
,
TimeStamp
,
cPersistence
,
Persistence
# This is lame. Don't look. :(
sys
.
modules
[
'cPersistence'
]
=
cPersistence
Persistent
=
cPersistence
.
Persistent
del
cPersistence
# Install Persistent and PersistentMapping in Persistence
if
not
hasattr
(
Persistence
,
'Persistent'
):
Persistence
.
Persistent
=
Persistent
Persistent
.
__module__
=
'Persistence'
if
not
hasattr
(
Persistence
,
'PersistentMapping'
):
from
PersistentMapping
import
PersistentMapping
Persistence
.
PersistentMapping
=
PersistentMapping
PersistentMapping
.
__module__
=
'Persistence'
del
PersistentMapping
from
DB
import
DB
from
DB
import
DB
from
Persistence
import
Persistent
from
POSException
import
*
import
Transaction
del
Transaction
trunk/src/ZODB/cPersistence.c
View file @
69c8c4a9
/***********************************************************************
/***********************************************************************
$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $
C Persistence Module
C Persistence Module
...
@@ -12,16 +12,19 @@
...
@@ -12,16 +12,19 @@
*****************************************************************************/
*****************************************************************************/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $"
;
#include <
time
.h>
#include <
string
.h>
#include "cPersistence.h"
#include "cPersistence.h"
#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)
#define OBJECT(V) ((PyObject*)(V))
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
;
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
,
*
py_timeTime
;
static
PyObject
*
TimeStamp
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
static
PyObject
*
debug_log
=
0
;
static
PyObject
*
debug_log
=
0
;
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
/*
/*
printf("%s %p\n",event,self->ob_type->tp_name);
printf("%s %p\n",event,self->ob_type->tp_name);
*/
*/
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
s#
i)"
,
event
,
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
O
i)"
,
event
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
8
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
self
->
state
);
self
->
state
);
Py_XDECREF
(
r
);
Py_XDECREF
(
r
);
}
}
...
@@ -48,6 +51,7 @@ init_strings()
...
@@ -48,6 +51,7 @@ init_strings()
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
keys
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
setstate
);
INIT_STRING
(
timeTime
);
INIT_STRING
(
__dict__
);
INIT_STRING
(
__dict__
);
#undef INIT_STRING
#undef INIT_STRING
}
}
...
@@ -201,14 +205,16 @@ static PyObject *
...
@@ -201,14 +205,16 @@ static PyObject *
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
v
=
0
;
PyObject
*
v
=
0
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
v
&&
!
PyObject_IsTrue
(
v
))
if
(
!
v
)
return
PyObject_GetAttrString
(
OBJECT
(
self
),
"_p_changed"
);
if
(
PyObject_IsTrue
(
v
))
{
{
PyErr_SetString
(
PyExc_TypeError
,
if
(
changed
(
self
)
<
0
)
return
NULL
;
"Only true arguments are allowed."
);
return
NULL
;
}
}
if
(
changed
(
self
)
<
0
)
return
NULL
;
else
if
(
self
->
state
>=
0
)
self
->
state
=
cPersistent_UPTODATE_STATE
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
static
PyObject
*
orNothing
(
PyObject
*
v
)
{
if
(
!
v
)
v
=
Py_None
;
Py_INCREF
(
v
);
return
v
;
}
static
PyObject
*
static
PyObject
*
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
{
{
char
*
n
=
name
;
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
n
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
{
switch
(
*
n
++
)
switch
(
*
n
++
)
{
{
case
'o'
:
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
return
orNothing
(
self
->
oid
);
return
PyString_FromStringAndSize
(
self
->
oid
,
8
);
break
;
break
;
case
'j'
:
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
return
orNothing
(
self
->
jar
);
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
break
;
case
'c'
:
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
cPersistent_CHANGED_STATE
);
cPersistent_CHANGED_STATE
);
}
}
break
;
break
;
case
's'
:
if
(
strcmp
(
n
,
"erial"
)
==
0
)
return
PyString_FromStringAndSize
(
self
->
serial
,
8
);
break
;
case
'm'
:
if
(
strcmp
(
n
,
"time"
)
==
0
)
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
oname
=
PyString_FromStringAndSize
(
self
->
serial
,
8
);
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallFunction
(
TimeStamp
,
"O"
,
oname
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_GetAttr
(
oname
,
py_timeTime
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallObject
(
oname
,
NULL
));
return
oname
;
}
break
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
if
(
!
(
name
&&
*
name
++==
'_'
&&
*
name
++==
'_'
&&
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
||
strcmp
(
name
,
"of__"
)
==
0
)))
||
strcmp
(
name
,
"of__"
)
==
0
)))
{
{
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
static
PyObject
*
static
PyObject
*
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
{
{
char
*
s
;
char
*
s
=
NULL
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
if
(
PyString_Check
(
name
))
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
}
}
static
int
static
int
...
@@ -456,27 +479,36 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -456,27 +479,36 @@ _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
(
!
v
)
return
bad_delattr
();
Py_XINCREF
(
v
);
if
(
PyString_Check
(
v
)
&&
PyString_GET_SIZE
(
v
)
==
8
)
ASSIGN
(
self
->
oid
,
v
);
memcpy
(
self
->
oid
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_AttributeError
,
"_p_oid must be an 8-character string"
);
return
-
1
;
}
return
0
;
return
0
;
}
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
jar
,
v
);
ASSIGN
(
self
->
jar
,
v
);
Py_XINCREF
(
self
->
jar
);
return
0
;
return
0
;
}
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
if
(
name
[
3
]
==
's'
&&
strcmp
(
name
+
4
,
"erial"
)
==
0
)
{
{
if
(
!
v
)
return
bad_delattr
();
if
(
v
)
if
(
v
==
Py_None
)
{
if
(
PyString_Check
(
v
)
&&
PyString_Size
(
v
)
==
8
)
memcpy
(
self
->
serial
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_ValueError
,
"_p_serial must be an 8-character string"
);
return
-
1
;
}
}
else
memset
(
self
->
serial
,
0
,
8
);
return
0
;
}
if
(
name
[
3
]
==
'c'
&&
strcmp
(
name
+
4
,
"hanged"
)
==
0
)
{
if
(
!
v
||
v
==
Py_None
)
{
{
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
return
0
;
return
0
;
...
@@ -585,8 +617,15 @@ void
...
@@ -585,8 +617,15 @@ void
initcPersistence
()
initcPersistence
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.25 $"
;
char
*
rev
=
"$Revision: 1.26 $"
;
TimeStamp
=
PyString_FromString
(
"TimeStamp"
);
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyImport_Import
(
TimeStamp
));
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyObject_GetAttrString
(
TimeStamp
,
"TimeStamp"
));
if
(
!
TimeStamp
)
return
;
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
""
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/ZODB/cPersistence.h
View file @
69c8c4a9
/*
/*
$Id: cPersistence.h,v 1.1
0 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.h,v 1.1
1 1999/05/07 01:03:03
jim Exp $
Definitions to facilitate making cPersistent subclasses in C.
Definitions to facilitate making cPersistent subclasses in C.
...
@@ -15,9 +15,11 @@
...
@@ -15,9 +15,11 @@
#define cPersistent_HEAD PyObject_HEAD \
#define cPersistent_HEAD PyObject_HEAD \
PyObject *jar; \
PyObject *jar; \
char oid[8]; \
PyObject *oid; \
char serial[8]; \
unsigned short atime; \
unsigned short atime; \
signed char state; \
signed char state; \
unsigned char reserved; \
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
...
@@ -43,6 +45,8 @@ typedef struct {
...
@@ -43,6 +45,8 @@ typedef struct {
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
#define cPersistanceModuleName "cPersistence"
#define PER_USE_OR_RETURN(O,R) { \
#define PER_USE_OR_RETURN(O,R) { \
if ((O)->state==cPersistent_GHOST_STATE && \
if ((O)->state==cPersistent_GHOST_STATE && \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
((O)->state==cPersistent_STICKY_STATE && \
((O)->state==cPersistent_STICKY_STATE && \
((O)->state=cPersistent_UPTODATE_STATE))
((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) \
((O)->state==cPersistent_UPTODATE_STATE && \
((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O) Py_XDECREF((O)->jar)
#define PER_DEL(O) Py_XDECREF((O)->jar)
#endif
#endif
...
...
trunk/src/ZODB/cPickleCache.c
View file @
69c8c4a9
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
6 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
7 1999/05/07 01:03:03
jim Exp $"
;
#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))
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
/* Declarations for objects of type cCache */
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
PyObject
*
data
;
PyObject
*
data
;
PyObject
*
jar
;
int
position
;
int
position
;
int
cache_size
;
int
cache_size
;
int
cache_age
;
int
cache_age
;
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
if
(
dt
&&
v
->
ob_type
->
tp_basicsize
>=
sizeof
(
cPersistentObject
)
&&
if
(
dt
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
(
!
PyExtensionClass_Check
(
v
))
&&
((
cPersistentObject
*
)
v
)
->
jar
==
self
->
jar
/* I'm paranoid */
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
{
{
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
if
(
now
<
0
)
now
+=
65536
;
if
(
now
<
0
)
now
+=
65536
;
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
};
};
static
ccobject
*
static
ccobject
*
newccobject
(
int
cache_size
,
int
cache_age
)
newccobject
(
PyObject
*
jar
,
int
cache_size
,
int
cache_age
)
{
{
ccobject
*
self
;
ccobject
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
if
(
self
->
data
=
PyDict_New
())
if
(
self
->
data
=
PyDict_New
())
{
{
self
->
jar
=
jar
;
Py_INCREF
(
jar
);
self
->
position
=
0
;
self
->
position
=
0
;
self
->
cache_size
=
cache_size
;
self
->
cache_size
=
cache_size
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
...
@@ -312,6 +315,7 @@ static void
...
@@ -312,6 +315,7 @@ static void
cc_dealloc
(
ccobject
*
self
)
cc_dealloc
(
ccobject
*
self
)
{
{
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
jar
);
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
return
r
;
return
r
;
}
}
static
PyExtensionClass
*
Persistent
=
0
;
static
int
static
int
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
{
if
(
v
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
if
(
v
)
{
if
(
PyExtensionClass_Check
(
v
)
||
(
PyExtensionInstance_Check
(
v
)
&&
ExtensionClassSubclassInstance_Check
(
v
,
Persistent
)
)
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
PyErr_SetString
(
PyExc_ValueError
,
"Cache values must be persistent objects or classes."
);
return
-
1
;
}
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
...
@@ -446,8 +464,10 @@ static PyObject *
...
@@ -446,8 +464,10 @@ static PyObject *
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
{
{
int
cache_size
=
100
,
cache_age
=
1000
;
int
cache_size
=
100
,
cache_age
=
1000
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|ii"
,
&
cache_size
,
&
cache_age
))
return
NULL
;
PyObject
*
jar
;
return
(
PyObject
*
)
newccobject
(
cache_size
,
cache_age
);
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|ii"
,
&
jar
,
&
cache_size
,
&
cache_age
))
return
NULL
;
return
(
PyObject
*
)
newccobject
(
jar
,
cache_size
,
cache_age
);
}
}
static
struct
PyMethodDef
cCM_methods
[]
=
{
static
struct
PyMethodDef
cCM_methods
[]
=
{
...
@@ -459,10 +479,20 @@ void
...
@@ -459,10 +479,20 @@ void
initcPickleCache
()
initcPickleCache
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.1
6
$"
;
char
*
rev
=
"$Revision: 1.1
7
$"
;
Cctype
.
ob_type
=&
PyType_Type
;
Cctype
.
ob_type
=&
PyType_Type
;
UNLESS
(
ExtensionClassImported
)
return
;
/* Get the Persistent base class */
UNLESS
(
m
=
PyString_FromString
(
cPersistanceModuleName
))
return
;
ASSIGN
(
m
,
PyImport_Import
(
m
));
UNLESS
(
m
)
return
;
ASSIGN
(
m
,
PyObject_GetAttrString
(
m
,
"Persistent"
));
UNLESS
(
m
)
return
;
Persistent
=
(
PyExtensionClass
*
)
m
;
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/ZODB/intSet.c
deleted
100644 → 0
View file @
77e0ce28
/***********************************************************
Copyright
Copyright 1997 Digital Creations, L.L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved.
******************************************************************/
static
char
intSet_module_documentation
[]
=
""
"
\n
$Id: intSet.c,v 1.10 1998/11/11 02:00:56 jim Exp $"
;
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <time.h>
#include "cPersistence.h"
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;}
#define ASSIGN(V,E) PyVar_Assign(&(V),(E))
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E); UNLESS(V)
#define RETURN_NONE Py_INCREF(Py_None); return Py_None
#define MIN_INTSET_ALLOC 8
#define INTSET_DATA_TYPE int
#define INTSET_DATA_FLAG "l"
typedef
struct
{
cPersistent_HEAD
int
size
,
len
;
INTSET_DATA_TYPE
*
data
;
}
intSet
;
staticforward
PyExtensionClass
intSetType
;
#define OBJECT(O) ((PyObject*)(O))
#define INTSET(O) ((intSet*)(O))
static
PyObject
*
_PER_RETURN
(
intSet
*
self
,
PyObject
*
r
)
{
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
static
int
_PER_INT_RETURN
(
intSet
*
self
,
int
r
)
{
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
/* We want to be sticky most of the time */
#define PER_RETURN(O,R) R
#define PER_INT_RETURN(O,R) R
#undef PER_ALLOW_DEACTIVATION
#define PER_ALLOW_DEACTIVATION(O)
static
PyObject
*
intSet_has_key
(
intSet
*
self
,
PyObject
*
args
)
{
int
min
,
max
,
i
,
l
;
INTSET_DATA_TYPE
k
,
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
INTSET_DATA_FLAG
,
&
key
))
return
NULL
;
PER_USE_OR_RETURN
(
self
,
NULL
);
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
,
l
=
max
;
i
!=
l
;
l
=
i
,
i
=
(
min
+
max
)
/
2
)
{
k
=
self
->
data
[
i
];
if
(
k
==
key
)
return
PER_RETURN
(
self
,
PyInt_FromLong
(
1
));
if
(
k
>
key
)
max
=
i
;
else
min
=
i
;
}
return
PER_RETURN
(
self
,
PyInt_FromLong
(
0
));
}
static
int
intSet_grow
(
intSet
*
self
,
int
l
)
{
int
g
;
INTSET_DATA_TYPE
*
data
;
if
(
self
->
data
)
{
g
=
self
->
size
*
2
;
if
(
g
<
l
)
g
=
l
;
UNLESS
(
data
=
realloc
(
self
->
data
,
sizeof
(
INTSET_DATA_TYPE
)
*
g
))
{
PyErr_NoMemory
();
return
-
1
;
}
self
->
data
=
data
;
self
->
size
=
g
;
}
else
{
g
=
l
<
MIN_INTSET_ALLOC
?
MIN_INTSET_ALLOC
:
l
;
UNLESS
(
self
->
data
=
malloc
(
sizeof
(
INTSET_DATA_TYPE
)
*
g
))
{
PyErr_NoMemory
();
return
-
1
;
}
self
->
size
=
g
;
}
return
0
;
}
static
INTSET_DATA_TYPE
intSet_modify
(
intSet
*
self
,
INTSET_DATA_TYPE
ikey
,
int
add
)
{
int
min
,
max
,
i
,
l
;
INTSET_DATA_TYPE
*
data
,
k
;
PER_USE_OR_RETURN
(
self
,
-
1
);
data
=
self
->
data
;
for
(
min
=
0
,
max
=
self
->
len
,
i
=
max
/
2
,
l
=
max
;
i
!=
l
;
l
=
i
,
i
=
(
min
+
max
)
/
2
)
{
k
=
data
[
i
];
if
(
k
==
ikey
)
{
if
(
!
add
)
{
data
+=
i
;
self
->
len
--
;
if
(
i
<
(
self
->
len
))
memmove
(
data
,
data
+
1
,
(
self
->
len
-
i
)
*
sizeof
(
INTSET_DATA_TYPE
));
if
(
PER_CHANGED
(
self
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
}
return
PER_INT_RETURN
(
self
,
0
);
}
if
(
k
>
ikey
)
max
=
i
;
else
min
=
i
;
}
if
(
!
add
)
return
PER_INT_RETURN
(
self
,
0
);
if
(
self
->
len
>=
self
->
size
&&
intSet_grow
(
self
,
self
->
len
+
1
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
if
(
max
!=
i
)
i
++
;
data
=
self
->
data
+
i
;
if
(
self
->
len
>
i
)
memmove
(
data
+
1
,
data
,(
self
->
len
-
i
)
*
sizeof
(
INTSET_DATA_TYPE
));
*
data
=
ikey
;
self
->
len
++
;
if
(
PER_CHANGED
(
self
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
return
PER_INT_RETURN
(
self
,
ikey
);
}
static
PyObject
*
intSet_insert
(
intSet
*
self
,
PyObject
*
args
)
{
INTSET_DATA_TYPE
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
INTSET_DATA_FLAG
,
&
key
))
return
NULL
;
if
(
intSet_modify
(
self
,
key
,
1
)
<
0
)
return
NULL
;
RETURN_NONE
;
}
static
PyObject
*
intSet_remove
(
intSet
*
self
,
PyObject
*
args
)
{
INTSET_DATA_TYPE
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
INTSET_DATA_FLAG
,
&
key
))
return
NULL
;
if
(
intSet_modify
(
self
,
key
,
0
)
<
0
)
return
NULL
;
RETURN_NONE
;
}
static
PyObject
*
intSet_clear
(
intSet
*
self
,
PyObject
*
args
)
{
self
->
len
=
0
;
if
(
PER_CHANGED
(
self
)
<
0
)
return
PER_RETURN
(
self
,
NULL
);
RETURN_NONE
;
}
static
PyObject
*
intSet___getstate__
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
r
=
0
;
int
i
,
l
;
char
*
c
;
INTSET_DATA_TYPE
*
d
;
PER_USE_OR_RETURN
(
self
,
NULL
);
l
=
self
->
len
;
UNLESS
(
r
=
PyString_FromStringAndSize
(
NULL
,
l
*
4
))
goto
err
;
UNLESS
(
c
=
PyString_AsString
(
r
))
goto
err
;
d
=
self
->
data
;
for
(
i
=
0
;
i
<
l
;
i
++
,
*
d
++
)
{
*
c
++
=
(
int
)(
*
d
&
0xff
);
*
c
++
=
(
int
)((
*
d
>>
8
)
&
0xff
);
*
c
++
=
(
int
)((
*
d
>>
16
)
&
0xff
);
*
c
++
=
(
int
)((
*
d
>>
24
)
&
0xff
);
}
return
PER_RETURN
(
self
,
r
);
err:
Py_DECREF
(
r
);
return
PER_RETURN
(
self
,
NULL
);
}
static
PyObject
*
intSet___setstate__
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
data
;
int
i
,
l
,
v
;
char
*
c
;
INTSET_DATA_TYPE
k
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
data
))
return
PER_RETURN
(
self
,
NULL
);
UNLESS
(
c
=
PyString_AsString
(
data
))
return
PER_RETURN
(
self
,
NULL
);
if
((
l
=
PyString_Size
(
data
))
<
0
)
return
PER_RETURN
(
self
,
NULL
);
l
/=
4
;
intSet_clear
(
self
,
NULL
);
if
(
l
>
self
->
size
&&
intSet_grow
(
self
,
l
)
<
0
)
return
PER_RETURN
(
self
,
NULL
);
PyErr_Clear
();
for
(
i
=
0
;
i
<
l
;
i
++
)
{
v
=
((
int
)(
unsigned
char
)
*
c
++
)
;
v
|=
((
int
)(
unsigned
char
)
*
c
++
)
<<
8
;
v
|=
((
int
)(
unsigned
char
)
*
c
++
)
<<
16
;
v
|=
((
int
)(
unsigned
char
)
*
c
++
)
<<
24
;
self
->
data
[
i
]
=
v
;
}
self
->
len
=
l
;
Py_INCREF
(
Py_None
);
return
PER_RETURN
(
self
,
Py_None
);
}
static
PyObject
*
intSet_set_operation
(
intSet
*
self
,
PyObject
*
other
,
int
cpysrc
,
int
cpyboth
,
int
cpyoth
)
{
intSet
*
r
=
0
,
*
o
;
int
i
,
l
,
io
,
lo
,
ir
;
INTSET_DATA_TYPE
*
d
,
*
od
,
v
,
vo
,
dif
;
if
(
other
->
ob_type
!=
self
->
ob_type
)
{
PyErr_SetString
(
PyExc_TypeError
,
"intSet set operations require same-type operands"
);
return
NULL
;
}
o
=
INTSET
(
other
);
PER_USE_OR_RETURN
(
self
,
NULL
);
PER_USE_OR_RETURN
((
intSet
*
)
other
,
NULL
);
od
=
o
->
data
;
d
=
self
->
data
;
UNLESS
(
r
=
INTSET
(
PyObject_CallObject
(
OBJECT
(
self
->
ob_type
),
NULL
)))
goto
err
;
for
(
i
=
0
,
l
=
self
->
len
,
io
=
0
,
lo
=
o
->
len
;
i
<
l
&&
io
<
lo
;
)
{
v
=
d
[
i
];
vo
=
od
[
io
];
if
(
v
<
vo
)
{
if
(
cpysrc
)
{
if
(
r
->
len
>=
r
->
size
&&
intSet_grow
(
r
,
0
)
<
0
)
goto
err
;
r
->
data
[
r
->
len
]
=
v
;
r
->
len
++
;
}
i
++
;
}
else
if
(
v
==
vo
)
{
if
(
cpyboth
)
{
if
(
r
->
len
>=
r
->
size
&&
intSet_grow
(
r
,
0
)
<
0
)
goto
err
;
r
->
data
[
r
->
len
]
=
v
;
r
->
len
++
;
}
i
++
;
io
++
;
}
else
{
if
(
cpyoth
)
{
if
(
r
->
len
>=
r
->
size
&&
intSet_grow
(
r
,
0
)
<
0
)
goto
err
;
r
->
data
[
r
->
len
]
=
vo
;
r
->
len
++
;
}
io
++
;
}
}
if
(
cpysrc
&&
i
<
l
)
{
l
-=
i
;
if
(
r
->
len
+
l
>
r
->
size
&&
intSet_grow
(
r
,
r
->
len
+
l
)
<
0
)
goto
err
;
memcpy
(
r
->
data
+
r
->
len
,
d
+
i
,
l
*
sizeof
(
INTSET_DATA_TYPE
));
r
->
len
+=
l
;
}
else
if
(
cpyoth
&&
io
<
lo
)
{
lo
-=
io
;
if
(
r
->
len
+
lo
>
r
->
size
&&
intSet_grow
(
r
,
r
->
len
+
lo
)
<
0
)
goto
err
;
memcpy
(
r
->
data
+
r
->
len
,
od
+
io
,
lo
*
sizeof
(
INTSET_DATA_TYPE
));
r
->
len
+=
lo
;
}
return
OBJECT
(
r
);
err:
PER_ALLOW_DEACTIVATION
(
self
);
PER_ALLOW_DEACTIVATION
(
o
);
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
intSet_add
(
intSet
*
self
,
PyObject
*
other
)
{
return
intSet_set_operation
(
self
,
other
,
1
,
1
,
1
);
}
static
PyObject
*
intSet_union
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
other
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
other
))
return
NULL
;
return
intSet_set_operation
(
self
,
other
,
1
,
1
,
1
);
}
static
PyObject
*
intSet_intersection
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
other
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
other
))
return
NULL
;
return
intSet_set_operation
(
self
,
other
,
0
,
1
,
0
);
}
static
PyObject
*
intSet_difference
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
other
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
other
))
return
NULL
;
return
intSet_set_operation
(
self
,
other
,
1
,
0
,
0
);
}
static
PyObject
*
intSet__p___reinit__
(
intSet
*
self
,
PyObject
*
args
)
{
PyObject
*
dict
;
if
(
self
->
state
==
cPersistent_UPTODATE_STATE
&&
HasInstDict
(
self
)
&&
(
dict
=
INSTANCE_DICT
(
self
)))
{
PyDict_Clear
(
dict
);
self
->
state
=
cPersistent_GHOST_STATE
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
struct
PyMethodDef
intSet_methods
[]
=
{
{
"has_key"
,
(
PyCFunction
)
intSet_has_key
,
METH_VARARGS
,
"has_key(id) -- Test whether the set has the given id"
},
{
"insert"
,
(
PyCFunction
)
intSet_insert
,
METH_VARARGS
,
"insert(id,[ignored]) -- Add an id to the set"
},
{
"remove"
,
(
PyCFunction
)
intSet_remove
,
METH_VARARGS
,
"remove(id) -- Remove an id from the set"
},
{
"clear"
,
(
PyCFunction
)
intSet_clear
,
METH_VARARGS
,
"clear() -- Remove all of the ids from the set"
},
{
"union"
,
(
PyCFunction
)
intSet_union
,
METH_VARARGS
,
"union(other) -- Return the union of the set with another set"
},
{
"intersection"
,
(
PyCFunction
)
intSet_intersection
,
METH_VARARGS
,
"intersection(other) -- "
"Return the intersection of the set with another set"
},
{
"difference"
,
(
PyCFunction
)
intSet_difference
,
METH_VARARGS
,
"difference(other) -- Return the difference of the set with another set"
},
{
"__getstate__"
,
(
PyCFunction
)
intSet___getstate__
,
METH_VARARGS
,
"__getstate__() -- get the persistent state"
},
{
"__setstate__"
,
(
PyCFunction
)
intSet___setstate__
,
METH_VARARGS
,
"__setstate__() -- set the persistent state"
},
{
"_p___reinit__"
,
(
PyCFunction
)
intSet__p___reinit__
,
METH_VARARGS
,
"_p___reinit__(oid,jar,copy) -- Reinitialize from a newly created copy"
},
{
"_p_deactivate"
,
(
PyCFunction
)
intSet__p___reinit__
,
METH_VARARGS
,
"_p_deactivate(oid,jar,copy) -- Reinitialize from a newly created copy"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
void
intSet_dealloc
(
intSet
*
self
)
{
free
(
self
->
data
);
PER_DEL
(
self
);
PyMem_DEL
(
self
);
}
static
PyObject
*
intSet_getattr
(
intSet
*
self
,
PyObject
*
name
)
{
return
Py_FindAttr
((
PyObject
*
)
self
,
name
);
}
/* Code to handle accessing intSet objects as sequence objects */
static
int
intSet_length
(
intSet
*
self
)
{
PER_USE_OR_RETURN
(
self
,
-
1
);
return
PER_INT_RETURN
(
self
,
self
->
len
);
}
static
PyObject
*
intSet_repeat
(
intSet
*
self
,
int
n
)
{
PyErr_SetString
(
PyExc_TypeError
,
"intSet objects do not support repetition"
);
return
NULL
;
}
static
PyObject
*
intSet_item
(
intSet
*
self
,
int
i
)
{
PyObject
*
e
;
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
i
>=
0
&&
i
<
self
->
len
)
return
PER_RETURN
(
self
,
PyInt_FromLong
(
self
->
data
[
i
]));
UNLESS
(
e
=
PyInt_FromLong
(
i
))
goto
err
;
PyErr_SetObject
(
PyExc_IndexError
,
e
);
Py_DECREF
(
e
);
err:
PER_ALLOW_DEACTIVATION
(
self
)
return
NULL
;
}
static
PyObject
*
intSet_slice
(
intSet
*
self
,
int
ilow
,
int
ihigh
)
{
PyErr_SetString
(
PyExc_TypeError
,
"intSet objects do not support slicing"
);
return
NULL
;
}
static
int
intSet_ass_item
(
intSet
*
self
,
int
i
,
PyObject
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"intSet objects do not support item assignment"
);
return
-
1
;
}
static
int
intSet_ass_slice
(
PyListObject
*
self
,
int
ilow
,
int
ihigh
,
PyObject
*
v
)
{
PyErr_SetString
(
PyExc_TypeError
,
"intSet objects do not support slice assignment"
);
return
-
1
;
}
static
PySequenceMethods
intSet_as_sequence
=
{
(
inquiry
)
intSet_length
,
/*sq_length*/
(
binaryfunc
)
intSet_add
,
/*sq_concat*/
(
intargfunc
)
intSet_repeat
,
/*sq_repeat*/
(
intargfunc
)
intSet_item
,
/*sq_item*/
(
intintargfunc
)
intSet_slice
,
/*sq_slice*/
(
intobjargproc
)
intSet_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
intSet_ass_slice
,
/*sq_ass_slice*/
};
static
PyExtensionClass
intSetType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"intSet"
,
/*tp_name*/
sizeof
(
intSet
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
intSet_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
&
intSet_as_sequence
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
intSet_getattr
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
"A set of integers"
,
METHOD_CHAIN
(
intSet_methods
),
EXTENSIONCLASS_BASICNEW_FLAG
,
};
static
struct
PyMethodDef
module_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
void
initintSet
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.10 $"
;
UNLESS
(
ExtensionClassImported
)
return
;
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
intSetType
.
methods
.
link
=
cPersistenceCAPI
->
methods
;
intSetType
.
tp_getattro
=
cPersistenceCAPI
->
getattro
;
intSetType
.
tp_setattro
=
cPersistenceCAPI
->
setattro
;
}
else
return
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"intSet"
,
module_methods
,
intSet_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"intSet"
,
intSetType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
#include "dcprotect.h"
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module intSet"
);
}
/**************************************************************************
Revision Log:
$Log: intSet.c,v $
Revision 1.10 1998/11/11 02:00:56 jim
alpha1
Revision 1.9 1998/03/24 15:17:34 jim
*** empty log message ***
Revision 1.8 1998/03/24 15:15:33 jim
Brought reinit/deactivate machinery up to date.
Revision 1.7 1998/02/18 22:19:39 jim
Fixed C inheritence problem. Waaaaaaa.
Revision 1.6 1997/12/12 23:48:07 jim
Added basicnew support.
Revision 1.5 1997/11/13 20:47:13 jim
Fixed some bad return values.
Revision 1.4 1997/11/13 20:38:39 jim
added dcprotect
Revision 1.3 1997/10/01 02:45:58 jim
Minor reformat.
Revision 1.2 1997/09/08 18:41:59 jim
Added logic to save data in binary form.
Revision 1.1 1997/08/05 14:55:22 jim
*** empty log message ***
**************************************************************************/
trunk/src/persistent/cPersistence.c
View file @
69c8c4a9
/***********************************************************************
/***********************************************************************
$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $
C Persistence Module
C Persistence Module
...
@@ -12,16 +12,19 @@
...
@@ -12,16 +12,19 @@
*****************************************************************************/
*****************************************************************************/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
5 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.2
6 1999/05/07 01:03:03
jim Exp $"
;
#include <
time
.h>
#include <
string
.h>
#include "cPersistence.h"
#include "cPersistence.h"
#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)
#define OBJECT(V) ((PyObject*)(V))
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
;
static
PyObject
*
py_keys
,
*
py_setstate
,
*
py___dict__
,
*
py_timeTime
;
static
PyObject
*
TimeStamp
;
#ifdef DEBUG_LOG
#ifdef DEBUG_LOG
static
PyObject
*
debug_log
=
0
;
static
PyObject
*
debug_log
=
0
;
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
...
@@ -35,8 +38,8 @@ call_debug(char *event, cPersistentObject *self)
/*
/*
printf("%s %p\n",event,self->ob_type->tp_name);
printf("%s %p\n",event,self->ob_type->tp_name);
*/
*/
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
s#
i)"
,
event
,
r
=
PyObject_CallFunction
(
debug_log
,
"s(s
O
i)"
,
event
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
8
,
self
->
ob_type
->
tp_name
,
self
->
oid
,
self
->
state
);
self
->
state
);
Py_XDECREF
(
r
);
Py_XDECREF
(
r
);
}
}
...
@@ -48,6 +51,7 @@ init_strings()
...
@@ -48,6 +51,7 @@ init_strings()
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
keys
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
setstate
);
INIT_STRING
(
timeTime
);
INIT_STRING
(
__dict__
);
INIT_STRING
(
__dict__
);
#undef INIT_STRING
#undef INIT_STRING
}
}
...
@@ -201,14 +205,16 @@ static PyObject *
...
@@ -201,14 +205,16 @@ static PyObject *
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
Per___changed__
(
cPersistentObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
v
=
0
;
PyObject
*
v
=
0
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
args
&&
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
v
))
return
NULL
;
if
(
v
&&
!
PyObject_IsTrue
(
v
))
if
(
!
v
)
return
PyObject_GetAttrString
(
OBJECT
(
self
),
"_p_changed"
);
if
(
PyObject_IsTrue
(
v
))
{
{
PyErr_SetString
(
PyExc_TypeError
,
if
(
changed
(
self
)
<
0
)
return
NULL
;
"Only true arguments are allowed."
);
return
NULL
;
}
}
if
(
changed
(
self
)
<
0
)
return
NULL
;
else
if
(
self
->
state
>=
0
)
self
->
state
=
cPersistent_UPTODATE_STATE
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
...
@@ -368,35 +374,30 @@ Per_dealloc(self)
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
static
PyObject
*
orNothing
(
PyObject
*
v
)
{
if
(
!
v
)
v
=
Py_None
;
Py_INCREF
(
v
);
return
v
;
}
static
PyObject
*
static
PyObject
*
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
Per_getattr
(
cPersistentObject
*
self
,
PyObject
*
oname
,
char
*
name
,
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
PyObject
*
(
*
getattrf
)(
PyObject
*
,
PyObject
*
))
{
{
char
*
n
=
name
;
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
n
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
{
switch
(
*
n
++
)
switch
(
*
n
++
)
{
{
case
'o'
:
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
return
orNothing
(
self
->
oid
);
return
PyString_FromStringAndSize
(
self
->
oid
,
8
);
break
;
break
;
case
'j'
:
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
return
orNothing
(
self
->
jar
);
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
break
;
case
'c'
:
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -410,11 +411,32 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
cPersistent_CHANGED_STATE
);
cPersistent_CHANGED_STATE
);
}
}
break
;
break
;
case
's'
:
if
(
strcmp
(
n
,
"erial"
)
==
0
)
return
PyString_FromStringAndSize
(
self
->
serial
,
8
);
break
;
case
'm'
:
if
(
strcmp
(
n
,
"time"
)
==
0
)
{
UPDATE_STATE_IF_NECESSARY
(
self
,
NULL
);
self
->
atime
=
((
long
)(
time
(
NULL
)
/
3
))
%
65536
;
oname
=
PyString_FromStringAndSize
(
self
->
serial
,
8
);
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallFunction
(
TimeStamp
,
"O"
,
oname
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_GetAttr
(
oname
,
py_timeTime
));
if
(
!
oname
)
return
oname
;
ASSIGN
(
oname
,
PyObject_CallObject
(
oname
,
NULL
));
return
oname
;
}
break
;
}
}
return
getattrf
((
PyObject
*
)
self
,
oname
);
return
getattrf
((
PyObject
*
)
self
,
oname
);
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
if
(
!
(
name
&&
*
name
++==
'_'
&&
*
name
++==
'_'
&&
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
(
strcmp
(
name
,
"dict__"
)
==
0
||
strcmp
(
name
,
"class__"
)
==
0
||
strcmp
(
name
,
"of__"
)
==
0
)))
||
strcmp
(
name
,
"of__"
)
==
0
)))
{
{
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
...
@@ -429,10 +451,11 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
static
PyObject
*
static
PyObject
*
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
Per_getattro
(
cPersistentObject
*
self
,
PyObject
*
name
)
{
{
char
*
s
;
char
*
s
=
NULL
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
if
(
PyString_Check
(
name
))
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
,
PyExtensionClassCAPI
->
getattro
);
}
}
static
int
static
int
...
@@ -456,27 +479,36 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
...
@@ -456,27 +479,36 @@ _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
(
!
v
)
return
bad_delattr
();
Py_XINCREF
(
v
);
if
(
PyString_Check
(
v
)
&&
PyString_GET_SIZE
(
v
)
==
8
)
ASSIGN
(
self
->
oid
,
v
);
memcpy
(
self
->
oid
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_AttributeError
,
"_p_oid must be an 8-character string"
);
return
-
1
;
}
return
0
;
return
0
;
}
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
{
Py_XINCREF
(
v
);
ASSIGN
(
self
->
jar
,
v
);
ASSIGN
(
self
->
jar
,
v
);
Py_XINCREF
(
self
->
jar
);
return
0
;
return
0
;
}
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
if
(
name
[
3
]
==
's'
&&
strcmp
(
name
+
4
,
"erial"
)
==
0
)
{
{
if
(
!
v
)
return
bad_delattr
();
if
(
v
)
if
(
v
==
Py_None
)
{
if
(
PyString_Check
(
v
)
&&
PyString_Size
(
v
)
==
8
)
memcpy
(
self
->
serial
,
PyString_AS_STRING
(
v
),
8
);
else
{
PyErr_SetString
(
PyExc_ValueError
,
"_p_serial must be an 8-character string"
);
return
-
1
;
}
}
else
memset
(
self
->
serial
,
0
,
8
);
return
0
;
}
if
(
name
[
3
]
==
'c'
&&
strcmp
(
name
+
4
,
"hanged"
)
==
0
)
{
if
(
!
v
||
v
==
Py_None
)
{
{
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
if
(
Per__p_deactivate
(
self
,
NULL
))
Py_DECREF
(
Py_None
);
return
0
;
return
0
;
...
@@ -585,8 +617,15 @@ void
...
@@ -585,8 +617,15 @@ void
initcPersistence
()
initcPersistence
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.25 $"
;
char
*
rev
=
"$Revision: 1.26 $"
;
TimeStamp
=
PyString_FromString
(
"TimeStamp"
);
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyImport_Import
(
TimeStamp
));
if
(
!
TimeStamp
)
return
;
ASSIGN
(
TimeStamp
,
PyObject_GetAttrString
(
TimeStamp
,
"TimeStamp"
));
if
(
!
TimeStamp
)
return
;
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
""
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/persistent/cPersistence.h
View file @
69c8c4a9
/*
/*
$Id: cPersistence.h,v 1.1
0 1998/11/11 02:00:56
jim Exp $
$Id: cPersistence.h,v 1.1
1 1999/05/07 01:03:03
jim Exp $
Definitions to facilitate making cPersistent subclasses in C.
Definitions to facilitate making cPersistent subclasses in C.
...
@@ -15,9 +15,11 @@
...
@@ -15,9 +15,11 @@
#define cPersistent_HEAD PyObject_HEAD \
#define cPersistent_HEAD PyObject_HEAD \
PyObject *jar; \
PyObject *jar; \
char oid[8]; \
PyObject *oid; \
char serial[8]; \
unsigned short atime; \
unsigned short atime; \
signed char state; \
signed char state; \
unsigned char reserved; \
#define cPersistent_GHOST_STATE -1
#define cPersistent_GHOST_STATE -1
#define cPersistent_UPTODATE_STATE 0
#define cPersistent_UPTODATE_STATE 0
...
@@ -43,6 +45,8 @@ typedef struct {
...
@@ -43,6 +45,8 @@ typedef struct {
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
static
cPersistenceCAPIstruct
*
cPersistenceCAPI
;
#define cPersistanceModuleName "cPersistence"
#define PER_USE_OR_RETURN(O,R) { \
#define PER_USE_OR_RETURN(O,R) { \
if ((O)->state==cPersistent_GHOST_STATE && \
if ((O)->state==cPersistent_GHOST_STATE && \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
cPersistenceCAPI->setstate((PyObject*)(O)) < 0) \
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
...
@@ -57,6 +61,10 @@ static cPersistenceCAPIstruct *cPersistenceCAPI;
((O)->state==cPersistent_STICKY_STATE && \
((O)->state==cPersistent_STICKY_STATE && \
((O)->state=cPersistent_UPTODATE_STATE))
((O)->state=cPersistent_UPTODATE_STATE))
#define PER_PREVENT_DEACTIVATION(O) \
((O)->state==cPersistent_UPTODATE_STATE && \
((O)->state=cPersistent_STICKY_STATE))
#define PER_DEL(O) Py_XDECREF((O)->jar)
#define PER_DEL(O) Py_XDECREF((O)->jar)
#endif
#endif
...
...
trunk/src/persistent/cPickleCache.c
View file @
69c8c4a9
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
6 1998/11/11 02:00:56
jim Exp $"
;
static
char
*
what_string
=
"$Id: cPickleCache.c,v 1.1
7 1999/05/07 01:03:03
jim Exp $"
;
#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))
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
...
@@ -12,12 +12,10 @@ static char *what_string = "$Id: cPickleCache.c,v 1.16 1998/11/11 02:00:56 jim E
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
static
PyObject
*
py_reload
,
*
py__p_jar
,
*
py__p_deactivate
;
/* Declarations for objects of type cCache */
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
PyObject
*
data
;
PyObject
*
data
;
PyObject
*
jar
;
int
position
;
int
position
;
int
cache_size
;
int
cache_size
;
int
cache_age
;
int
cache_age
;
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
...
@@ -65,8 +63,11 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
if
(
dt
&&
v
->
ob_type
->
tp_basicsize
>=
sizeof
(
cPersistentObject
)
&&
if
(
dt
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
(
!
PyExtensionClass_Check
(
v
))
&&
((
cPersistentObject
*
)
v
)
->
jar
==
self
->
jar
/* I'm paranoid */
&&
((
cPersistentObject
*
)
v
)
->
state
==
cPersistent_UPTODATE_STATE
)
{
{
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
now
-=
((
cPersistentObject
*
)
v
)
->
atime
;
if
(
now
<
0
)
now
+=
65536
;
if
(
now
<
0
)
now
+=
65536
;
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
...
@@ -281,13 +282,15 @@ static struct PyMethodDef cc_methods[] = {
};
};
static
ccobject
*
static
ccobject
*
newccobject
(
int
cache_size
,
int
cache_age
)
newccobject
(
PyObject
*
jar
,
int
cache_size
,
int
cache_age
)
{
{
ccobject
*
self
;
ccobject
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
UNLESS
(
self
=
PyObject_NEW
(
ccobject
,
&
Cctype
))
return
NULL
;
if
(
self
->
data
=
PyDict_New
())
if
(
self
->
data
=
PyDict_New
())
{
{
self
->
jar
=
jar
;
Py_INCREF
(
jar
);
self
->
position
=
0
;
self
->
position
=
0
;
self
->
cache_size
=
cache_size
;
self
->
cache_size
=
cache_size
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
self
->
cache_age
=
cache_age
<
1
?
1
:
cache_age
;
...
@@ -312,6 +315,7 @@ static void
...
@@ -312,6 +315,7 @@ static void
cc_dealloc
(
ccobject
*
self
)
cc_dealloc
(
ccobject
*
self
)
{
{
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
jar
);
PyMem_DEL
(
self
);
PyMem_DEL
(
self
);
}
}
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
...
@@ -404,10 +408,24 @@ cc_subscript(ccobject *self, PyObject *key)
return
r
;
return
r
;
}
}
static
PyExtensionClass
*
Persistent
=
0
;
static
int
static
int
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
cc_ass_sub
(
ccobject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
{
if
(
v
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
if
(
v
)
{
if
(
PyExtensionClass_Check
(
v
)
||
(
PyExtensionInstance_Check
(
v
)
&&
ExtensionClassSubclassInstance_Check
(
v
,
Persistent
)
)
)
return
PyDict_SetItem
(
self
->
data
,
key
,
v
);
PyErr_SetString
(
PyExc_ValueError
,
"Cache values must be persistent objects or classes."
);
return
-
1
;
}
return
PyDict_DelItem
(
self
->
data
,
key
);
return
PyDict_DelItem
(
self
->
data
,
key
);
}
}
...
@@ -446,8 +464,10 @@ static PyObject *
...
@@ -446,8 +464,10 @@ static PyObject *
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
cCM_new
(
PyObject
*
self
,
PyObject
*
args
)
{
{
int
cache_size
=
100
,
cache_age
=
1000
;
int
cache_size
=
100
,
cache_age
=
1000
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"|ii"
,
&
cache_size
,
&
cache_age
))
return
NULL
;
PyObject
*
jar
;
return
(
PyObject
*
)
newccobject
(
cache_size
,
cache_age
);
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|ii"
,
&
jar
,
&
cache_size
,
&
cache_age
))
return
NULL
;
return
(
PyObject
*
)
newccobject
(
jar
,
cache_size
,
cache_age
);
}
}
static
struct
PyMethodDef
cCM_methods
[]
=
{
static
struct
PyMethodDef
cCM_methods
[]
=
{
...
@@ -459,10 +479,20 @@ void
...
@@ -459,10 +479,20 @@ void
initcPickleCache
()
initcPickleCache
()
{
{
PyObject
*
m
,
*
d
;
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.1
6
$"
;
char
*
rev
=
"$Revision: 1.1
7
$"
;
Cctype
.
ob_type
=&
PyType_Type
;
Cctype
.
ob_type
=&
PyType_Type
;
UNLESS
(
ExtensionClassImported
)
return
;
/* Get the Persistent base class */
UNLESS
(
m
=
PyString_FromString
(
cPersistanceModuleName
))
return
;
ASSIGN
(
m
,
PyImport_Import
(
m
));
UNLESS
(
m
)
return
;
ASSIGN
(
m
,
PyObject_GetAttrString
(
m
,
"Persistent"
));
UNLESS
(
m
)
return
;
Persistent
=
(
PyExtensionClass
*
)
m
;
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
m
=
Py_InitModule4
(
"cPickleCache"
,
cCM_methods
,
""
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
...
...
trunk/src/persistent/mapping.py
View file @
69c8c4a9
...
@@ -48,12 +48,12 @@
...
@@ -48,12 +48,12 @@
__doc__
=
'''Python implementation of persistent base types
__doc__
=
'''Python implementation of persistent base types
$Id: mapping.py,v 1.
3 1998/11/11 02:00:56
jim Exp $'''
$Id: mapping.py,v 1.
4 1999/05/07 01:03:03
jim Exp $'''
__version__
=
'$Revision: 1.
3
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
4
$'
[
11
:
-
2
]
import
Persistence
import
Persistence
class
P
M
(
Persistence
.
Persistent
):
class
P
ersistentMapping
(
Persistence
.
Persistent
):
"""A persistent wrapper for mapping objects.
"""A persistent wrapper for mapping objects.
This class allows wrapping of mapping objects so that
This class allows wrapping of mapping objects so that
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
...
@@ -113,4 +113,3 @@ class PM(Persistence.Persistent):
def
values
(
self
):
def
values
(
self
):
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
return
map
(
lambda
k
,
d
=
self
:
d
[
k
],
self
.
keys
())
PersistentMapping
=
PM
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