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
55ed9237
Commit
55ed9237
authored
May 07, 2011
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated indentation.
parent
b3c584b7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
905 additions
and
905 deletions
+905
-905
src/BTrees/BucketTemplate.c
src/BTrees/BucketTemplate.c
+905
-905
No files found.
src/BTrees/BucketTemplate.c
View file @
55ed9237
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
FOR A PARTICULAR PURPOSE
****************************************************************************/
****************************************************************************/
#define BUCKETTEMPLATE_C "$Id$\n"
#define BUCKETTEMPLATE_C "$Id$\n"
...
@@ -38,15 +38,15 @@
...
@@ -38,15 +38,15 @@
int _i; \
int _i; \
int _cmp = 1; \
int _cmp = 1; \
for (_i = _hi >> 1; _lo < _hi; _i = (_lo + _hi) >> 1) { \
for (_i = _hi >> 1; _lo < _hi; _i = (_lo + _hi) >> 1) { \
TEST_KEY_SET_OR(_cmp, (SELF)->keys[_i], (KEY))
\
TEST_KEY_SET_OR(_cmp, (SELF)->keys[_i], (KEY))
\
ONERROR;
\
ONERROR;
\
if (_cmp < 0) _lo = _i + 1;
\
if (_cmp < 0) _lo = _i + 1;
\
else if (_cmp == 0) break;
\
else if (_cmp == 0) break;
\
else _hi = _i;
\
else _hi = _i;
\
} \
} \
(INDEX) = _i; \
(INDEX) = _i; \
(ABSENT) = _cmp; \
(ABSENT) = _cmp; \
}
}
/*
/*
** _bucket_get
** _bucket_get
...
@@ -75,30 +75,30 @@
...
@@ -75,30 +75,30 @@
static
PyObject
*
static
PyObject
*
_bucket_get
(
Bucket
*
self
,
PyObject
*
keyarg
,
int
has_key
)
_bucket_get
(
Bucket
*
self
,
PyObject
*
keyarg
,
int
has_key
)
{
{
int
i
,
cmp
;
int
i
,
cmp
;
KEY_TYPE
key
;
KEY_TYPE
key
;
PyObject
*
r
=
NULL
;
PyObject
*
r
=
NULL
;
int
copied
=
1
;
int
copied
=
1
;
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
UNLESS
(
copied
)
return
NULL
;
UNLESS
(
copied
)
return
NULL
;
UNLESS
(
PER_USE
(
self
))
return
NULL
;
UNLESS
(
PER_USE
(
self
))
return
NULL
;
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
if
(
has_key
)
if
(
has_key
)
r
=
PyInt_FromLong
(
cmp
?
0
:
has_key
);
r
=
PyInt_FromLong
(
cmp
?
0
:
has_key
);
else
{
else
{
if
(
cmp
==
0
)
{
if
(
cmp
==
0
)
{
COPY_VALUE_TO_OBJECT
(
r
,
self
->
values
[
i
]);
COPY_VALUE_TO_OBJECT
(
r
,
self
->
values
[
i
]);
}
else
PyErr_SetObject
(
PyExc_KeyError
,
keyarg
);
}
}
else
PyErr_SetObject
(
PyExc_KeyError
,
keyarg
);
}
Done:
Done:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
r
;
return
r
;
}
}
...
@@ -126,45 +126,45 @@ bucket_getitem(Bucket *self, PyObject *key)
...
@@ -126,45 +126,45 @@ bucket_getitem(Bucket *self, PyObject *key)
static
int
static
int
Bucket_grow
(
Bucket
*
self
,
int
newsize
,
int
noval
)
Bucket_grow
(
Bucket
*
self
,
int
newsize
,
int
noval
)
{
{
KEY_TYPE
*
keys
;
KEY_TYPE
*
keys
;
VALUE_TYPE
*
values
;
VALUE_TYPE
*
values
;
if
(
self
->
size
)
{
if
(
self
->
size
)
{
if
(
newsize
<
0
)
if
(
newsize
<
0
)
newsize
=
self
->
size
*
2
;
newsize
=
self
->
size
*
2
;
if
(
newsize
<
0
)
/* int overflow */
if
(
newsize
<
0
)
/* int overflow */
goto
Overflow
;
goto
Overflow
;
UNLESS
(
keys
=
BTree_Realloc
(
self
->
keys
,
sizeof
(
KEY_TYPE
)
*
newsize
))
UNLESS
(
keys
=
BTree_Realloc
(
self
->
keys
,
sizeof
(
KEY_TYPE
)
*
newsize
))
return
-
1
;
return
-
1
;
UNLESS
(
noval
)
{
UNLESS
(
noval
)
{
values
=
BTree_Realloc
(
self
->
values
,
sizeof
(
VALUE_TYPE
)
*
newsize
);
values
=
BTree_Realloc
(
self
->
values
,
sizeof
(
VALUE_TYPE
)
*
newsize
);
if
(
values
==
NULL
)
{
if
(
values
==
NULL
)
{
free
(
keys
);
free
(
keys
);
return
-
1
;
return
-
1
;
}
}
self
->
values
=
values
;
self
->
values
=
values
;
}
self
->
keys
=
keys
;
}
}
else
{
self
->
keys
=
keys
;
if
(
newsize
<
0
)
}
newsize
=
MIN_BUCKET_ALLOC
;
else
{
UNLESS
(
self
->
keys
=
BTree_Malloc
(
sizeof
(
KEY_TYPE
)
*
newsize
))
if
(
newsize
<
0
)
return
-
1
;
newsize
=
MIN_BUCKET_ALLOC
;
UNLESS
(
noval
)
{
UNLESS
(
self
->
keys
=
BTree_Malloc
(
sizeof
(
KEY_TYPE
)
*
newsize
))
self
->
values
=
BTree_Malloc
(
sizeof
(
VALUE_TYPE
)
*
newsize
);
return
-
1
;
if
(
self
->
values
==
NULL
)
{
UNLESS
(
noval
)
{
free
(
self
->
keys
);
self
->
values
=
BTree_Malloc
(
sizeof
(
VALUE_TYPE
)
*
newsize
);
self
->
keys
=
NULL
;
if
(
self
->
values
==
NULL
)
{
return
-
1
;
free
(
self
->
keys
);
}
self
->
keys
=
NULL
;
}
return
-
1
;
}
}
}
self
->
size
=
newsize
;
}
return
0
;
self
->
size
=
newsize
;
return
0
;
Overflow:
Overflow:
PyErr_NoMemory
();
PyErr_NoMemory
();
return
-
1
;
return
-
1
;
}
}
...
@@ -213,54 +213,54 @@ static int
...
@@ -213,54 +213,54 @@ static int
bucket_append
(
Bucket
*
self
,
Bucket
*
from
,
int
i
,
int
n
,
bucket_append
(
Bucket
*
self
,
Bucket
*
from
,
int
i
,
int
n
,
int
copyValues
,
int
overallocate
)
int
copyValues
,
int
overallocate
)
{
{
int
newlen
;
int
newlen
;
assert
(
self
&&
from
&&
self
!=
from
);
assert
(
self
&&
from
&&
self
!=
from
);
assert
(
i
>=
0
);
assert
(
i
>=
0
);
assert
(
n
>
0
);
assert
(
n
>
0
);
assert
(
i
+
n
<=
from
->
len
);
assert
(
i
+
n
<=
from
->
len
);
/* Make room. */
/* Make room. */
newlen
=
self
->
len
+
n
;
newlen
=
self
->
len
+
n
;
if
(
newlen
>
self
->
size
)
{
if
(
newlen
>
self
->
size
)
{
int
newsize
=
newlen
;
int
newsize
=
newlen
;
if
(
overallocate
)
/* boost by 25% -- pretty arbitrary */
if
(
overallocate
)
/* boost by 25% -- pretty arbitrary */
newsize
+=
newsize
>>
2
;
newsize
+=
newsize
>>
2
;
if
(
Bucket_grow
(
self
,
newsize
,
!
copyValues
)
<
0
)
if
(
Bucket_grow
(
self
,
newsize
,
!
copyValues
)
<
0
)
return
-
1
;
return
-
1
;
}
}
assert
(
newlen
<=
self
->
size
);
assert
(
newlen
<=
self
->
size
);
/* Copy stuff. */
/* Copy stuff. */
memcpy
(
self
->
keys
+
self
->
len
,
from
->
keys
+
i
,
n
*
sizeof
(
KEY_TYPE
));
memcpy
(
self
->
keys
+
self
->
len
,
from
->
keys
+
i
,
n
*
sizeof
(
KEY_TYPE
));
if
(
copyValues
)
{
if
(
copyValues
)
{
assert
(
self
->
values
);
assert
(
self
->
values
);
assert
(
from
->
values
);
assert
(
from
->
values
);
memcpy
(
self
->
values
+
self
->
len
,
from
->
values
+
i
,
memcpy
(
self
->
values
+
self
->
len
,
from
->
values
+
i
,
n
*
sizeof
(
VALUE_TYPE
));
n
*
sizeof
(
VALUE_TYPE
));
}
}
self
->
len
=
newlen
;
self
->
len
=
newlen
;
/* Bump refcounts. */
/* Bump refcounts. */
#ifdef KEY_TYPE_IS_PYOBJECT
#ifdef KEY_TYPE_IS_PYOBJECT
{
{
int
j
;
int
j
;
PyObject
**
p
=
from
->
keys
+
i
;
PyObject
**
p
=
from
->
keys
+
i
;
for
(
j
=
0
;
j
<
n
;
++
j
,
++
p
)
{
for
(
j
=
0
;
j
<
n
;
++
j
,
++
p
)
{
Py_INCREF
(
*
p
);
Py_INCREF
(
*
p
);
}
}
}
}
#endif
#endif
#ifdef VALUE_TYPE_IS_PYOBJECT
#ifdef VALUE_TYPE_IS_PYOBJECT
if
(
copyValues
)
{
if
(
copyValues
)
{
int
j
;
int
j
;
PyObject
**
p
=
from
->
values
+
i
;
PyObject
**
p
=
from
->
values
+
i
;
for
(
j
=
0
;
j
<
n
;
++
j
,
++
p
)
{
for
(
j
=
0
;
j
<
n
;
++
j
,
++
p
)
{
Py_INCREF
(
*
p
);
Py_INCREF
(
*
p
);
}
}
}
}
#endif
#endif
return
0
;
return
0
;
}
}
#endif
/* MULTI_INT_UNION */
#endif
/* MULTI_INT_UNION */
...
@@ -291,136 +291,136 @@ static int
...
@@ -291,136 +291,136 @@ static int
_bucket_set
(
Bucket
*
self
,
PyObject
*
keyarg
,
PyObject
*
v
,
_bucket_set
(
Bucket
*
self
,
PyObject
*
keyarg
,
PyObject
*
v
,
int
unique
,
int
noval
,
int
*
changed
)
int
unique
,
int
noval
,
int
*
changed
)
{
{
int
i
,
cmp
;
int
i
,
cmp
;
KEY_TYPE
key
;
KEY_TYPE
key
;
/* Subtle: there may or may not be a value. If there is, we need to
/* Subtle: there may or may not be a value. If there is, we need to
* check its type early, so that in case of error we can get out before
* check its type early, so that in case of error we can get out before
* mutating the bucket. But because value isn't used on all paths, if
* mutating the bucket. But because value isn't used on all paths, if
* we don't initialize value then gcc gives a nuisance complaint that
* we don't initialize value then gcc gives a nuisance complaint that
* value may be used initialized (it can't be, but gcc doesn't know
* value may be used initialized (it can't be, but gcc doesn't know
* that). So we initialize it. However, VALUE_TYPE can be various types,
* that). So we initialize it. However, VALUE_TYPE can be various types,
* including int, PyObject*, and char[6], so it's a puzzle to spell
* including int, PyObject*, and char[6], so it's a puzzle to spell
* initialization. It so happens that {0} is a valid initializer for all
* initialization. It so happens that {0} is a valid initializer for all
* these types.
* these types.
*/
*/
VALUE_TYPE
value
=
{
0
};
/* squash nuisance warning */
VALUE_TYPE
value
=
{
0
};
/* squash nuisance warning */
int
result
=
-
1
;
/* until proven innocent */
int
result
=
-
1
;
/* until proven innocent */
int
copied
=
1
;
int
copied
=
1
;
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
UNLESS
(
copied
)
return
-
1
;
/* Copy the value early (if needed), so that in case of error a
* pile of bucket mutations don't need to be undone.
*/
if
(
v
&&
!
noval
)
{
COPY_VALUE_FROM_ARG
(
value
,
v
,
copied
);
UNLESS
(
copied
)
return
-
1
;
UNLESS
(
copied
)
return
-
1
;
}
/* Copy the value early (if needed), so that in case of error a
UNLESS
(
PER_USE
(
self
))
return
-
1
;
* pile of bucket mutations don't need to be undone.
*/
if
(
v
&&
!
noval
)
{
COPY_VALUE_FROM_ARG
(
value
,
v
,
copied
);
UNLESS
(
copied
)
return
-
1
;
}
UNLESS
(
PER_USE
(
self
))
return
-
1
;
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
if
(
cmp
==
0
)
{
/* The key exists, at index i. */
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
if
(
v
)
{
if
(
cmp
==
0
)
{
/* The key exists at index i, and there's a new value.
/* The key exists, at index i. */
* If unique, we're not supposed to replace it. If noval, or this
* is a set bucket (self->values is NULL), there's nothing to do.
if
(
v
)
{
*/
/* The key exists at index i, and there's a new value.
if
(
unique
||
noval
||
self
->
values
==
NULL
)
{
* If unique, we're not supposed to replace it. If noval, or this
result
=
0
;
* is a set bucket (self->values is NULL), there's nothing to do.
goto
Done
;
*/
}
if
(
unique
||
noval
||
self
->
values
==
NULL
)
{
result
=
0
;
/* The key exists at index i, and we need to replace the value. */
goto
Done
;
}
/* The key exists at index i, and we need to replace the value. */
#ifdef VALUE_SAME
#ifdef VALUE_SAME
/* short-circuit if no change */
/* short-circuit if no change */
if
(
VALUE_SAME
(
self
->
values
[
i
],
value
))
{
if
(
VALUE_SAME
(
self
->
values
[
i
],
value
))
{
result
=
0
;
result
=
0
;
goto
Done
;
goto
Done
;
}
}
#endif
#endif
if
(
changed
)
if
(
changed
)
*
changed
=
1
;
*
changed
=
1
;
DECREF_VALUE
(
self
->
values
[
i
]);
DECREF_VALUE
(
self
->
values
[
i
]);
COPY_VALUE
(
self
->
values
[
i
],
value
);
COPY_VALUE
(
self
->
values
[
i
],
value
);
INCREF_VALUE
(
self
->
values
[
i
]);
INCREF_VALUE
(
self
->
values
[
i
]);
if
(
PER_CHANGED
(
self
)
>=
0
)
if
(
PER_CHANGED
(
self
)
>=
0
)
result
=
0
;
result
=
0
;
goto
Done
;
goto
Done
;
}
}
/* The key exists at index i, and should be deleted. */
DECREF_KEY
(
self
->
keys
[
i
]);
self
->
len
--
;
if
(
i
<
self
->
len
)
memmove
(
self
->
keys
+
i
,
self
->
keys
+
i
+
1
,
sizeof
(
KEY_TYPE
)
*
(
self
->
len
-
i
));
if
(
self
->
values
)
{
DECREF_VALUE
(
self
->
values
[
i
]);
if
(
i
<
self
->
len
)
memmove
(
self
->
values
+
i
,
self
->
values
+
i
+
1
,
sizeof
(
VALUE_TYPE
)
*
(
self
->
len
-
i
));
}
if
(
!
self
->
len
)
{
/* The key exists at index i, and should be deleted. */
self
->
size
=
0
;
DECREF_KEY
(
self
->
keys
[
i
]);
free
(
self
->
keys
);
self
->
len
--
;
self
->
keys
=
NULL
;
if
(
i
<
self
->
len
)
if
(
self
->
values
)
{
memmove
(
self
->
keys
+
i
,
self
->
keys
+
i
+
1
,
free
(
self
->
values
);
sizeof
(
KEY_TYPE
)
*
(
self
->
len
-
i
));
self
->
values
=
NULL
;
}
}
if
(
changed
)
if
(
self
->
values
)
{
*
changed
=
1
;
DECREF_VALUE
(
self
->
values
[
i
])
;
if
(
PER_CHANGED
(
self
)
>=
0
)
if
(
i
<
self
->
len
)
result
=
1
;
memmove
(
self
->
values
+
i
,
self
->
values
+
i
+
1
,
goto
Done
;
sizeof
(
VALUE_TYPE
)
*
(
self
->
len
-
i
))
;
}
}
/* The key doesn't exist, and belongs at index i. */
if
(
!
self
->
len
)
{
if
(
!
v
)
{
self
->
size
=
0
;
/* Can't delete a non-existent key. */
free
(
self
->
keys
);
PyErr_SetObject
(
PyExc_KeyError
,
keyarg
);
self
->
keys
=
NULL
;
goto
Done
;
if
(
self
->
values
)
{
free
(
self
->
values
);
self
->
values
=
NULL
;
}
}
}
/* The key doesn't exist and should be inserted at index i. */
if
(
changed
)
if
(
self
->
len
==
self
->
size
&&
Bucket_grow
(
self
,
-
1
,
noval
)
<
0
)
*
changed
=
1
;
goto
Done
;
if
(
PER_CHANGED
(
self
)
>=
0
)
result
=
1
;
goto
Done
;
}
if
(
self
->
len
>
i
)
{
/* The key doesn't exist, and belongs at index i. */
memmove
(
self
->
keys
+
i
+
1
,
self
->
keys
+
i
,
if
(
!
v
)
{
sizeof
(
KEY_TYPE
)
*
(
self
->
len
-
i
));
/* Can't delete a non-existent key. */
if
(
self
->
values
)
{
PyErr_SetObject
(
PyExc_KeyError
,
keyarg
);
memmove
(
self
->
values
+
i
+
1
,
self
->
values
+
i
,
goto
Done
;
sizeof
(
VALUE_TYPE
)
*
(
self
->
len
-
i
));
}
}
}
COPY_KEY
(
self
->
keys
[
i
],
key
);
/* The key doesn't exist and should be inserted at index i. */
INCREF_KEY
(
self
->
keys
[
i
]);
if
(
self
->
len
==
self
->
size
&&
Bucket_grow
(
self
,
-
1
,
noval
)
<
0
)
goto
Done
;
if
(
!
noval
)
{
if
(
self
->
len
>
i
)
{
COPY_VALUE
(
self
->
values
[
i
],
value
);
memmove
(
self
->
keys
+
i
+
1
,
self
->
keys
+
i
,
INCREF_VALUE
(
self
->
values
[
i
]);
sizeof
(
KEY_TYPE
)
*
(
self
->
len
-
i
));
if
(
self
->
values
)
{
memmove
(
self
->
values
+
i
+
1
,
self
->
values
+
i
,
sizeof
(
VALUE_TYPE
)
*
(
self
->
len
-
i
));
}
}
}
self
->
len
++
;
COPY_KEY
(
self
->
keys
[
i
],
key
);
if
(
changed
)
INCREF_KEY
(
self
->
keys
[
i
]);
*
changed
=
1
;
if
(
PER_CHANGED
(
self
)
>=
0
)
if
(
!
noval
)
{
result
=
1
;
COPY_VALUE
(
self
->
values
[
i
],
value
);
INCREF_VALUE
(
self
->
values
[
i
]);
}
Done:
self
->
len
++
;
PER_UNUSE
(
self
);
if
(
changed
)
return
result
;
*
changed
=
1
;
if
(
PER_CHANGED
(
self
)
>=
0
)
result
=
1
;
Done:
PER_UNUSE
(
self
);
return
result
;
}
}
/*
/*
...
@@ -438,9 +438,9 @@ Done:
...
@@ -438,9 +438,9 @@ Done:
static
int
static
int
bucket_setitem
(
Bucket
*
self
,
PyObject
*
key
,
PyObject
*
v
)
bucket_setitem
(
Bucket
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
{
if
(
_bucket_set
(
self
,
key
,
v
,
0
,
0
,
0
)
<
0
)
if
(
_bucket_set
(
self
,
key
,
v
,
0
,
0
,
0
)
<
0
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
}
}
/**
/**
...
@@ -450,71 +450,71 @@ bucket_setitem(Bucket *self, PyObject *key, PyObject *v)
...
@@ -450,71 +450,71 @@ bucket_setitem(Bucket *self, PyObject *key, PyObject *v)
static
int
static
int
update_from_seq
(
PyObject
*
map
,
PyObject
*
seq
)
update_from_seq
(
PyObject
*
map
,
PyObject
*
seq
)
{
{
PyObject
*
iter
,
*
o
,
*
k
,
*
v
;
PyObject
*
iter
,
*
o
,
*
k
,
*
v
;
int
err
=
-
1
;
int
err
=
-
1
;
/* One path creates a new seq object. The other path has an
/* One path creates a new seq object. The other path has an
INCREF of the seq argument. So seq must always be DECREFed on
INCREF of the seq argument. So seq must always be DECREFed on
the way out.
the way out.
*/
*/
/* Use items() if it's not a sequence. Alas, PySequence_Check()
/* Use items() if it's not a sequence. Alas, PySequence_Check()
* returns true for a PeristentMapping or PersistentDict, and we
* returns true for a PeristentMapping or PersistentDict, and we
* want to use items() in those cases too.
* want to use items() in those cases too.
*/
*/
if
(
!
PySequence_Check
(
seq
)
||
/* or it "looks like a dict" */
if
(
!
PySequence_Check
(
seq
)
||
/* or it "looks like a dict" */
PyObject_HasAttrString
(
seq
,
"iteritems"
))
{
PyObject_HasAttrString
(
seq
,
"iteritems"
))
{
PyObject
*
items
;
PyObject
*
items
;
items
=
PyObject_GetAttrString
(
seq
,
"items"
);
items
=
PyObject_GetAttrString
(
seq
,
"items"
);
if
(
items
==
NULL
)
if
(
items
==
NULL
)
return
-
1
;
return
-
1
;
seq
=
PyObject_CallObject
(
items
,
NULL
);
seq
=
PyObject_CallObject
(
items
,
NULL
);
Py_DECREF
(
items
);
Py_DECREF
(
items
);
if
(
seq
==
NULL
)
if
(
seq
==
NULL
)
return
-
1
;
return
-
1
;
}
}
else
else
Py_INCREF
(
seq
);
Py_INCREF
(
seq
);
iter
=
PyObject_GetIter
(
seq
);
iter
=
PyObject_GetIter
(
seq
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
goto
err
;
goto
err
;
while
(
1
)
{
while
(
1
)
{
o
=
PyIter_Next
(
iter
);
o
=
PyIter_Next
(
iter
);
if
(
o
==
NULL
)
{
if
(
o
==
NULL
)
{
if
(
PyErr_Occurred
())
if
(
PyErr_Occurred
())
goto
err
;
goto
err
;
else
else
break
;
break
;
}
}
if
(
!
PyTuple_Check
(
o
)
||
PyTuple_GET_SIZE
(
o
)
!=
2
)
{
if
(
!
PyTuple_Check
(
o
)
||
PyTuple_GET_SIZE
(
o
)
!=
2
)
{
Py_DECREF
(
o
);
Py_DECREF
(
o
);
PyErr_SetString
(
PyExc_TypeError
,
PyErr_SetString
(
PyExc_TypeError
,
"Sequence must contain 2-item tuples"
);
"Sequence must contain 2-item tuples"
);
goto
err
;
goto
err
;
}
}
k
=
PyTuple_GET_ITEM
(
o
,
0
);
k
=
PyTuple_GET_ITEM
(
o
,
0
);
v
=
PyTuple_GET_ITEM
(
o
,
1
);
v
=
PyTuple_GET_ITEM
(
o
,
1
);
if
(
PyObject_SetItem
(
map
,
k
,
v
)
<
0
)
{
if
(
PyObject_SetItem
(
map
,
k
,
v
)
<
0
)
{
Py_DECREF
(
o
);
Py_DECREF
(
o
);
goto
err
;
goto
err
;
}
Py_DECREF
(
o
);
}
}
Py_DECREF
(
o
);
}
err
=
0
;
err
=
0
;
err:
err:
Py_DECREF
(
iter
);
Py_DECREF
(
iter
);
Py_DECREF
(
seq
);
Py_DECREF
(
seq
);
return
err
;
return
err
;
}
}
static
PyObject
*
static
PyObject
*
Mapping_update
(
PyObject
*
self
,
PyObject
*
seq
)
Mapping_update
(
PyObject
*
self
,
PyObject
*
seq
)
{
{
if
(
update_from_seq
(
self
,
seq
)
<
0
)
if
(
update_from_seq
(
self
,
seq
)
<
0
)
return
NULL
;
return
NULL
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
/*
/*
...
@@ -532,42 +532,42 @@ Mapping_update(PyObject *self, PyObject *seq)
...
@@ -532,42 +532,42 @@ Mapping_update(PyObject *self, PyObject *seq)
static
int
static
int
bucket_split
(
Bucket
*
self
,
int
index
,
Bucket
*
next
)
bucket_split
(
Bucket
*
self
,
int
index
,
Bucket
*
next
)
{
{
int
next_size
;
int
next_size
;
ASSERT
(
self
->
len
>
1
,
"split of empty bucket"
,
-
1
);
ASSERT
(
self
->
len
>
1
,
"split of empty bucket"
,
-
1
);
if
(
index
<
0
||
index
>=
self
->
len
)
if
(
index
<
0
||
index
>=
self
->
len
)
index
=
self
->
len
/
2
;
index
=
self
->
len
/
2
;
next_size
=
self
->
len
-
index
;
next_size
=
self
->
len
-
index
;
next
->
keys
=
BTree_Malloc
(
sizeof
(
KEY_TYPE
)
*
next_size
);
next
->
keys
=
BTree_Malloc
(
sizeof
(
KEY_TYPE
)
*
next_size
);
if
(
!
next
->
keys
)
if
(
!
next
->
keys
)
return
-
1
;
return
-
1
;
memcpy
(
next
->
keys
,
self
->
keys
+
index
,
sizeof
(
KEY_TYPE
)
*
next_size
);
memcpy
(
next
->
keys
,
self
->
keys
+
index
,
sizeof
(
KEY_TYPE
)
*
next_size
);
if
(
self
->
values
)
{
if
(
self
->
values
)
{
next
->
values
=
BTree_Malloc
(
sizeof
(
VALUE_TYPE
)
*
next_size
);
next
->
values
=
BTree_Malloc
(
sizeof
(
VALUE_TYPE
)
*
next_size
);
if
(
!
next
->
values
)
{
if
(
!
next
->
values
)
{
free
(
next
->
keys
);
free
(
next
->
keys
);
next
->
keys
=
NULL
;
next
->
keys
=
NULL
;
return
-
1
;
return
-
1
;
}
memcpy
(
next
->
values
,
self
->
values
+
index
,
sizeof
(
VALUE_TYPE
)
*
next_size
);
}
}
next
->
size
=
next_size
;
memcpy
(
next
->
values
,
self
->
values
+
index
,
next
->
len
=
next_size
;
sizeof
(
VALUE_TYPE
)
*
next_size
);
self
->
len
=
index
;
}
next
->
size
=
next_size
;
next
->
len
=
next_size
;
self
->
len
=
index
;
next
->
next
=
self
->
next
;
next
->
next
=
self
->
next
;
Py_INCREF
(
next
);
Py_INCREF
(
next
);
self
->
next
=
next
;
self
->
next
=
next
;
if
(
PER_CHANGED
(
self
)
<
0
)
if
(
PER_CHANGED
(
self
)
<
0
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
}
}
/* Set self->next to self->next->next, i.e. unlink self's successor from
/* Set self->next to self->next->next, i.e. unlink self's successor from
...
@@ -580,106 +580,106 @@ bucket_split(Bucket *self, int index, Bucket *next)
...
@@ -580,106 +580,106 @@ bucket_split(Bucket *self, int index, Bucket *next)
static
int
static
int
Bucket_deleteNextBucket
(
Bucket
*
self
)
Bucket_deleteNextBucket
(
Bucket
*
self
)
{
{
int
result
=
-
1
;
/* until proven innocent */
int
result
=
-
1
;
/* until proven innocent */
Bucket
*
successor
;
Bucket
*
successor
;
PER_USE_OR_RETURN
(
self
,
-
1
);
PER_USE_OR_RETURN
(
self
,
-
1
);
successor
=
self
->
next
;
successor
=
self
->
next
;
if
(
successor
)
{
if
(
successor
)
{
Bucket
*
next
;
Bucket
*
next
;
/* Before: self -> successor -> next
/* Before: self -> successor -> next
* After: self --------------> next
* After: self --------------> next
*/
*/
UNLESS
(
PER_USE
(
successor
))
goto
Done
;
UNLESS
(
PER_USE
(
successor
))
goto
Done
;
next
=
successor
->
next
;
next
=
successor
->
next
;
PER_UNUSE
(
successor
);
PER_UNUSE
(
successor
);
Py_XINCREF
(
next
);
/* it may be NULL, of course */
Py_XINCREF
(
next
);
/* it may be NULL, of course */
self
->
next
=
next
;
self
->
next
=
next
;
Py_DECREF
(
successor
);
Py_DECREF
(
successor
);
if
(
PER_CHANGED
(
self
)
<
0
)
if
(
PER_CHANGED
(
self
)
<
0
)
goto
Done
;
goto
Done
;
}
}
result
=
0
;
result
=
0
;
Done:
Done:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
result
;
return
result
;
}
}
/*
/*
Bucket_findRangeEnd -- Find the index of a range endpoint
Bucket_findRangeEnd -- Find the index of a range endpoint
(possibly) contained in a bucket.
(possibly) contained in a bucket.
Arguments: self The bucket
Arguments: self The bucket
keyarg The key to match against
keyarg The key to match against
low Boolean; true for low end of range, false for high
low Boolean; true for low end of range, false for high
exclude_equal Boolean; if true, don't accept an exact match,
exclude_equal Boolean; if true, don't accept an exact match,
and if there is one then move right if low and
and if there is one then move right if low and
left if !low.
left if !low.
offset The output offset
offset The output offset
If low true, *offset <- index of the smallest item >= key,
If low true, *offset <- index of the smallest item >= key,
if low false the index of the largest item <= key. In either case, if there
if low false the index of the largest item <= key. In either case, if there
is no such index, *offset is left alone and 0 is returned.
is no such index, *offset is left alone and 0 is returned.
Return:
Return:
0 No suitable index exists; *offset has not been changed
0 No suitable index exists; *offset has not been changed
1 The correct index was stored into *offset
1 The correct index was stored into *offset
-1 Error
-1 Error
Example: Suppose the keys are [2, 4], and exclude_equal is false. Searching
Example: Suppose the keys are [2, 4], and exclude_equal is false. Searching
for 2 sets *offset to 0 and returns 1 regardless of low. Searching for 4
for 2 sets *offset to 0 and returns 1 regardless of low. Searching for 4
sets *offset to 1 and returns 1 regardless of low.
sets *offset to 1 and returns 1 regardless of low.
Searching for 1:
Searching for 1:
If low true, sets *offset to 0, returns 1.
If low true, sets *offset to 0, returns 1.
If low false, returns 0.
If low false, returns 0.
Searching for 3:
Searching for 3:
If low true, sets *offset to 1, returns 1.
If low true, sets *offset to 1, returns 1.
If low false, sets *offset to 0, returns 1.
If low false, sets *offset to 0, returns 1.
Searching for 5:
Searching for 5:
If low true, returns 0.
If low true, returns 0.
If low false, sets *offset to 1, returns 1.
If low false, sets *offset to 1, returns 1.
The 1, 3 and 5 examples are the same when exclude_equal is true.
The 1, 3 and 5 examples are the same when exclude_equal is true.
*/
*/
static
int
static
int
Bucket_findRangeEnd
(
Bucket
*
self
,
PyObject
*
keyarg
,
int
low
,
int
exclude_equal
,
Bucket_findRangeEnd
(
Bucket
*
self
,
PyObject
*
keyarg
,
int
low
,
int
exclude_equal
,
int
*
offset
)
int
*
offset
)
{
{
int
i
,
cmp
;
int
i
,
cmp
;
int
result
=
-
1
;
/* until proven innocent */
int
result
=
-
1
;
/* until proven innocent */
KEY_TYPE
key
;
KEY_TYPE
key
;
int
copied
=
1
;
int
copied
=
1
;
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
COPY_KEY_FROM_ARG
(
key
,
keyarg
,
copied
);
UNLESS
(
copied
)
return
-
1
;
UNLESS
(
copied
)
return
-
1
;
UNLESS
(
PER_USE
(
self
))
return
-
1
;
UNLESS
(
PER_USE
(
self
))
return
-
1
;
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
BUCKET_SEARCH
(
i
,
cmp
,
self
,
key
,
goto
Done
);
if
(
cmp
==
0
)
{
if
(
cmp
==
0
)
{
/* exact match at index i */
/* exact match at index i */
if
(
exclude_equal
)
{
if
(
exclude_equal
)
{
/* but we don't want an exact match */
/* but we don't want an exact match */
if
(
low
)
if
(
low
)
++
i
;
++
i
;
else
else
--
i
;
}
}
/* Else keys[i-1] < key < keys[i], picturing infinities at OOB indices,
* and i has the smallest item > key, which is correct for low.
*/
else
if
(
!
low
)
/* i-1 has the largest item < key (unless i-1 is 0OB) */
--
i
;
--
i
;
}
result
=
0
<=
i
&&
i
<
self
->
len
;
}
if
(
result
)
/* Else keys[i-1] < key < keys[i], picturing infinities at OOB indices,
*
offset
=
i
;
* and i has the smallest item > key, which is correct for low.
*/
Done:
else
if
(
!
low
)
/* i-1 has the largest item < key (unless i-1 is 0OB) */
--
i
;
result
=
0
<=
i
&&
i
<
self
->
len
;
if
(
result
)
*
offset
=
i
;
Done:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
result
;
return
result
;
}
}
...
@@ -717,8 +717,8 @@ Bucket_maxminKey(Bucket *self, PyObject *args, int min)
...
@@ -717,8 +717,8 @@ Bucket_maxminKey(Bucket *self, PyObject *args, int min)
empty:
empty:
PyErr_SetString
(
PyExc_ValueError
,
PyErr_SetString
(
PyExc_ValueError
,
empty_bucket
?
"empty bucket"
:
empty_bucket
?
"empty bucket"
:
"no key satisfies the conditions"
);
"no key satisfies the conditions"
);
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
NULL
;
return
NULL
;
}
}
...
@@ -737,67 +737,67 @@ Bucket_maxKey(Bucket *self, PyObject *args)
...
@@ -737,67 +737,67 @@ Bucket_maxKey(Bucket *self, PyObject *args)
static
int
static
int
Bucket_rangeSearch
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
,
Bucket_rangeSearch
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
,
int
*
low
,
int
*
high
)
int
*
low
,
int
*
high
)
{
{
PyObject
*
min
=
Py_None
;
PyObject
*
min
=
Py_None
;
PyObject
*
max
=
Py_None
;
PyObject
*
max
=
Py_None
;
int
excludemin
=
0
;
int
excludemin
=
0
;
int
excludemax
=
0
;
int
excludemax
=
0
;
int
rc
;
int
rc
;
if
(
args
)
{
if
(
args
)
{
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"|OOii"
,
search_keywords
,
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"|OOii"
,
search_keywords
,
&
min
,
&
min
,
&
max
,
&
max
,
&
excludemin
,
&
excludemin
,
&
excludemax
))
&
excludemax
))
return
-
1
;
return
-
1
;
}
}
UNLESS
(
self
->
len
)
goto
empty
;
UNLESS
(
self
->
len
)
goto
empty
;
/* Find the low range */
/* Find the low range */
if
(
min
!=
Py_None
)
{
if
(
min
!=
Py_None
)
{
rc
=
Bucket_findRangeEnd
(
self
,
min
,
1
,
excludemin
,
low
);
rc
=
Bucket_findRangeEnd
(
self
,
min
,
1
,
excludemin
,
low
);
if
(
rc
<
0
)
if
(
rc
<
0
)
return
-
1
;
return
-
1
;
if
(
rc
==
0
)
if
(
rc
==
0
)
goto
empty
;
goto
empty
;
}
}
else
{
else
{
*
low
=
0
;
*
low
=
0
;
if
(
excludemin
)
{
if
(
excludemin
)
{
if
(
self
->
len
<
2
)
if
(
self
->
len
<
2
)
goto
empty
;
goto
empty
;
++*
low
;
++*
low
;
}
}
}
}
/* Find the high range */
/* Find the high range */
if
(
max
!=
Py_None
)
{
if
(
max
!=
Py_None
)
{
rc
=
Bucket_findRangeEnd
(
self
,
max
,
0
,
excludemax
,
high
);
rc
=
Bucket_findRangeEnd
(
self
,
max
,
0
,
excludemax
,
high
);
if
(
rc
<
0
)
if
(
rc
<
0
)
return
-
1
;
return
-
1
;
if
(
rc
==
0
)
if
(
rc
==
0
)
goto
empty
;
goto
empty
;
}
}
else
{
else
{
*
high
=
self
->
len
-
1
;
*
high
=
self
->
len
-
1
;
if
(
excludemax
)
{
if
(
excludemax
)
{
if
(
self
->
len
<
2
)
if
(
self
->
len
<
2
)
goto
empty
;
goto
empty
;
--*
high
;
--*
high
;
}
}
}
}
/* If min < max to begin with, it's quite possible that low > high now. */
/* If min < max to begin with, it's quite possible that low > high now. */
if
(
*
low
<=
*
high
)
if
(
*
low
<=
*
high
)
return
0
;
return
0
;
empty:
empty:
*
low
=
0
;
*
low
=
0
;
*
high
=
-
1
;
*
high
=
-
1
;
return
0
;
return
0
;
}
}
/*
/*
...
@@ -819,16 +819,16 @@ bucket_keys(Bucket *self, PyObject *args, PyObject *kw)
...
@@ -819,16 +819,16 @@ bucket_keys(Bucket *self, PyObject *args, PyObject *kw)
PER_USE_OR_RETURN
(
self
,
NULL
);
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
Bucket_rangeSearch
(
self
,
args
,
kw
,
&
low
,
&
high
)
<
0
)
if
(
Bucket_rangeSearch
(
self
,
args
,
kw
,
&
low
,
&
high
)
<
0
)
goto
err
;
goto
err
;
r
=
PyList_New
(
high
-
low
+
1
);
r
=
PyList_New
(
high
-
low
+
1
);
if
(
r
==
NULL
)
if
(
r
==
NULL
)
goto
err
;
goto
err
;
for
(
i
=
low
;
i
<=
high
;
i
++
)
{
for
(
i
=
low
;
i
<=
high
;
i
++
)
{
COPY_KEY_TO_OBJECT
(
key
,
self
->
keys
[
i
]);
COPY_KEY_TO_OBJECT
(
key
,
self
->
keys
[
i
]);
if
(
PyList_SetItem
(
r
,
i
-
low
,
key
)
<
0
)
if
(
PyList_SetItem
(
r
,
i
-
low
,
key
)
<
0
)
goto
err
;
goto
err
;
}
}
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
...
@@ -992,84 +992,84 @@ bucket_byValue(Bucket *self, PyObject *omin)
...
@@ -992,84 +992,84 @@ bucket_byValue(Bucket *self, PyObject *omin)
static
int
static
int
_bucket_clear
(
Bucket
*
self
)
_bucket_clear
(
Bucket
*
self
)
{
{
const
int
len
=
self
->
len
;
const
int
len
=
self
->
len
;
/* Don't declare i at this level. If neither keys nor values are
/* Don't declare i at this level. If neither keys nor values are
* PyObject*, i won't be referenced, and you'll get a nuisance compiler
* PyObject*, i won't be referenced, and you'll get a nuisance compiler
* wng for declaring it here.
* wng for declaring it here.
*/
*/
self
->
len
=
self
->
size
=
0
;
self
->
len
=
self
->
size
=
0
;
if
(
self
->
next
)
{
if
(
self
->
next
)
{
Py_DECREF
(
self
->
next
);
Py_DECREF
(
self
->
next
);
self
->
next
=
NULL
;
self
->
next
=
NULL
;
}
}
/* Silence compiler warning about unused variable len for the case
/* Silence compiler warning about unused variable len for the case
when neither key nor value is an object, i.e. II. */
when neither key nor value is an object, i.e. II. */
(
void
)
len
;
(
void
)
len
;
if
(
self
->
keys
)
{
if
(
self
->
keys
)
{
#ifdef KEY_TYPE_IS_PYOBJECT
#ifdef KEY_TYPE_IS_PYOBJECT
int
i
;
int
i
;
for
(
i
=
0
;
i
<
len
;
++
i
)
for
(
i
=
0
;
i
<
len
;
++
i
)
DECREF_KEY
(
self
->
keys
[
i
]);
DECREF_KEY
(
self
->
keys
[
i
]);
#endif
#endif
free
(
self
->
keys
);
free
(
self
->
keys
);
self
->
keys
=
NULL
;
self
->
keys
=
NULL
;
}
}
if
(
self
->
values
)
{
if
(
self
->
values
)
{
#ifdef VALUE_TYPE_IS_PYOBJECT
#ifdef VALUE_TYPE_IS_PYOBJECT
int
i
;
int
i
;
for
(
i
=
0
;
i
<
len
;
++
i
)
for
(
i
=
0
;
i
<
len
;
++
i
)
DECREF_VALUE
(
self
->
values
[
i
]);
DECREF_VALUE
(
self
->
values
[
i
]);
#endif
#endif
free
(
self
->
values
);
free
(
self
->
values
);
self
->
values
=
NULL
;
self
->
values
=
NULL
;
}
}
return
0
;
return
0
;
}
}
#ifdef PERSISTENT
#ifdef PERSISTENT
static
PyObject
*
static
PyObject
*
bucket__p_deactivate
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
keywords
)
bucket__p_deactivate
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
keywords
)
{
{
int
ghostify
=
1
;
int
ghostify
=
1
;
PyObject
*
force
=
NULL
;
PyObject
*
force
=
NULL
;
if
(
args
&&
PyTuple_GET_SIZE
(
args
)
>
0
)
{
if
(
args
&&
PyTuple_GET_SIZE
(
args
)
>
0
)
{
PyErr_SetString
(
PyExc_TypeError
,
PyErr_SetString
(
PyExc_TypeError
,
"_p_deactivate takes not
positional arguments"
);
"_p_deactivate takes no
positional arguments"
);
return
NULL
;
return
NULL
;
}
}
if
(
keywords
)
{
if
(
keywords
)
{
int
size
=
PyDict_Size
(
keywords
);
int
size
=
PyDict_Size
(
keywords
);
force
=
PyDict_GetItemString
(
keywords
,
"force"
);
force
=
PyDict_GetItemString
(
keywords
,
"force"
);
if
(
force
)
if
(
force
)
size
--
;
size
--
;
if
(
size
)
{
if
(
size
)
{
PyErr_SetString
(
PyExc_TypeError
,
PyErr_SetString
(
PyExc_TypeError
,
"_p_deactivate only accepts keyword arg force"
);
"_p_deactivate only accepts keyword arg force"
);
return
NULL
;
return
NULL
;
}
}
}
}
if
(
self
->
jar
&&
self
->
oid
)
{
if
(
self
->
jar
&&
self
->
oid
)
{
ghostify
=
self
->
state
==
cPersistent_UPTODATE_STATE
;
ghostify
=
self
->
state
==
cPersistent_UPTODATE_STATE
;
if
(
!
ghostify
&&
force
)
{
if
(
!
ghostify
&&
force
)
{
if
(
PyObject_IsTrue
(
force
))
if
(
PyObject_IsTrue
(
force
))
ghostify
=
1
;
ghostify
=
1
;
if
(
PyErr_Occurred
())
if
(
PyErr_Occurred
())
return
NULL
;
return
NULL
;
}
}
if
(
ghostify
)
{
if
(
ghostify
)
{
if
(
_bucket_clear
(
self
)
<
0
)
if
(
_bucket_clear
(
self
)
<
0
)
return
NULL
;
return
NULL
;
PER_GHOSTIFY
(
self
);
PER_GHOSTIFY
(
self
);
}
}
}
Py_INCREF
(
Py_None
);
}
return
Py_None
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
#endif
#endif
...
@@ -1079,16 +1079,16 @@ bucket_clear(Bucket *self, PyObject *args)
...
@@ -1079,16 +1079,16 @@ bucket_clear(Bucket *self, PyObject *args)
PER_USE_OR_RETURN
(
self
,
NULL
);
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
self
->
len
)
{
if
(
self
->
len
)
{
if
(
_bucket_clear
(
self
)
<
0
)
if
(
_bucket_clear
(
self
)
<
0
)
return
NULL
;
return
NULL
;
if
(
PER_CHANGED
(
self
)
<
0
)
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
goto
err
;
}
}
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
err:
err:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
NULL
;
return
NULL
;
}
}
...
@@ -1119,178 +1119,178 @@ err:
...
@@ -1119,178 +1119,178 @@ err:
static
PyObject
*
static
PyObject
*
bucket_getstate
(
Bucket
*
self
)
bucket_getstate
(
Bucket
*
self
)
{
{
PyObject
*
o
=
NULL
,
*
items
=
NULL
,
*
state
;
PyObject
*
o
=
NULL
,
*
items
=
NULL
,
*
state
;
int
i
,
len
,
l
;
int
i
,
len
,
l
;
PER_USE_OR_RETURN
(
self
,
NULL
);
PER_USE_OR_RETURN
(
self
,
NULL
);
len
=
self
->
len
;
len
=
self
->
len
;
if
(
self
->
values
)
{
/* Bucket */
if
(
self
->
values
)
{
/* Bucket */
items
=
PyTuple_New
(
len
*
2
);
items
=
PyTuple_New
(
len
*
2
);
if
(
items
==
NULL
)
if
(
items
==
NULL
)
goto
err
;
goto
err
;
for
(
i
=
0
,
l
=
0
;
i
<
len
;
i
++
)
{
for
(
i
=
0
,
l
=
0
;
i
<
len
;
i
++
)
{
COPY_KEY_TO_OBJECT
(
o
,
self
->
keys
[
i
]);
COPY_KEY_TO_OBJECT
(
o
,
self
->
keys
[
i
]);
if
(
o
==
NULL
)
if
(
o
==
NULL
)
goto
err
;
goto
err
;
PyTuple_SET_ITEM
(
items
,
l
,
o
);
PyTuple_SET_ITEM
(
items
,
l
,
o
);
l
++
;
l
++
;
COPY_VALUE_TO_OBJECT
(
o
,
self
->
values
[
i
]);
COPY_VALUE_TO_OBJECT
(
o
,
self
->
values
[
i
]);
if
(
o
==
NULL
)
if
(
o
==
NULL
)
goto
err
;
goto
err
;
PyTuple_SET_ITEM
(
items
,
l
,
o
);
PyTuple_SET_ITEM
(
items
,
l
,
o
);
l
++
;
l
++
;
}
}
}
else
{
/* Set */
}
else
{
/* Set */
items
=
PyTuple_New
(
len
);
items
=
PyTuple_New
(
len
);
if
(
items
==
NULL
)
if
(
items
==
NULL
)
goto
err
;
goto
err
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
for
(
i
=
0
;
i
<
len
;
i
++
)
{
COPY_KEY_TO_OBJECT
(
o
,
self
->
keys
[
i
]);
COPY_KEY_TO_OBJECT
(
o
,
self
->
keys
[
i
]);
if
(
o
==
NULL
)
if
(
o
==
NULL
)
goto
err
;
goto
err
;
PyTuple_SET_ITEM
(
items
,
i
,
o
);
PyTuple_SET_ITEM
(
items
,
i
,
o
);
}
}
}
}
if
(
self
->
next
)
if
(
self
->
next
)
state
=
Py_BuildValue
(
"OO"
,
items
,
self
->
next
);
state
=
Py_BuildValue
(
"OO"
,
items
,
self
->
next
);
else
else
state
=
Py_BuildValue
(
"(O)"
,
items
);
state
=
Py_BuildValue
(
"(O)"
,
items
);
Py_DECREF
(
items
);
Py_DECREF
(
items
);
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
state
;
return
state
;
err:
err:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
Py_XDECREF
(
items
);
Py_XDECREF
(
items
);
return
NULL
;
return
NULL
;
}
}
static
int
static
int
_bucket_setstate
(
Bucket
*
self
,
PyObject
*
state
)
_bucket_setstate
(
Bucket
*
self
,
PyObject
*
state
)
{
{
PyObject
*
k
,
*
v
,
*
items
;
PyObject
*
k
,
*
v
,
*
items
;
Bucket
*
next
=
NULL
;
Bucket
*
next
=
NULL
;
int
i
,
l
,
len
,
copied
=
1
;
int
i
,
l
,
len
,
copied
=
1
;
KEY_TYPE
*
keys
;
KEY_TYPE
*
keys
;
VALUE_TYPE
*
values
;
VALUE_TYPE
*
values
;
if
(
!
PyArg_ParseTuple
(
state
,
"O|O:__setstate__"
,
&
items
,
&
next
))
if
(
!
PyArg_ParseTuple
(
state
,
"O|O:__setstate__"
,
&
items
,
&
next
))
return
-
1
;
return
-
1
;
if
(
!
PyTuple_Check
(
items
))
{
if
(
!
PyTuple_Check
(
items
))
{
PyErr_SetString
(
PyExc_TypeError
,
PyErr_SetString
(
PyExc_TypeError
,
"tuple required for first state element"
);
"tuple required for first state element"
);
return
-
1
;
return
-
1
;
}
}
len
=
PyTuple_Size
(
items
);
len
=
PyTuple_Size
(
items
);
if
(
len
<
0
)
if
(
len
<
0
)
return
-
1
;
return
-
1
;
len
/=
2
;
len
/=
2
;
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
keys
[
i
]);
DECREF_KEY
(
self
->
keys
[
i
]);
DECREF_VALUE
(
self
->
values
[
i
]);
DECREF_VALUE
(
self
->
values
[
i
]);
}
}
self
->
len
=
0
;
self
->
len
=
0
;
if
(
self
->
next
)
{
if
(
self
->
next
)
{
Py_DECREF
(
self
->
next
);
Py_DECREF
(
self
->
next
);
self
->
next
=
NULL
;
self
->
next
=
NULL
;
}
}
if
(
len
>
self
->
size
)
{
if
(
len
>
self
->
size
)
{
keys
=
BTree_Realloc
(
self
->
keys
,
sizeof
(
KEY_TYPE
)
*
len
);
keys
=
BTree_Realloc
(
self
->
keys
,
sizeof
(
KEY_TYPE
)
*
len
);
if
(
keys
==
NULL
)
if
(
keys
==
NULL
)
return
-
1
;
return
-
1
;
values
=
BTree_Realloc
(
self
->
values
,
sizeof
(
VALUE_TYPE
)
*
len
);
values
=
BTree_Realloc
(
self
->
values
,
sizeof
(
VALUE_TYPE
)
*
len
);
if
(
values
==
NULL
)
if
(
values
==
NULL
)
return
-
1
;
return
-
1
;
self
->
keys
=
keys
;
self
->
keys
=
keys
;
self
->
values
=
values
;
self
->
values
=
values
;
self
->
size
=
len
;
self
->
size
=
len
;
}
}
for
(
i
=
0
,
l
=
0
;
i
<
len
;
i
++
)
{
for
(
i
=
0
,
l
=
0
;
i
<
len
;
i
++
)
{
k
=
PyTuple_GET_ITEM
(
items
,
l
);
k
=
PyTuple_GET_ITEM
(
items
,
l
);
l
++
;
l
++
;
v
=
PyTuple_GET_ITEM
(
items
,
l
);
v
=
PyTuple_GET_ITEM
(
items
,
l
);
l
++
;
l
++
;
COPY_KEY_FROM_ARG
(
self
->
keys
[
i
],
k
,
copied
);
COPY_KEY_FROM_ARG
(
self
->
keys
[
i
],
k
,
copied
);
if
(
!
copied
)
if
(
!
copied
)
return
-
1
;
return
-
1
;
COPY_VALUE_FROM_ARG
(
self
->
values
[
i
],
v
,
copied
);
COPY_VALUE_FROM_ARG
(
self
->
values
[
i
],
v
,
copied
);
if
(
!
copied
)
if
(
!
copied
)
return
-
1
;
return
-
1
;
INCREF_KEY
(
self
->
keys
[
i
]);
INCREF_KEY
(
self
->
keys
[
i
]);
INCREF_VALUE
(
self
->
values
[
i
]);
INCREF_VALUE
(
self
->
values
[
i
]);
}
}
self
->
len
=
len
;
self
->
len
=
len
;
if
(
next
)
{
if
(
next
)
{
self
->
next
=
next
;
self
->
next
=
next
;
Py_INCREF
(
next
);
Py_INCREF
(
next
);
}
}
return
0
;
return
0
;
}
}
static
PyObject
*
static
PyObject
*
bucket_setstate
(
Bucket
*
self
,
PyObject
*
state
)
bucket_setstate
(
Bucket
*
self
,
PyObject
*
state
)
{
{
int
r
;
int
r
;
PER_PREVENT_DEACTIVATION
(
self
);
PER_PREVENT_DEACTIVATION
(
self
);
r
=
_bucket_setstate
(
self
,
state
);
r
=
_bucket_setstate
(
self
,
state
);
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
if
(
r
<
0
)
if
(
r
<
0
)
return
NULL
;
return
NULL
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
}
}
static
PyObject
*
static
PyObject
*
bucket_has_key
(
Bucket
*
self
,
PyObject
*
key
)
bucket_has_key
(
Bucket
*
self
,
PyObject
*
key
)
{
{
return
_bucket_get
(
self
,
key
,
1
);
return
_bucket_get
(
self
,
key
,
1
);
}
}
static
PyObject
*
static
PyObject
*
bucket_setdefault
(
Bucket
*
self
,
PyObject
*
args
)
bucket_setdefault
(
Bucket
*
self
,
PyObject
*
args
)
{
{
PyObject
*
key
;
PyObject
*
key
;
PyObject
*
failobj
;
/* default */
PyObject
*
failobj
;
/* default */
PyObject
*
value
;
/* return value */
PyObject
*
value
;
/* return value */
int
dummy_changed
;
/* in order to call _bucket_set */
int
dummy_changed
;
/* in order to call _bucket_set */
if
(
!
PyArg_UnpackTuple
(
args
,
"setdefault"
,
2
,
2
,
&
key
,
&
failobj
))
return
NULL
;
value
=
_bucket_get
(
self
,
key
,
0
);
if
(
!
PyArg_UnpackTuple
(
args
,
"setdefault"
,
2
,
2
,
&
key
,
&
failobj
))
if
(
value
!=
NULL
)
return
NULL
;
return
value
;
/* The key isn't in the bucket. If that's not due to a KeyError exception,
* pass back the unexpected exception.
*/
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
return
NULL
;
PyErr_Clear
();
/* Associate `key` with `failobj` in the bucket, and return `failobj`. */
value
=
_bucket_get
(
self
,
key
,
0
);
value
=
failobj
;
if
(
value
!=
NULL
)
if
(
_bucket_set
(
self
,
key
,
failobj
,
0
,
0
,
&
dummy_changed
)
<
0
)
value
=
NULL
;
Py_XINCREF
(
value
);
return
value
;
return
value
;
/* The key isn't in the bucket. If that's not due to a KeyError exception,
* pass back the unexpected exception.
*/
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
return
NULL
;
PyErr_Clear
();
/* Associate `key` with `failobj` in the bucket, and return `failobj`. */
value
=
failobj
;
if
(
_bucket_set
(
self
,
key
,
failobj
,
0
,
0
,
&
dummy_changed
)
<
0
)
value
=
NULL
;
Py_XINCREF
(
value
);
return
value
;
}
}
...
@@ -1301,44 +1301,44 @@ Bucket_length(Bucket *self);
...
@@ -1301,44 +1301,44 @@ Bucket_length(Bucket *self);
static
PyObject
*
static
PyObject
*
bucket_pop
(
Bucket
*
self
,
PyObject
*
args
)
bucket_pop
(
Bucket
*
self
,
PyObject
*
args
)
{
{
PyObject
*
key
;
PyObject
*
key
;
PyObject
*
failobj
=
NULL
;
/* default */
PyObject
*
failobj
=
NULL
;
/* default */
PyObject
*
value
;
/* return value */
PyObject
*
value
;
/* return value */
int
dummy_changed
;
/* in order to call _bucket_set */
int
dummy_changed
;
/* in order to call _bucket_set */
if
(
!
PyArg_UnpackTuple
(
args
,
"pop"
,
1
,
2
,
&
key
,
&
failobj
))
return
NULL
;
value
=
_bucket_get
(
self
,
key
,
0
);
if
(
value
!=
NULL
)
{
/* Delete key and associated value. */
if
(
_bucket_set
(
self
,
key
,
NULL
,
0
,
0
,
&
dummy_changed
)
<
0
)
{
Py_DECREF
(
value
);
return
NULL
;
}
return
value
;
}
/* The key isn't in the bucket. If that's not due to a KeyError exception,
if
(
!
PyArg_UnpackTuple
(
args
,
"pop"
,
1
,
2
,
&
key
,
&
failobj
))
* pass back the unexpected exception.
return
NULL
;
*/
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
return
NULL
;
if
(
failobj
!=
NULL
)
{
value
=
_bucket_get
(
self
,
key
,
0
);
/* Clear the KeyError and return the explicit default. */
if
(
value
!=
NULL
)
{
PyErr_Clear
();
/* Delete key and associated value. */
Py_INCREF
(
failobj
);
if
(
_bucket_set
(
self
,
key
,
NULL
,
0
,
0
,
&
dummy_changed
)
<
0
)
{
return
failobj
;
Py_DECREF
(
value
);
return
NULL
;
}
}
return
value
;
}
/* No default given. The only difference in this case is the error
/* The key isn't in the bucket. If that's not due to a KeyError exception,
* message, which depends on whether the bucket is empty.
* pass back the unexpected exception.
*/
*/
if
(
Bucket_length
(
self
)
==
0
)
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
PyErr_SetString
(
PyExc_KeyError
,
"pop(): Bucket is empty"
);
return
NULL
;
return
NULL
;
}
if
(
failobj
!=
NULL
)
{
/* Clear the KeyError and return the explicit default. */
PyErr_Clear
();
Py_INCREF
(
failobj
);
return
failobj
;
}
/* No default given. The only difference in this case is the error
* message, which depends on whether the bucket is empty.
*/
if
(
Bucket_length
(
self
)
==
0
)
PyErr_SetString
(
PyExc_KeyError
,
"pop(): Bucket is empty"
);
return
NULL
;
}
/* Search bucket self for key. This is the sq_contains slot of the
/* Search bucket self for key. This is the sq_contains slot of the
* PySequenceMethods.
* PySequenceMethods.
...
@@ -1351,14 +1351,14 @@ bucket_pop(Bucket *self, PyObject *args)
...
@@ -1351,14 +1351,14 @@ bucket_pop(Bucket *self, PyObject *args)
static
int
static
int
bucket_contains
(
Bucket
*
self
,
PyObject
*
key
)
bucket_contains
(
Bucket
*
self
,
PyObject
*
key
)
{
{
PyObject
*
asobj
=
_bucket_get
(
self
,
key
,
1
);
PyObject
*
asobj
=
_bucket_get
(
self
,
key
,
1
);
int
result
=
-
1
;
int
result
=
-
1
;
if
(
asobj
!=
NULL
)
{
if
(
asobj
!=
NULL
)
{
result
=
PyInt_AsLong
(
asobj
)
?
1
:
0
;
result
=
PyInt_AsLong
(
asobj
)
?
1
:
0
;
Py_DECREF
(
asobj
);
Py_DECREF
(
asobj
);
}
}
return
result
;
return
result
;
}
}
/*
/*
...
@@ -1368,18 +1368,18 @@ bucket_contains(Bucket *self, PyObject *key)
...
@@ -1368,18 +1368,18 @@ bucket_contains(Bucket *self, PyObject *key)
static
PyObject
*
static
PyObject
*
bucket_getm
(
Bucket
*
self
,
PyObject
*
args
)
bucket_getm
(
Bucket
*
self
,
PyObject
*
args
)
{
{
PyObject
*
key
,
*
d
=
Py_None
,
*
r
;
PyObject
*
key
,
*
d
=
Py_None
,
*
r
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O:get"
,
&
key
,
&
d
))
if
(
!
PyArg_ParseTuple
(
args
,
"O|O:get"
,
&
key
,
&
d
))
return
NULL
;
return
NULL
;
r
=
_bucket_get
(
self
,
key
,
0
);
r
=
_bucket_get
(
self
,
key
,
0
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
if
(
!
PyErr_ExceptionMatches
(
PyExc_KeyError
))
return
NULL
;
return
NULL
;
PyErr_Clear
();
PyErr_Clear
();
Py_INCREF
(
d
);
Py_INCREF
(
d
);
return
d
;
return
d
;
}
}
/**************************************************************************/
/**************************************************************************/
...
@@ -1394,52 +1394,52 @@ bucket_getm(Bucket *self, PyObject *args)
...
@@ -1394,52 +1394,52 @@ bucket_getm(Bucket *self, PyObject *args)
static
PyObject
*
static
PyObject
*
buildBucketIter
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
,
char
kind
)
buildBucketIter
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
,
char
kind
)
{
{
BTreeItems
*
items
;
BTreeItems
*
items
;
int
lowoffset
,
highoffset
;
int
lowoffset
,
highoffset
;
BTreeIter
*
result
=
NULL
;
BTreeIter
*
result
=
NULL
;
PER_USE_OR_RETURN
(
self
,
NULL
);
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
Bucket_rangeSearch
(
self
,
args
,
kw
,
&
lowoffset
,
&
highoffset
)
<
0
)
if
(
Bucket_rangeSearch
(
self
,
args
,
kw
,
&
lowoffset
,
&
highoffset
)
<
0
)
goto
Done
;
goto
Done
;
items
=
(
BTreeItems
*
)
newBTreeItems
(
kind
,
self
,
lowoffset
,
items
=
(
BTreeItems
*
)
newBTreeItems
(
kind
,
self
,
lowoffset
,
self
,
highoffset
);
self
,
highoffset
);
if
(
items
==
NULL
)
goto
Done
;
if
(
items
==
NULL
)
goto
Done
;
result
=
BTreeIter_new
(
items
);
/* win or lose, we're done */
result
=
BTreeIter_new
(
items
);
/* win or lose, we're done */
Py_DECREF
(
items
);
Py_DECREF
(
items
);
Done:
Done:
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
(
PyObject
*
)
result
;
return
(
PyObject
*
)
result
;
}
}
/* The implementation of iter(Bucket_or_Set); the Bucket tp_iter slot. */
/* The implementation of iter(Bucket_or_Set); the Bucket tp_iter slot. */
static
PyObject
*
static
PyObject
*
Bucket_getiter
(
Bucket
*
self
)
Bucket_getiter
(
Bucket
*
self
)
{
{
return
buildBucketIter
(
self
,
NULL
,
NULL
,
'k'
);
return
buildBucketIter
(
self
,
NULL
,
NULL
,
'k'
);
}
}
/* The implementation of Bucket.iterkeys(). */
/* The implementation of Bucket.iterkeys(). */
static
PyObject
*
static
PyObject
*
Bucket_iterkeys
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
Bucket_iterkeys
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
{
return
buildBucketIter
(
self
,
args
,
kw
,
'k'
);
return
buildBucketIter
(
self
,
args
,
kw
,
'k'
);
}
}
/* The implementation of Bucket.itervalues(). */
/* The implementation of Bucket.itervalues(). */
static
PyObject
*
static
PyObject
*
Bucket_itervalues
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
Bucket_itervalues
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
{
return
buildBucketIter
(
self
,
args
,
kw
,
'v'
);
return
buildBucketIter
(
self
,
args
,
kw
,
'v'
);
}
}
/* The implementation of Bucket.iteritems(). */
/* The implementation of Bucket.iteritems(). */
static
PyObject
*
static
PyObject
*
Bucket_iteritems
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
Bucket_iteritems
(
Bucket
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
{
return
buildBucketIter
(
self
,
args
,
kw
,
'i'
);
return
buildBucketIter
(
self
,
args
,
kw
,
'i'
);
}
}
/* End of iterator support. */
/* End of iterator support. */
...
@@ -1451,61 +1451,61 @@ static PyObject *bucket_merge(Bucket *s1, Bucket *s2, Bucket *s3);
...
@@ -1451,61 +1451,61 @@ static PyObject *bucket_merge(Bucket *s1, Bucket *s2, Bucket *s3);
static
PyObject
*
static
PyObject
*
_bucket__p_resolveConflict
(
PyObject
*
ob_type
,
PyObject
*
s
[
3
])
_bucket__p_resolveConflict
(
PyObject
*
ob_type
,
PyObject
*
s
[
3
])
{
{
PyObject
*
result
=
NULL
;
/* guilty until proved innocent */
PyObject
*
result
=
NULL
;
/* guilty until proved innocent */
Bucket
*
b
[
3
]
=
{
NULL
,
NULL
,
NULL
};
Bucket
*
b
[
3
]
=
{
NULL
,
NULL
,
NULL
};
PyObject
*
meth
=
NULL
;
PyObject
*
meth
=
NULL
;
PyObject
*
a
=
NULL
;
PyObject
*
a
=
NULL
;
int
i
;
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
{
PyObject
*
r
;
PyObject
*
r
;
b
[
i
]
=
(
Bucket
*
)
PyObject_CallObject
((
PyObject
*
)
ob_type
,
NULL
);
b
[
i
]
=
(
Bucket
*
)
PyObject_CallObject
((
PyObject
*
)
ob_type
,
NULL
);
if
(
b
[
i
]
==
NULL
)
if
(
b
[
i
]
==
NULL
)
goto
Done
;
goto
Done
;
if
(
s
[
i
]
==
Py_None
)
/* None is equivalent to empty, for BTrees */
if
(
s
[
i
]
==
Py_None
)
/* None is equivalent to empty, for BTrees */
continue
;
continue
;
meth
=
PyObject_GetAttr
((
PyObject
*
)
b
[
i
],
__setstate___str
);
meth
=
PyObject_GetAttr
((
PyObject
*
)
b
[
i
],
__setstate___str
);
if
(
meth
==
NULL
)
if
(
meth
==
NULL
)
goto
Done
;
goto
Done
;
a
=
PyTuple_New
(
1
);
a
=
PyTuple_New
(
1
);
if
(
a
==
NULL
)
if
(
a
==
NULL
)
goto
Done
;
goto
Done
;
PyTuple_SET_ITEM
(
a
,
0
,
s
[
i
]);
PyTuple_SET_ITEM
(
a
,
0
,
s
[
i
]);
Py_INCREF
(
s
[
i
]);
Py_INCREF
(
s
[
i
]);
r
=
PyObject_CallObject
(
meth
,
a
);
/* b[i].__setstate__(s[i]) */
r
=
PyObject_CallObject
(
meth
,
a
);
/* b[i].__setstate__(s[i]) */
if
(
r
==
NULL
)
if
(
r
==
NULL
)
goto
Done
;
goto
Done
;
Py_DECREF
(
r
);
Py_DECREF
(
r
);
Py_DECREF
(
a
);
Py_DECREF
(
a
);
Py_DECREF
(
meth
);
Py_DECREF
(
meth
);
a
=
meth
=
NULL
;
a
=
meth
=
NULL
;
}
}
if
(
b
[
0
]
->
next
!=
b
[
1
]
->
next
||
b
[
0
]
->
next
!=
b
[
2
]
->
next
)
if
(
b
[
0
]
->
next
!=
b
[
1
]
->
next
||
b
[
0
]
->
next
!=
b
[
2
]
->
next
)
merge_error
(
-
1
,
-
1
,
-
1
,
0
);
merge_error
(
-
1
,
-
1
,
-
1
,
0
);
else
else
result
=
bucket_merge
(
b
[
0
],
b
[
1
],
b
[
2
]);
result
=
bucket_merge
(
b
[
0
],
b
[
1
],
b
[
2
]);
Done:
Done:
Py_XDECREF
(
meth
);
Py_XDECREF
(
meth
);
Py_XDECREF
(
a
);
Py_XDECREF
(
a
);
Py_XDECREF
(
b
[
0
]);
Py_XDECREF
(
b
[
0
]);
Py_XDECREF
(
b
[
1
]);
Py_XDECREF
(
b
[
1
]);
Py_XDECREF
(
b
[
2
]);
Py_XDECREF
(
b
[
2
]);
return
result
;
return
result
;
}
}
static
PyObject
*
static
PyObject
*
bucket__p_resolveConflict
(
Bucket
*
self
,
PyObject
*
args
)
bucket__p_resolveConflict
(
Bucket
*
self
,
PyObject
*
args
)
{
{
PyObject
*
s
[
3
];
PyObject
*
s
[
3
];
if
(
!
PyArg_ParseTuple
(
args
,
"OOO"
,
&
s
[
0
],
&
s
[
1
],
&
s
[
2
]))
if
(
!
PyArg_ParseTuple
(
args
,
"OOO"
,
&
s
[
0
],
&
s
[
1
],
&
s
[
2
]))
return
NULL
;
return
NULL
;
return
_bucket__p_resolveConflict
((
PyObject
*
)
self
->
ob_type
,
s
);
return
_bucket__p_resolveConflict
((
PyObject
*
)
self
->
ob_type
,
s
);
}
}
#endif
#endif
...
@@ -1518,157 +1518,157 @@ bucket__p_resolveConflict(Bucket *self, PyObject *args)
...
@@ -1518,157 +1518,157 @@ bucket__p_resolveConflict(Bucket *self, PyObject *args)
*/
*/
static
struct
PyMemberDef
Bucket_members
[]
=
{
static
struct
PyMemberDef
Bucket_members
[]
=
{
{
"_next"
,
T_OBJECT
,
offsetof
(
Bucket
,
next
)},
{
"_next"
,
T_OBJECT
,
offsetof
(
Bucket
,
next
)},
{
NULL
}
{
NULL
}
};
};
static
struct
PyMethodDef
Bucket_methods
[]
=
{
static
struct
PyMethodDef
Bucket_methods
[]
=
{
{
"__getstate__"
,
(
PyCFunction
)
bucket_getstate
,
METH_NOARGS
,
{
"__getstate__"
,
(
PyCFunction
)
bucket_getstate
,
METH_NOARGS
,
"__getstate__() -- Return the picklable state of the object"
},
"__getstate__() -- Return the picklable state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
bucket_setstate
,
METH_O
,
{
"__setstate__"
,
(
PyCFunction
)
bucket_setstate
,
METH_O
,
"__setstate__() -- Set the state of the object"
},
"__setstate__() -- Set the state of the object"
},
{
"keys"
,
(
PyCFunction
)
bucket_keys
,
METH_KEYWORDS
,
{
"keys"
,
(
PyCFunction
)
bucket_keys
,
METH_KEYWORDS
,
"keys([min, max]) -- Return the keys"
},
"keys([min, max]) -- Return the keys"
},
{
"has_key"
,
(
PyCFunction
)
bucket_has_key
,
METH_O
,
{
"has_key"
,
(
PyCFunction
)
bucket_has_key
,
METH_O
,
"has_key(key) -- Test whether the bucket contains the given key"
},
"has_key(key) -- Test whether the bucket contains the given key"
},
{
"clear"
,
(
PyCFunction
)
bucket_clear
,
METH_VARARGS
,
{
"clear"
,
(
PyCFunction
)
bucket_clear
,
METH_VARARGS
,
"clear() -- Remove all of the items from the bucket"
},
"clear() -- Remove all of the items from the bucket"
},
{
"update"
,
(
PyCFunction
)
Mapping_update
,
METH_O
,
{
"update"
,
(
PyCFunction
)
Mapping_update
,
METH_O
,
"update(collection) -- Add the items from the given collection"
},
"update(collection) -- Add the items from the given collection"
},
{
"maxKey"
,
(
PyCFunction
)
Bucket_maxKey
,
METH_VARARGS
,
{
"maxKey"
,
(
PyCFunction
)
Bucket_maxKey
,
METH_VARARGS
,
"maxKey([key]) -- Find the maximum key
\n\n
"
"maxKey([key]) -- Find the maximum key
\n\n
"
"If an argument is given, find the maximum <= the argument"
},
"If an argument is given, find the maximum <= the argument"
},
{
"minKey"
,
(
PyCFunction
)
Bucket_minKey
,
METH_VARARGS
,
{
"minKey"
,
(
PyCFunction
)
Bucket_minKey
,
METH_VARARGS
,
"minKey([key]) -- Find the minimum key
\n\n
"
"minKey([key]) -- Find the minimum key
\n\n
"
"If an argument is given, find the minimum >= the argument"
},
"If an argument is given, find the minimum >= the argument"
},
{
"values"
,
(
PyCFunction
)
bucket_values
,
METH_KEYWORDS
,
{
"values"
,
(
PyCFunction
)
bucket_values
,
METH_KEYWORDS
,
"values([min, max]) -- Return the values"
},
"values([min, max]) -- Return the values"
},
{
"items"
,
(
PyCFunction
)
bucket_items
,
METH_KEYWORDS
,
{
"items"
,
(
PyCFunction
)
bucket_items
,
METH_KEYWORDS
,
"items([min, max])) -- Return the items"
},
"items([min, max])) -- Return the items"
},
{
"byValue"
,
(
PyCFunction
)
bucket_byValue
,
METH_O
,
{
"byValue"
,
(
PyCFunction
)
bucket_byValue
,
METH_O
,
"byValue(min) -- "
"byValue(min) -- "
"Return value-keys with values >= min and reverse sorted by values"
},
"Return value-keys with values >= min and reverse sorted by values"
},
{
"get"
,
(
PyCFunction
)
bucket_getm
,
METH_VARARGS
,
{
"get"
,
(
PyCFunction
)
bucket_getm
,
METH_VARARGS
,
"get(key[,default]) -- Look up a value
\n\n
"
"get(key[,default]) -- Look up a value
\n\n
"
"Return the default (or None) if the key is not found."
},
"Return the default (or None) if the key is not found."
},
{
"setdefault"
,
(
PyCFunction
)
bucket_setdefault
,
METH_VARARGS
,
{
"setdefault"
,
(
PyCFunction
)
bucket_setdefault
,
METH_VARARGS
,
"D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.
\n\n
"
"D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.
\n\n
"
"Return the value like get() except that if key is missing, d is both
\n
"
"Return the value like get() except that if key is missing, d is both
\n
"
"returned and inserted into the bucket as the value of k."
},
"returned and inserted into the bucket as the value of k."
},
{
"pop"
,
(
PyCFunction
)
bucket_pop
,
METH_VARARGS
,
{
"pop"
,
(
PyCFunction
)
bucket_pop
,
METH_VARARGS
,
"D.pop(k[, d]) -> v, remove key and return the corresponding value.
\n\n
"
"D.pop(k[, d]) -> v, remove key and return the corresponding value.
\n\n
"
"If key is not found, d is returned if given, otherwise KeyError
\n
"
"If key is not found, d is returned if given, otherwise KeyError
\n
"
"is raised."
},
"is raised."
},
{
"iterkeys"
,
(
PyCFunction
)
Bucket_iterkeys
,
METH_KEYWORDS
,
{
"iterkeys"
,
(
PyCFunction
)
Bucket_iterkeys
,
METH_KEYWORDS
,
"B.iterkeys([min[,max]]) -> an iterator over the keys of B"
},
"B.iterkeys([min[,max]]) -> an iterator over the keys of B"
},
{
"itervalues"
,
(
PyCFunction
)
Bucket_itervalues
,
METH_KEYWORDS
,
{
"itervalues"
,
(
PyCFunction
)
Bucket_itervalues
,
METH_KEYWORDS
,
"B.itervalues([min[,max]]) -> an iterator over the values of B"
},
"B.itervalues([min[,max]]) -> an iterator over the values of B"
},
{
"iteritems"
,
(
PyCFunction
)
Bucket_iteritems
,
METH_KEYWORDS
,
{
"iteritems"
,
(
PyCFunction
)
Bucket_iteritems
,
METH_KEYWORDS
,
"B.iteritems([min[,max]]) -> an iterator over the (key, value) items of B"
},
"B.iteritems([min[,max]]) -> an iterator over the (key, value) items of B"
},
#ifdef EXTRA_BUCKET_METHODS
#ifdef EXTRA_BUCKET_METHODS
EXTRA_BUCKET_METHODS
EXTRA_BUCKET_METHODS
#endif
#endif
#ifdef PERSISTENT
#ifdef PERSISTENT
{
"_p_resolveConflict"
,
(
PyCFunction
)
bucket__p_resolveConflict
,
{
"_p_resolveConflict"
,
(
PyCFunction
)
bucket__p_resolveConflict
,
METH_VARARGS
,
METH_VARARGS
,
"_p_resolveConflict() -- Reinitialize from a newly created copy"
},
"_p_resolveConflict() -- Reinitialize from a newly created copy"
},
{
"_p_deactivate"
,
(
PyCFunction
)
bucket__p_deactivate
,
METH_KEYWORDS
,
{
"_p_deactivate"
,
(
PyCFunction
)
bucket__p_deactivate
,
METH_KEYWORDS
,
"_p_deactivate() -- Reinitialize from a newly created copy"
},
"_p_deactivate() -- Reinitialize from a newly created copy"
},
#endif
#endif
{
NULL
,
NULL
}
{
NULL
,
NULL
}
};
};
static
int
static
int
Bucket_init
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
Bucket_init
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
{
{
PyObject
*
v
=
NULL
;
PyObject
*
v
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
"|O:"
MOD_NAME_PREFIX
"Bucket"
,
&
v
))
if
(
!
PyArg_ParseTuple
(
args
,
"|O:"
MOD_NAME_PREFIX
"Bucket"
,
&
v
))
return
-
1
;
return
-
1
;
if
(
v
)
if
(
v
)
return
update_from_seq
(
self
,
v
);
return
update_from_seq
(
self
,
v
);
else
else
return
0
;
return
0
;
}
}
static
void
static
void
bucket_dealloc
(
Bucket
*
self
)
bucket_dealloc
(
Bucket
*
self
)
{
{
if
(
self
->
state
!=
cPersistent_GHOST_STATE
)
if
(
self
->
state
!=
cPersistent_GHOST_STATE
)
_bucket_clear
(
self
);
_bucket_clear
(
self
);
cPersistenceCAPI
->
pertype
->
tp_dealloc
((
PyObject
*
)
self
);
cPersistenceCAPI
->
pertype
->
tp_dealloc
((
PyObject
*
)
self
);
}
}
static
int
static
int
bucket_traverse
(
Bucket
*
self
,
visitproc
visit
,
void
*
arg
)
bucket_traverse
(
Bucket
*
self
,
visitproc
visit
,
void
*
arg
)
{
{
int
err
=
0
;
int
err
=
0
;
int
i
,
len
;
int
i
,
len
;
#define VISIT(SLOT) \
#define VISIT(SLOT) \
if (SLOT) { \
if (SLOT) { \
err = visit((PyObject *)(SLOT), arg); \
err = visit((PyObject *)(SLOT), arg); \
if (err) \
if (err) \
goto Done; \
goto Done; \
}
}
/* Call our base type's traverse function. Because buckets are
* subclasses of Peristent, there must be one.
*/
err
=
cPersistenceCAPI
->
pertype
->
tp_traverse
((
PyObject
*
)
self
,
visit
,
arg
);
if
(
err
)
goto
Done
;
/* If this is registered with the persistence system, cleaning up cycles
* is the database's problem. It would be horrid to unghostify buckets
* here just to chase pointers every time gc runs.
*/
if
(
self
->
state
==
cPersistent_GHOST_STATE
)
goto
Done
;
len
=
self
->
len
;
/* Call our base type's traverse function. Because buckets are
(
void
)
i
;
/* if neither keys nor values are PyObject*, "i" is otherwise
* subclasses of Peristent, there must be one.
unreferenced and we get a nuisance compiler wng */
*/
err
=
cPersistenceCAPI
->
pertype
->
tp_traverse
((
PyObject
*
)
self
,
visit
,
arg
);
if
(
err
)
goto
Done
;
/* If this is registered with the persistence system, cleaning up cycles
* is the database's problem. It would be horrid to unghostify buckets
* here just to chase pointers every time gc runs.
*/
if
(
self
->
state
==
cPersistent_GHOST_STATE
)
goto
Done
;
len
=
self
->
len
;
(
void
)
i
;
/* if neither keys nor values are PyObject*, "i" is otherwise
unreferenced and we get a nuisance compiler wng */
#ifdef KEY_TYPE_IS_PYOBJECT
#ifdef KEY_TYPE_IS_PYOBJECT
/* Keys are Python objects so need to be traversed. */
/* Keys are Python objects so need to be traversed. */
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
VISIT
(
self
->
keys
[
i
]);
VISIT
(
self
->
keys
[
i
]);
#endif
#endif
#ifdef VALUE_TYPE_IS_PYOBJECT
#ifdef VALUE_TYPE_IS_PYOBJECT
if
(
self
->
values
!=
NULL
)
{
if
(
self
->
values
!=
NULL
)
{
/* self->values exists (this is a mapping bucket, not a set bucket),
/* self->values exists (this is a mapping bucket, not a set bucket),
* and are Python objects, so need to be traversed. */
* and are Python objects, so need to be traversed. */
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
VISIT
(
self
->
values
[
i
]);
VISIT
(
self
->
values
[
i
]);
}
}
#endif
#endif
VISIT
(
self
->
next
);
VISIT
(
self
->
next
);
Done:
Done:
return
err
;
return
err
;
#undef VISIT
#undef VISIT
}
}
...
@@ -1676,20 +1676,20 @@ Done:
...
@@ -1676,20 +1676,20 @@ Done:
static
int
static
int
bucket_tp_clear
(
Bucket
*
self
)
bucket_tp_clear
(
Bucket
*
self
)
{
{
if
(
self
->
state
!=
cPersistent_GHOST_STATE
)
if
(
self
->
state
!=
cPersistent_GHOST_STATE
)
_bucket_clear
(
self
);
_bucket_clear
(
self
);
return
0
;
return
0
;
}
}
/* Code to access Bucket objects as mappings */
/* Code to access Bucket objects as mappings */
static
int
static
int
Bucket_length
(
Bucket
*
self
)
Bucket_length
(
Bucket
*
self
)
{
{
int
r
;
int
r
;
UNLESS
(
PER_USE
(
self
))
return
-
1
;
UNLESS
(
PER_USE
(
self
))
return
-
1
;
r
=
self
->
len
;
r
=
self
->
len
;
PER_UNUSE
(
self
);
PER_UNUSE
(
self
);
return
r
;
return
r
;
}
}
static
PyMappingMethods
Bucket_as_mapping
=
{
static
PyMappingMethods
Bucket_as_mapping
=
{
...
@@ -1699,100 +1699,100 @@ static PyMappingMethods Bucket_as_mapping = {
...
@@ -1699,100 +1699,100 @@ static PyMappingMethods Bucket_as_mapping = {
};
};
static
PySequenceMethods
Bucket_as_sequence
=
{
static
PySequenceMethods
Bucket_as_sequence
=
{
(
lenfunc
)
0
,
/* sq_length */
(
lenfunc
)
0
,
/* sq_length */
(
binaryfunc
)
0
,
/* sq_concat */
(
binaryfunc
)
0
,
/* sq_concat */
(
ssizeargfunc
)
0
,
/* sq_repeat */
(
ssizeargfunc
)
0
,
/* sq_repeat */
(
ssizeargfunc
)
0
,
/* sq_item */
(
ssizeargfunc
)
0
,
/* sq_item */
(
ssizessizeargfunc
)
0
,
/* sq_slice */
(
ssizessizeargfunc
)
0
,
/* sq_slice */
(
ssizeobjargproc
)
0
,
/* sq_ass_item */
(
ssizeobjargproc
)
0
,
/* sq_ass_item */
(
ssizessizeobjargproc
)
0
,
/* sq_ass_slice */
(
ssizessizeobjargproc
)
0
,
/* sq_ass_slice */
(
objobjproc
)
bucket_contains
,
/* sq_contains */
(
objobjproc
)
bucket_contains
,
/* sq_contains */
0
,
/* sq_inplace_concat */
0
,
/* sq_inplace_concat */
0
,
/* sq_inplace_repeat */
0
,
/* sq_inplace_repeat */
};
};
static
PyObject
*
static
PyObject
*
bucket_repr
(
Bucket
*
self
)
bucket_repr
(
Bucket
*
self
)
{
{
PyObject
*
i
,
*
r
;
PyObject
*
i
,
*
r
;
char
repr
[
10000
];
char
repr
[
10000
];
int
rv
;
int
rv
;
i
=
bucket_items
(
self
,
NULL
,
NULL
);
i
=
bucket_items
(
self
,
NULL
,
NULL
);
if
(
!
i
)
if
(
!
i
)
return
NULL
;
return
NULL
;
r
=
PyObject_Repr
(
i
);
r
=
PyObject_Repr
(
i
);
Py_DECREF
(
i
);
Py_DECREF
(
i
);
if
(
!
r
)
{
if
(
!
r
)
{
return
NULL
;
return
NULL
;
}
}
rv
=
PyOS_snprintf
(
repr
,
sizeof
(
repr
),
rv
=
PyOS_snprintf
(
repr
,
sizeof
(
repr
),
"%s(%s)"
,
self
->
ob_type
->
tp_name
,
"%s(%s)"
,
self
->
ob_type
->
tp_name
,
PyString_AS_STRING
(
r
));
PyString_AS_STRING
(
r
));
if
(
rv
>
0
&&
rv
<
sizeof
(
repr
))
{
if
(
rv
>
0
&&
rv
<
sizeof
(
repr
))
{
Py_DECREF
(
r
);
Py_DECREF
(
r
);
return
PyString_FromStringAndSize
(
repr
,
strlen
(
repr
));
return
PyString_FromStringAndSize
(
repr
,
strlen
(
repr
));
}
}
else
{
else
{
/* The static buffer wasn't big enough */
/* The static buffer wasn't big enough */
int
size
;
int
size
;
PyObject
*
s
;
PyObject
*
s
;
/* 3 for the parens and the null byte */
/* 3 for the parens and the null byte */
size
=
strlen
(
self
->
ob_type
->
tp_name
)
+
PyString_GET_SIZE
(
r
)
+
3
;
size
=
strlen
(
self
->
ob_type
->
tp_name
)
+
PyString_GET_SIZE
(
r
)
+
3
;
s
=
PyString_FromStringAndSize
(
NULL
,
size
);
s
=
PyString_FromStringAndSize
(
NULL
,
size
);
if
(
!
s
)
{
if
(
!
s
)
{
Py_DECREF
(
r
);
Py_DECREF
(
r
);
return
r
;
return
r
;
}
PyOS_snprintf
(
PyString_AS_STRING
(
s
),
size
,
"%s(%s)"
,
self
->
ob_type
->
tp_name
,
PyString_AS_STRING
(
r
));
Py_DECREF
(
r
);
return
s
;
}
}
PyOS_snprintf
(
PyString_AS_STRING
(
s
),
size
,
"%s(%s)"
,
self
->
ob_type
->
tp_name
,
PyString_AS_STRING
(
r
));
Py_DECREF
(
r
);
return
s
;
}
}
}
static
PyTypeObject
BucketType
=
{
static
PyTypeObject
BucketType
=
{
PyObject_HEAD_INIT
(
NULL
)
/* PyPersist_Type */
PyObject_HEAD_INIT
(
NULL
)
/* PyPersist_Type */
0
,
/* ob_size */
0
,
/* ob_size */
MODULE_NAME
MOD_NAME_PREFIX
"Bucket"
,
/* tp_name */
MODULE_NAME
MOD_NAME_PREFIX
"Bucket"
,
/* tp_name */
sizeof
(
Bucket
),
/* tp_basicsize */
sizeof
(
Bucket
),
/* tp_basicsize */
0
,
/* tp_itemsize */
0
,
/* tp_itemsize */
(
destructor
)
bucket_dealloc
,
/* tp_dealloc */
(
destructor
)
bucket_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_compare */
(
reprfunc
)
bucket_repr
,
/* tp_repr */
(
reprfunc
)
bucket_repr
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_number */
&
Bucket_as_sequence
,
/* tp_as_sequence */
&
Bucket_as_sequence
,
/* tp_as_sequence */
&
Bucket_as_mapping
,
/* tp_as_mapping */
&
Bucket_as_mapping
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_call */
0
,
/* tp_str */
0
,
/* tp_str */
0
,
/* tp_getattro */
0
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
0
,
/* tp_doc */
0
,
/* tp_doc */
(
traverseproc
)
bucket_traverse
,
/* tp_traverse */
(
traverseproc
)
bucket_traverse
,
/* tp_traverse */
(
inquiry
)
bucket_tp_clear
,
/* tp_clear */
(
inquiry
)
bucket_tp_clear
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_weaklistoffset */
(
getiterfunc
)
Bucket_getiter
,
/* tp_iter */
(
getiterfunc
)
Bucket_getiter
,
/* tp_iter */
0
,
/* tp_iternext */
0
,
/* tp_iternext */
Bucket_methods
,
/* tp_methods */
Bucket_methods
,
/* tp_methods */
Bucket_members
,
/* tp_members */
Bucket_members
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
0
,
/* tp_descr_set */
0
,
/* tp_dictoffset */
0
,
/* tp_dictoffset */
Bucket_init
,
/* tp_init */
Bucket_init
,
/* tp_init */
0
,
/* tp_alloc */
0
,
/* tp_alloc */
0
,
/*PyType_GenericNew,*/
/* tp_new */
0
,
/*PyType_GenericNew,*/
/* tp_new */
};
};
static
int
static
int
...
...
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