Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
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
Kirill Smelkov
Zope
Commits
9671a5bc
Commit
9671a5bc
authored
Nov 21, 1997
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
got rid of BTree and intSet modules
parent
b823b5cb
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
0 additions
and
3852 deletions
+0
-3852
lib/python/SearchIndex/BTree.c
lib/python/SearchIndex/BTree.c
+0
-1819
lib/python/SearchIndex/IIBTree.c
lib/python/SearchIndex/IIBTree.c
+0
-8
lib/python/SearchIndex/IOBTree.c
lib/python/SearchIndex/IOBTree.c
+0
-7
lib/python/SearchIndex/OIBTree.c
lib/python/SearchIndex/OIBTree.c
+0
-7
lib/python/SearchIndex/Trie.c
lib/python/SearchIndex/Trie.c
+0
-836
lib/python/SearchIndex/WordSequence.c
lib/python/SearchIndex/WordSequence.c
+0
-587
lib/python/SearchIndex/intSet.c
lib/python/SearchIndex/intSet.c
+0
-588
No files found.
lib/python/SearchIndex/BTree.c
deleted
100755 → 0
View file @
b823b5cb
/***********************************************************
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.10 1997/11/13 20:45:51 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_PREVENT_DEACTIVATION(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
(
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
UNLESS
(
!
v
||
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
)
{
Py_INCREF
(
v
);
#ifdef INTVAL
self
->
data
[
i
].
value
=
iv
;
#else
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
(
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 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
UNLESS
(
!
value
||
PyInt_Check
(
value
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Bucket __getitem__ expected integer key"
);
return
-
1
;
}
iv
=
PyInt_AsLong
(
value
);
#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
--
;
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
)
{
int
i
;
/* Note that this implementation is broken, in that it doesn't
account for subclass needs. */
for
(
i
=
self
->
len
;
--
i
>=
0
;
)
{
DECREF_KEY
(
self
->
data
[
i
].
key
);
DECREF_VALUE
(
self
->
data
[
i
].
value
);
}
self
->
len
=
0
;
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
)
{
/* Note that this implementation is broken, in that it doesn't
account for subclass needs. */
if
(
_BTree_clear
(
self
)
<
0
)
return
NULL
;
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
);
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
PER_PREVENT_DEACTIVATION
(
self
);
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
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"
},
#ifdef PERSISTENT
{
"_p___reinit__"
,
(
PyCFunction
)
bucket__p___reinit__
,
METH_VARARGS
,
"_p___reinit__() -- 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
;
PER_PREVENT_DEACTIVATION
(
self
);
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
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"
},
#ifdef PERSISTENT
{
"_p___reinit__"
,
(
PyCFunction
)
BTree__p___reinit__
,
METH_VARARGS
,
"_p___reinit__() -- 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
);
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
);
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
),
};
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
),
};
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.10 $"
;
UNLESS
(
PyExtensionClassCAPI
=
PyCObject_Import
(
"ExtensionClass"
,
"CAPI"
))
return
;
#ifdef PERSISTENT
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
static
PyMethodChain
mb
,
mn
;
mb
.
methods
=
BucketType
.
methods
.
methods
;
BucketType
.
methods
.
methods
=
cPersistenceCAPI
->
methods
->
methods
;
BucketType
.
methods
.
link
=&
mb
;
BucketType
.
tp_getattro
=
cPersistenceCAPI
->
getattro
;
BucketType
.
tp_setattro
=
cPersistenceCAPI
->
setattro
;
mn
.
methods
=
BTreeType
.
methods
.
methods
;
BTreeType
.
methods
.
methods
=
cPersistenceCAPI
->
methods
->
methods
;
BTreeType
.
methods
.
link
=&
mn
;
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
));
#include "dcprotect.h"
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module BTree"
);
}
/*
PER_USE_OR_RETURN(self, NULL);
PER_ALLOW_DEACTIVATION(self);
*/
/*****************************************************************************
Revision Log:
$Log: BTree.c,v $
Revision 1.10 1997/11/13 20:45:51 jim
Fixed some bad return values.
Revision 1.9 1997/11/13 20:38:35 jim
added dcprotect
Revision 1.8 1997/11/03 15:17:53 jim
Fixed stupid bug in has_key methods.
Revision 1.7 1997/10/30 20:58:43 jim
Upped bucket sizes.
Revision 1.6 1997/10/10 18:21:45 jim
Fixed bug in range queries.
Revision 1.5 1997/10/01 02:47:06 jim
Fixed bug in setstate that allocates too much memory.
Revision 1.4 1997/09/17 17:20:32 jim
Fixed bug in deleting members from BTree.
Revision 1.3 1997/09/12 18:35:45 jim
Fixed bug leading to random core dumps.
Revision 1.2 1997/09/10 17:24:47 jim
*** empty log message ***
Revision 1.1 1997/09/08 18:42:21 jim
initial BTree
$Revision 1.1 1997/02/24 23:25:42 jim
$initial
$
*****************************************************************************/
lib/python/SearchIndex/IIBTree.c
deleted
100755 → 0
View file @
b823b5cb
/* $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"
lib/python/SearchIndex/IOBTree.c
deleted
100755 → 0
View file @
b823b5cb
/* $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"
lib/python/SearchIndex/OIBTree.c
deleted
100755 → 0
View file @
b823b5cb
/* $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"
lib/python/SearchIndex/Trie.c
deleted
100644 → 0
View file @
b823b5cb
/***********************************************************
Copyright
Copyright 1997 Digital Creations, L.L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved. Copyright in this software is owned by DCLC,
unless otherwise indicated. Permission to use, copy and
distribute this software is hereby granted, provided that the
above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear. Note that
any product, process or technology described in this software
may be the subject of other Intellectual Property rights
reserved by Digital Creations, L.C. and are not licensed
hereunder.
Trademarks
Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
All other trademarks are owned by their respective companies.
No Warranty
The software is provided "as is" without warranty of any kind,
either express or implied, including, but not limited to, the
implied warranties of merchantability, fitness for a particular
purpose, or non-infringement. This software could include
technical inaccuracies or typographical errors. Changes are
periodically made to the software; these changes will be
incorporated in new editions of the software. DCLC may make
improvements and/or changes in this software at any time
without notice.
Limitation Of Liability
In no event will DCLC be liable for direct, indirect, special,
incidental, economic, cover, or consequential damages arising
out of the use of or inability to use this software even if
advised of the possibility of such damages. Some states do not
allow the exclusion or limitation of implied warranties or
limitation of liability for incidental or consequential
damages, so the above limitation or exclusion may not apply to
you.
If you have questions regarding this software,
contact:
Digital Creations L.L.C.
info@digicool.com
(540) 371-6909
******************************************************************/
static
char
Trie_module_documentation
[]
=
""
"
\n
$Id: Trie.c,v 1.13 1997/09/10 17:27:14 jim Exp $"
;
#define PERSISTENT 1
/* Note that I haven't put ifdefs everywhere they apply yet. */
#ifdef PERSISTENT
# include "cPersistence.h"
#else
# include "ExtensionClass.h"
# define PER_PREVENT_DEACTIVATION(SELF)
# define PER_ALLOW_DEACTIVATION(SELF)
# define PER_CHANGED(O) 0
# define PER_USE_OR_RETURN(O,R)
#endif
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 PyOb(O) ((PyObject*)(O))
#define LIST(O) ((PyListObject*)(O))
#define STRING(O) ((PyStringObject*)(O))
#define PyList_SIZE(O) (((PyListObject*)(O))->ob_size)
static
PyObject
*
py___class__
,
*
py_Trief
;
/* Declarations for objects of type Trie */
typedef
struct
{
#ifdef PERSISTENT
cPersistent_HEAD
#endif
int
min
;
PyObject
*
bins
;
PyObject
*
value
;
}
TrieObject
;
staticforward
PyExtensionClass
TrieType
;
/* ---------------------------------------------------------------- */
#ifdef PERSISTENT
static
PyObject
*
PER_RETURN
(
TrieObject
*
self
,
PyObject
*
r
)
{
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
static
int
PER_INT_RETURN
(
TrieObject
*
self
,
int
r
)
{
PER_ALLOW_DEACTIVATION
(
self
);
return
r
;
}
#else
#define PER_RETURN(SELF,R) R
#define PER_INT_RETURN(SELF,R) R
#endif
static
PyObject
*
Trie___setstate__
(
TrieObject
*
self
,
PyObject
*
args
)
{
PyObject
*
state
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
state
))
return
NULL
;
PER_PREVENT_DEACTIVATION
(
self
);
if
(
state
!=
Py_None
)
{
self
->
value
=
NULL
;
UNLESS
(
PyArg_ParseTuple
(
state
,
"iO|O"
,
&
(
self
->
min
),
&
(
self
->
bins
),
&
(
self
->
value
)))
return
PER_RETURN
(
self
,
NULL
);
if
(
self
->
min
<
0
)
{
self
->
value
=
self
->
bins
;
self
->
bins
=
NULL
;
}
Py_XINCREF
(
self
->
value
);
Py_XINCREF
(
self
->
bins
);
}
Py_INCREF
(
Py_None
);
return
PER_RETURN
(
self
,
Py_None
);
}
static
PyObject
*
Trie___getstate__
(
TrieObject
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
self
->
value
)
if
(
self
->
bins
)
return
PER_RETURN
(
self
,
Py_BuildValue
(
"(iOO)"
,
self
->
min
,
self
->
bins
,
self
->
value
));
else
return
PER_RETURN
(
self
,
Py_BuildValue
(
"(iO)"
,
-
1
,
self
->
value
));
else
if
(
self
->
bins
)
return
PER_RETURN
(
self
,
Py_BuildValue
(
"(iO)"
,
self
->
min
,
self
->
bins
));
Py_INCREF
(
Py_None
);
return
PER_RETURN
(
self
,
Py_None
);
}
#ifdef PERSISTENT
static
PyObject
*
Trie__p___reinit__
(
TrieObject
*
self
,
PyObject
*
args
)
{
/* Note that this implementation is broken, in that it doesn't
account for subclass needs. */
Py_XDECREF
(
self
->
bins
);
Py_XDECREF
(
self
->
value
);
self
->
bins
=
NULL
;
self
->
value
=
NULL
;
self
->
min
=
0
;
self
->
state
=
cPersistent_GHOST_STATE
;
/*printf("r");*/
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
typedef
struct
{
char
*
data
;
int
size
;
}
keybuf
;
static
PyObject
*
getiork
(
TrieObject
*
self
,
PyObject
*
r
,
keybuf
*
buf
,
int
l
,
int
dokeys
)
{
int
i
;
PyObject
*
item
=
0
;
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
self
->
value
)
{
if
(
dokeys
)
{
UNLESS
(
item
=
PyString_FromStringAndSize
(
buf
->
data
,
l
))
return
PER_RETURN
(
self
,
NULL
);
}
else
UNLESS
(
item
=
Py_BuildValue
(
"(s#O)"
,
buf
->
data
,
l
,
self
->
value
))
return
PER_RETURN
(
self
,
NULL
);
i
=
PyList_Append
(
r
,
item
);
Py_DECREF
(
item
);
if
(
i
<
0
)
return
PER_RETURN
(
self
,
NULL
);
}
if
(
l
==
buf
->
size
)
{
buf
->
size
*=
2
;
UNLESS
(
buf
->
data
=
realloc
(
buf
->
data
,
buf
->
size
))
return
PER_RETURN
(
self
,
PyErr_NoMemory
());
}
if
(
self
->
bins
)
{
PyObject
*
bin
;
int
s
,
l1
,
ibin
;
for
(
ibin
=
0
,
l1
=
l
+
1
,
s
=
PyList_SIZE
(
self
->
bins
);
ibin
<
s
;
ibin
++
)
{
bin
=
PyList_GET_ITEM
(
LIST
(
self
->
bins
),
ibin
);
if
(
bin
->
ob_type
==
self
->
ob_type
)
{
buf
->
data
[
l
]
=
self
->
min
+
ibin
;
UNLESS
(
getiork
((
TrieObject
*
)
bin
,
r
,
buf
,
l1
,
dokeys
))
return
PER_RETURN
(
self
,
NULL
);
}
else
if
(
PyTuple_Check
(
bin
))
{
buf
->
data
[
l
]
=
self
->
min
+
ibin
;
UNLESS
(
item
=
PyString_FromStringAndSize
(
buf
->
data
,
l1
))
return
PER_RETURN
(
self
,
NULL
);
ASSIGN
(
item
,
PySequence_Concat
(
item
,
PyTuple_GET_ITEM
(
bin
,
0
)));
if
(
!
dokeys
&&
item
)
ASSIGN
(
item
,
Py_BuildValue
(
"OO"
,
item
,
PyTuple_GET_ITEM
(
bin
,
1
)));
UNLESS
(
item
)
return
PER_RETURN
(
self
,
NULL
);
i
=
PyList_Append
(
r
,
item
);
Py_DECREF
(
item
);
if
(
i
<
0
)
return
PER_RETURN
(
self
,
NULL
);
}
}
}
return
PER_RETURN
(
self
,
r
);
}
static
PyObject
*
iork
(
TrieObject
*
self
,
int
dokeys
)
{
PyObject
*
r
=
0
;
keybuf
buf
;
buf
.
size
=
32
;
UNLESS
(
buf
.
data
=
(
char
*
)
malloc
(
buf
.
size
))
return
PyErr_NoMemory
();
UNLESS
(
r
=
PyList_New
(
0
))
goto
err
;
UNLESS
(
getiork
(
self
,
r
,
&
buf
,
0
,
dokeys
))
goto
err
;
free
(
buf
.
data
);
return
r
;
err:
free
(
buf
.
data
);
Py_XDECREF
(
r
);
return
NULL
;
}
static
PyObject
*
Trie_keys
(
TrieObject
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
return
iork
(
self
,
1
);
}
static
PyObject
*
Trie_cvalues
(
TrieObject
*
self
,
PyObject
*
r
)
{
PER_USE_OR_RETURN
(
self
,
NULL
);
if
(
self
->
value
)
if
(
PyList_Append
(
r
,
self
->
value
)
<
0
)
return
PER_RETURN
(
self
,
NULL
);
if
(
self
->
bins
)
{
PyObject
*
bin
;
int
i
,
s
=
0
;
for
(
i
=
0
,
s
=
PyList_SIZE
(
self
->
bins
);
i
<
s
;
i
++
)
{
bin
=
PyList_GET_ITEM
(
LIST
(
self
->
bins
),
i
);
if
(
bin
->
ob_type
==
self
->
ob_type
)
{
UNLESS
(
Trie_cvalues
((
TrieObject
*
)
bin
,
r
))
return
PER_RETURN
(
self
,
NULL
);
}
else
if
(
PyTuple_Check
(
bin
))
if
(
PyList_Append
(
r
,
PyTuple_GET_ITEM
(
bin
,
1
))
<
0
)
return
PER_RETURN
(
self
,
NULL
);
}
}
return
PER_RETURN
(
self
,
r
);
}
static
PyObject
*
Trie_values
(
TrieObject
*
self
,
PyObject
*
args
)
{
PyObject
*
r
;
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
UNLESS
(
r
=
PyList_New
(
0
))
return
NULL
;
UNLESS
(
Trie_cvalues
(
self
,
r
))
{
Py_DECREF
(
r
);
r
=
NULL
;
}
return
r
;
}
static
PyObject
*
Trie_items
(
TrieObject
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
return
iork
(
self
,
0
);
}
static
int
Trie_cclear
(
TrieObject
*
self
)
{
#ifdef PERSISTENT
int
changed
=
0
;
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
if
(
self
->
value
)
{
Py_DECREF
(
self
->
value
);
self
->
value
=
NULL
;
#ifdef PERSISTENT
changed
=
1
;
#endif
}
if
(
self
->
bins
)
{
PyObject
*
bin
;
int
i
,
s
=
0
;
for
(
i
=
0
,
s
=
PyList_SIZE
(
self
->
bins
);
i
<
s
;
i
++
)
{
bin
=
PyList_GET_ITEM
(
LIST
(
self
->
bins
),
i
);
if
(
bin
->
ob_type
==
self
->
ob_type
)
{
if
(
Trie_cclear
((
TrieObject
*
)
bin
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
}
else
{
Py_INCREF
(
Py_None
);
if
(
PyList_SetItem
(
self
->
bins
,
i
,
Py_None
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
#ifdef PERSISTENT
changed
=
1
;
#endif
}
}
}
#ifdef PERSISTENT
if
(
changed
&&
PER_CHANGED
(
self
)
<
0
)
return
PER_INT_RETURN
(
self
,
-
1
);
#endif
return
PER_INT_RETURN
(
self
,
0
);
}
static
PyObject
*
Trie_clear
(
TrieObject
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
if
(
Trie_cclear
(
self
)
<
0
)
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
struct
PyMethodDef
Trie_methods
[]
=
{
{
"__getstate__"
,
(
PyCFunction
)
Trie___getstate__
,
METH_VARARGS
,
"__getstate__() -- Get the persistent state of the trie"
},
{
"__setstate__"
,
(
PyCFunction
)
Trie___setstate__
,
METH_VARARGS
,
"__setstate__(v) -- Set the persistent state of the trie"
},
#ifdef PERSISTENT
{
"_p___reinit__"
,
(
PyCFunction
)
Trie__p___reinit__
,
METH_VARARGS
,
"_p___reinit__() -- Reinitialize from a newly created copy"
},
#endif
{
"keys"
,
(
PyCFunction
)
Trie_keys
,
METH_VARARGS
,
"keys() -- Get the keys of the trie"
},
{
"values"
,
(
PyCFunction
)
Trie_values
,
METH_VARARGS
,
"values() -- Get the values of the trie"
},
{
"items"
,
(
PyCFunction
)
Trie_items
,
METH_VARARGS
,
"items() -- Get the items of the trie"
},
{
"clear"
,
(
PyCFunction
)
Trie_clear
,
METH_VARARGS
,
"clear() -- Remove the items from the trie"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
NotFoundError
(
PyObject
*
key
)
{
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
PyObject
*
Trie_cget
(
TrieObject
*
self
,
char
*
word
,
PyObject
*
oword
)
{
int
c
;
PyObject
*
bins
,
*
bin
;
PyTypeObject
*
typ
;
PyObject
*
key
;
PER_USE_OR_RETURN
(
self
,
NULL
);
typ
=
self
->
ob_type
;
Py_INCREF
(
self
);
while
(
c
=*
word
++
)
{
if
(
!
(
bins
=
self
->
bins
)
||
c
<
self
->
min
)
goto
not_found
;
c
-=
self
->
min
;
if
(
c
>=
PyList_SIZE
(
bins
))
goto
not_found
;
bin
=
PyList_GET_ITEM
(
LIST
(
bins
),
c
);
Py_INCREF
(
bin
);
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
self
);
if
(
bin
->
ob_type
!=
typ
)
{
if
(
PyTuple_Check
(
bin
)
&&
PyString_Check
((
key
=
PyTuple_GET_ITEM
(
bin
,
0
)))
&&
strcmp
(
word
,
PyString_AS_STRING
(
STRING
(
key
)))
==
0
)
ASSIGN
(
bin
,
PySequence_GetItem
(
bin
,
1
));
else
ASSIGN
(
bin
,
NotFoundError
(
oword
));
return
bin
;
}
self
=
(
TrieObject
*
)
bin
;
PER_USE_OR_RETURN
(
self
,
NULL
);
}
if
(
!
self
->
value
)
{
Py_DECREF
(
self
);
return
PER_RETURN
(
self
,
NotFoundError
(
oword
));
}
bin
=
self
->
value
;
Py_INCREF
(
bin
);
Py_DECREF
(
self
);
return
PER_RETURN
(
self
,
bin
);
not_found:
PER_ALLOW_DEACTIVATION
(
self
);
Py_DECREF
(
self
);
return
NotFoundError
(
oword
);
}
static
int
Trie_cset
(
TrieObject
*
self
,
char
*
word
,
PyObject
*
v
,
PyObject
*
oword
)
{
PyObject
*
bin
=
0
;
int
c
,
r
,
max
;
#ifdef PERSISTENT
int
ch
=
0
;
#endif
PER_USE_OR_RETURN
(
self
,
-
1
);
c
=*
word
++
;
if
(
!
c
)
{
if
(
!
v
&&
!
self
->
value
)
{
NotFoundError
(
oword
);
goto
err
;
}
Py_XINCREF
(
v
);
ASSIGN
(
self
->
value
,
v
);
#ifdef PERSISTENT
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
#endif
return
0
;
}
if
(
!
v
&&
(
!
self
->
bins
||
c
<
self
->
min
||
c
-
self
->
min
>=
PyList_SIZE
(
self
->
bins
))
)
{
NotFoundError
(
oword
);
goto
err
;
}
if
(
!
self
->
bins
)
{
UNLESS
(
self
->
bins
=
PyList_New
(
1
))
goto
err
;
self
->
min
=
c
;
#ifdef PERSISTENT
ch
=
1
;
#endif
}
else
if
(
c
<
self
->
min
)
while
(
c
<
self
->
min
)
{
if
(
PyList_Insert
(
self
->
bins
,
0
,
Py_None
)
<
0
)
goto
err
;
self
->
min
--
;
#ifdef PERSISTENT
ch
=
1
;
#endif
}
else
{
max
=
PyList_SIZE
(
self
->
bins
)
-
1
+
self
->
min
;
if
(
c
>
max
)
while
(
c
>
max
)
{
if
(
PyList_Append
(
self
->
bins
,
Py_None
)
<
0
)
goto
err
;
max
++
;
#ifdef PERSISTENT
ch
=
1
;
#endif
}
}
c
-=
self
->
min
;
bin
=
PyList_GET_ITEM
(
LIST
(
self
->
bins
),
c
);
if
(
!
bin
||
bin
->
ob_type
!=
self
->
ob_type
)
{
PyObject
*
key
;
if
(
!
v
)
if
(
bin
&&
PyTuple_Check
(
bin
)
&&
(
key
=
PyTuple_GET_ITEM
(
bin
,
0
))
&&
PyString_Check
(
key
)
&&
strcmp
(
word
,
PyString_AS_STRING
(
STRING
(
key
)))
==
0
)
{
Py_INCREF
(
Py_None
);
bin
=
Py_None
;
}
else
{
NotFoundError
(
oword
);
goto
err
;
}
else
{
if
(
bin
&&
PyTuple_Check
(
bin
)
&&
(
key
=
PyTuple_GET_ITEM
(
bin
,
0
))
&&
PyString_Check
(
key
)
&&
strcmp
(
word
,
PyString_AS_STRING
(
STRING
(
key
)))
!=
0
)
{
PyObject
*
o
;
o
=
PyTuple_GET_ITEM
(
bin
,
1
);
UNLESS
(
bin
=
PyObject_GetAttr
(
PyOb
(
self
),
py___class__
))
goto
err
;
UNLESS_ASSIGN
(
bin
,
PyObject_CallObject
(
bin
,
NULL
))
goto
err
;
if
(
Trie_cset
((
TrieObject
*
)
bin
,
PyString_AS_STRING
(
STRING
(
key
)),
o
,
oword
)
<
0
||
Trie_cset
((
TrieObject
*
)
bin
,
word
,
v
,
oword
)
<
0
)
goto
err
;
}
else
UNLESS
(
bin
=
Py_BuildValue
(
"sO"
,
word
,
v
))
goto
err
;
}
r
=
PyList_SetItem
(
self
->
bins
,
c
,
bin
);
#ifdef PERSISTENT
if
(
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
#endif
return
r
;
}
r
=
Trie_cset
((
TrieObject
*
)
bin
,
word
,
v
,
oword
);
#ifdef PERSISTENT
if
(
ch
&&
PER_CHANGED
(
self
)
<
0
)
goto
err
;
PER_ALLOW_DEACTIVATION
(
self
);
#endif
return
r
;
err:
Py_XDECREF
(
bin
);
PER_ALLOW_DEACTIVATION
(
self
);
return
-
1
;
}
static
int
Trie_length
(
TrieObject
*
self
)
{
int
i
,
li
,
l
=
0
;
PyObject
*
bin
;
PER_USE_OR_RETURN
(
self
,
-
1
);
if
(
self
->
bins
)
for
(
i
=
PyList_SIZE
(
self
->
bins
);
--
i
>=
0
;
)
{
bin
=
PyList_GET_ITEM
(
LIST
(
self
->
bins
),
i
);
if
(
bin
->
ob_type
==
self
->
ob_type
)
{
li
=
Trie_length
((
TrieObject
*
)
bin
);
if
(
li
<
0
)
return
PER_INT_RETURN
(
self
,
li
);
l
+=
li
;
}
else
if
(
PyTuple_Check
(
bin
))
l
++
;
}
if
(
self
->
value
)
l
++
;
return
PER_INT_RETURN
(
self
,
l
);
}
static
PyObject
*
Trie_subscript
(
TrieObject
*
self
,
PyObject
*
key
)
{
char
*
word
;
if
(
PyString_Check
(
key
))
{
UNLESS
(
word
=
PyString_AsString
(
key
))
return
NULL
;
return
Trie_cget
(
self
,
word
,
key
);
}
PyErr_SetString
(
PyExc_TypeError
,
"Only string keys are allowed for tries."
);
return
NULL
;
}
static
int
Trie_ass_sub
(
TrieObject
*
self
,
PyObject
*
key
,
PyObject
*
v
)
{
char
*
word
;
if
(
PyString_Check
(
key
))
{
UNLESS
(
word
=
PyString_AsString
(
key
))
return
-
1
;
return
Trie_cset
((
TrieObject
*
)
self
,
word
,
v
,
key
);
}
PyErr_SetString
(
PyExc_TypeError
,
"Only string keys are allowed for tries."
);
return
-
1
;
}
static
PyMappingMethods
Trie_as_mapping
=
{
(
inquiry
)
Trie_length
,
/*mp_length*/
(
binaryfunc
)
Trie_subscript
,
/*mp_subscript*/
(
objobjargproc
)
Trie_ass_sub
,
/*mp_ass_subscript*/
};
static
void
Trie_dealloc
(
TrieObject
*
self
)
{
Py_XDECREF
(
self
->
bins
);
Py_XDECREF
(
self
->
value
);
PER_DEL
(
self
);
PyMem_DEL
(
self
);
/*printf("d");*/
}
static
PyObject
*
Trie_getattr
(
TrieObject
*
self
,
PyObject
*
name
)
{
return
Py_FindAttr
(
PyOb
(
self
),
name
);
}
static
PyObject
*
Trie_repr
(
TrieObject
*
self
)
{
PyObject
*
r
;
UNLESS
(
r
=
iork
(
self
,
0
))
return
NULL
;
ASSIGN
(
r
,
PyString_Format
(
py_Trief
,
r
));
return
r
;
}
static
int
Trie_compare
(
TrieObject
*
v
,
TrieObject
*
w
)
{
if
(
v
>
w
)
return
-
1
;
return
w
>
v
;
}
static
PyExtensionClass
TrieType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Trie"
,
/*tp_name*/
sizeof
(
TrieObject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Trie_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
Trie_compare
,
/*tp_compare*/
(
reprfunc
)
Trie_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
Trie_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
Trie_getattr
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
""
,
METHOD_CHAIN
(
Trie_methods
),
};
/* End of code for Trie objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
PyObject
*
spam
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
d
,
*
v
;
int
i
,
s
,
j
;
d
=
PySequence_GetItem
(
args
,
0
);
s
=
PyTuple_Size
(
args
);
for
(
j
=
10000
;
--
j
>=
0
;
)
for
(
i
=
s
;
--
i
>
0
;
)
{
v
=
PyObject_GetItem
(
d
,
PyTuple_GET_ITEM
(
args
,
i
));
Py_XDECREF
(
v
);
}
return
d
;
}
static
struct
PyMethodDef
Triem_methods
[]
=
{
{
"spam"
,
(
PyCFunction
)
spam
,
1
,
""
},
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
/* sentinel */
};
/* Initialization function for the module (*must* be called initTrie) */
void
initTrie
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.13 $"
;
UNLESS
(
ExtensionClassImported
)
return
;
#ifdef PERSISTENT
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
static
PyMethodChain
m
;
m
.
methods
=
TrieType
.
methods
.
methods
;
TrieType
.
methods
.
methods
=
cPersistenceCAPI
->
methods
->
methods
;
TrieType
.
methods
.
link
=&
m
;
TrieType
.
tp_getattro
=
cPersistenceCAPI
->
getattro
;
TrieType
.
tp_setattro
=
cPersistenceCAPI
->
setattro
;
}
else
return
;
#endif
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"Trie"
,
Triem_methods
,
Trie_module_documentation
,
PyOb
(
NULL
),
PYTHON_API_VERSION
);
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"Trie"
,
TrieType
);
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
py___class__
=
PyString_FromString
(
"__class__"
);
py_Trief
=
PyString_FromString
(
"Trie(%s)"
);
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module Trie"
);
}
/*****************************************************************************
Revision Log:
$Log: Trie.c,v $
Revision 1.13 1997/09/10 17:27:14 jim
Fixed doc string.
Revision 1.12 1997/07/18 14:43:24 jim
Added cPersistent, PER_DEL invocation to destructor.
Fixed memory leaks in cset.
Revision 1.11 1997/07/17 14:50:57 jim
Got rid of some unreferenced vars.
Revision 1.10 1997/06/06 19:36:36 jim
Fixed major bug in (de)activation control logic.
Revision 1.9 1997/05/19 17:49:35 jim
Added logic to disable deactivation during methods. This sort of
logic will be needed for any C-based persistent object.
Revision 1.8 1997/05/08 21:09:49 jim
Added clear method.
Revision 1.7 1997/04/22 00:13:58 jim
Changed to use new cPersistent header.
Revision 1.6 1997/04/03 15:53:48 jim
Fixed bug in reinitialization code.
Revision 1.5 1997/03/20 19:30:04 jim
Major rewrite to use more efficient data structure. In particular,
try to avoid one-element tries by storing partial-key/value tuples
instead of sub-tries.
Revision 1.4 1997/03/17 23:23:09 jim
Fixed reinit bug.
Revision 1.3 1997/03/17 23:17:30 jim
Added reinit method. Need something better than this.
Fixed dealloc bug.
Revision 1.2 1997/03/17 21:29:39 jim
Moved external imports before module initialization to give
better error handling.
Revision 1.1 1997/03/14 23:20:28 jim
initial
*****************************************************************************/
lib/python/SearchIndex/WordSequence.c
deleted
100644 → 0
View file @
b823b5cb
#include "Python.h"
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
static
PyObject
*
next_word
();
static
void
WordSequence_reset
();
static
PyObject
*
default_wordletters
;
static
PyObject
*
string_lower
;
typedef
struct
{
PyObject_HEAD
PyObject
*
text
,
*
synstop
,
*
wordletters
;
char
*
ctext
,
*
here
,
*
end
,
*
cwordletters
;
int
index
;
}
WordSequence
;
staticforward
PyTypeObject
WordSequenceType
;
static
WordSequence
*
newWordSequence
(
PyObject
*
text
,
PyObject
*
synstop
,
PyObject
*
wordletters
)
{
WordSequence
*
self
;
PyObject
*
t
;
PyObject
*
lower_text
;
UNLESS
(
self
=
PyObject_NEW
(
WordSequence
,
&
WordSequenceType
))
{
return
NULL
;
}
self
->
synstop
=
synstop
;
Py_XINCREF
(
self
->
synstop
);
if
(
wordletters
==
NULL
)
wordletters
=
default_wordletters
;
Py_INCREF
(
wordletters
);
self
->
wordletters
=
wordletters
;
self
->
cwordletters
=
PyString_AsString
(
self
->
wordletters
);
UNLESS
(
t
=
PyTuple_New
(
1
))
{
return
NULL
;
}
Py_INCREF
(
text
);
PyTuple_SET_ITEM
((
PyTupleObject
*
)
t
,
0
,
text
);
UNLESS
(
lower_text
=
PyObject_CallObject
(
string_lower
,
t
))
{
Py_DECREF
(
t
);
return
NULL
;
}
Py_DECREF
(
t
);
self
->
text
=
lower_text
;
self
->
ctext
=
self
->
here
=
PyString_AsString
(
lower_text
);
self
->
end
=
self
->
here
+
PyString_Size
(
lower_text
);
self
->
index
=
-
1
;
return
self
;
}
static
void
WordSequence_dealloc
(
WordSequence
*
self
)
{
Py_XDECREF
(
self
->
text
);
Py_XDECREF
(
self
->
synstop
);
Py_XDECREF
(
self
->
wordletters
);
PyMem_DEL
(
self
);
}
static
int
WordSequence_length
(
WordSequence
*
self
)
{
PyObject
*
res
;
WordSequence_reset
(
self
);
while
(
PyString_Check
(
res
=
next_word
(
self
)))
{
Py_DECREF
(
res
);
self
->
index
++
;
}
if
(
res
==
NULL
)
{
return
-
1
;
}
return
self
->
index
+
1
;
}
static
PyObject
*
WordSequence_concat
(
WordSequence
*
self
,
PyObject
*
other
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Cannot concatenate WordSequences."
);
return
NULL
;
}
static
PyObject
*
WordSequence_repeat
(
WordSequence
*
self
,
long
n
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Cannot repeat WordSequences."
);
return
NULL
;
}
static
PyObject
*
check_synstop
(
WordSequence
*
self
,
PyObject
*
word
)
{
PyObject
*
value
;
char
*
cword
;
int
len
;
cword
=
PyString_AsString
(
word
);
len
=
PyString_Size
(
word
)
-
1
;
for
(
len
=
PyString_Size
(
word
);
(
--
len
>=
0
)
&&
!
memchr
(
"abcdefghijklmnopqrstuvwxyz"
,
cword
[
len
],
26
);
);
if
(
len
<
0
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
Py_INCREF
(
word
);
if
(
self
->
synstop
==
NULL
)
return
word
;
while
((
value
=
PyObject_GetItem
(
self
->
synstop
,
word
))
&&
PyString_Check
(
value
))
{
ASSIGN
(
word
,
value
);
}
if
(
value
==
NULL
)
{
PyErr_Clear
();
return
word
;
}
return
value
;
/* Which must be None! */
}
#define MAX_WORD 256
static
PyObject
*
next_word
(
WordSequence
*
self
)
{
char
wbuf
[
MAX_WORD
];
char
*
p
,
*
end
,
*
here
,
*
b
;
int
size
=
PyString_Size
(
self
->
wordletters
),
i
=
0
;
PyObject
*
pyword
,
*
res
;
here
=
self
->
here
;
end
=
self
->
end
;
b
=
wbuf
;
while
(
here
<
end
)
{
/* skip hyphens */
if
((
i
>
0
)
&&
(
*
here
==
'-'
))
{
while
((
*++
here
<=
' '
)
&&
(
here
<
end
));
continue
;
}
/* Check to see if this character is part of a word */
if
(
memchr
(
self
->
cwordletters
,
*
here
,
size
))
{
if
(
i
++
<
MAX_WORD
)
*
b
++
=
*
here
;
}
else
if
(
i
!=
0
)
{
if
(
i
>=
MAX_WORD
)
{
/* Ridiculously long word! */
i
=
0
;
b
=
wbuf
;
here
++
;
continue
;
}
/* Check for and skip a phone number (I know it's lame :) */
if
(
i
==
8
&&
wbuf
[
0
]
>=
'0'
&&
wbuf
[
0
]
<=
'9'
&&
wbuf
[
1
]
>=
'0'
&&
wbuf
[
1
]
<=
'9'
&&
wbuf
[
2
]
>=
'0'
&&
wbuf
[
2
]
<=
'9'
&&
wbuf
[
3
]
==
'-'
&&
wbuf
[
4
]
>=
'0'
&&
wbuf
[
4
]
<=
'9'
&&
wbuf
[
5
]
>=
'0'
&&
wbuf
[
5
]
<=
'9'
&&
wbuf
[
6
]
>=
'0'
&&
wbuf
[
6
]
<=
'9'
&&
wbuf
[
7
]
>=
'0'
&&
wbuf
[
7
]
<=
'9'
)
{
i
=
0
;
b
=
wbuf
;
here
++
;
continue
;
}
UNLESS
(
pyword
=
PyString_FromStringAndSize
(
wbuf
,
i
))
{
self
->
here
=
here
;
return
NULL
;
}
/* We've found the end of a word */
UNLESS
(
res
=
check_synstop
(
self
,
pyword
))
{
self
->
here
=
here
;
Py_DECREF
(
pyword
);
return
NULL
;
}
if
(
res
!=
Py_None
)
{
self
->
here
=
here
;
Py_DECREF
(
pyword
);
return
res
;
}
/* The word is a stopword, so ignore it */
Py_DECREF
(
res
);
Py_DECREF
(
pyword
);
i
=
0
;
b
=
wbuf
;
}
here
++
;
}
self
->
here
=
here
;
/* We've reached the end of the string */
if
(
i
==
0
)
{
/* No words */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
UNLESS
(
pyword
=
PyString_FromStringAndSize
(
wbuf
,
i
))
{
return
NULL
;
}
res
=
check_synstop
(
self
,
pyword
);
Py_DECREF
(
pyword
);
return
res
;
}
static
void
WordSequence_reset
(
WordSequence
*
self
)
{
self
->
here
=
self
->
ctext
;
self
->
index
=
-
1
;
}
static
PyObject
*
WordSequence_item
(
WordSequence
*
self
,
int
i
)
{
PyObject
*
word
=
NULL
;
if
(
i
<=
self
->
index
)
{
WordSequence_reset
(
self
);
}
while
(
self
->
index
<
i
)
{
Py_XDECREF
(
word
);
UNLESS
(
word
=
next_word
(
self
))
{
return
NULL
;
}
if
(
word
==
Py_None
)
{
Py_DECREF
(
word
);
PyErr_SetString
(
PyExc_IndexError
,
"WordSequence index out of range"
);
return
NULL
;
}
self
->
index
++
;
}
return
word
;
}
static
PyObject
*
WordSequence_slice
(
WordSequence
*
self
,
int
i
,
int
j
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Cannot slice WordSequences."
);
return
NULL
;
}
static
PySequenceMethods
WordSequence_as_sequence
=
{
(
inquiry
)
WordSequence_length
,
/*sq_length*/
(
binaryfunc
)
WordSequence_concat
,
/*sq_concat*/
(
intargfunc
)
WordSequence_repeat
,
/*sq_repeat*/
(
intargfunc
)
WordSequence_item
,
/*sq_item*/
(
intintargfunc
)
WordSequence_slice
,
/*sq_slice*/
(
intobjargproc
)
0
,
/*sq_ass_item*/
(
intintobjargproc
)
0
,
/*sq_ass_slice*/
};
static
int
next_word_pos
(
WordSequence
*
self
,
char
**
start
,
char
**
end
)
{
int
size
=
PyString_Size
(
self
->
wordletters
),
res
=
-
1
;
PyObject
*
pyword
=
NULL
,
*
synstop
=
NULL
;
char
*
tmp_ptr
;
*
start
=
*
end
=
NULL
;
while
(
self
->
here
<
self
->
end
)
{
/* skip hyphens */
if
((
*
start
!=
NULL
)
&&
(
*
self
->
here
==
'-'
))
{
/* If this isn't a valid hyphenated region, we'll want
* to know where the end of the word is later.
*/
*
end
=
self
->
here
;
tmp_ptr
=
*
end
=
self
->
here
;
while
((
*
(
++
tmp_ptr
)
<=
' '
)
&&
(
tmp_ptr
<
self
->
end
));
if
((
tmp_ptr
<
self
->
end
)
&&
(
tmp_ptr
-
self
->
here
)
>
1
)
{
self
->
here
=
tmp_ptr
;
}
}
/* Check to see if this character is part of a word */
if
(
memchr
(
self
->
cwordletters
,
*
self
->
here
,
size
))
{
/* The character is part of a word. If we don't have
* a start position for the word, this must be the
* first character; save a pointer to it if so.
*/
if
(
*
start
==
NULL
)
{
*
start
=
self
->
here
;
}
if
(
*
end
!=
NULL
)
{
/* This must be valid hyphenated word, so reset the end */
*
end
=
NULL
;
}
}
else
if
(
*
start
!=
NULL
)
{
/* We've found the end of a word */
/* See if we already have an end for the word */
if
(
*
end
==
NULL
)
{
*
end
=
self
->
here
;
}
UNLESS
(
pyword
=
PyString_FromStringAndSize
(
*
start
,
*
end
-
*
start
))
{
return
-
1
;
}
UNLESS
(
synstop
=
check_synstop
(
self
,
pyword
))
{
res
=
-
1
;
goto
finally
;
}
if
(
synstop
!=
Py_None
)
{
/* We've found a word. Set the end and return */
*
end
=
self
->
here
;
res
=
1
;
goto
finally
;
}
/* The word is a stopword, so ignore it */
*
start
=
NULL
;
Py_DECREF
(
synstop
);
Py_DECREF
(
pyword
);
}
self
->
here
++
;
}
/* We've reached the end of the string */
if
(
*
start
==
NULL
)
{
/* No words */
res
=
0
;
goto
finally
;
}
*
end
=
self
->
here
;
UNLESS
(
pyword
=
PyString_FromStringAndSize
(
*
start
,
*
end
-
*
start
))
{
goto
finally
;
}
UNLESS
(
synstop
=
check_synstop
(
self
,
pyword
))
{
res
=
-
1
;
goto
finally
;
}
if
(
synstop
!=
Py_None
)
{
res
=
1
;
goto
finally
;
}
res
=
0
;
finally:
Py_XDECREF
(
pyword
);
Py_XDECREF
(
synstop
);
return
res
;
}
static
PyObject
*
WordSequence_pos
(
WordSequence
*
self
,
PyObject
*
args
)
{
char
*
start
,
*
end
;
int
res
,
i
;
UNLESS
(
PyArg_Parse
(
args
,
"i"
,
&
i
))
{
return
NULL
;
}
if
(
i
<=
self
->
index
)
{
WordSequence_reset
(
self
);
}
while
(
self
->
index
<
i
)
{
res
=
next_word_pos
(
self
,
&
start
,
&
end
);
if
(
res
>
0
)
{
self
->
index
++
;
continue
;
}
if
(
res
==
0
)
{
PyErr_SetString
(
PyExc_IndexError
,
"WordSequence index out of range"
);
}
return
NULL
;
}
return
Py_BuildValue
(
"(ii)"
,
start
-
self
->
ctext
,
end
-
self
->
ctext
);
}
static
struct
PyMethodDef
WordSequence_methods
[]
=
{
{
"pos"
,
(
PyCFunction
)
WordSequence_pos
,
0
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
WordSequence_getattr
(
WordSequence
*
self
,
char
*
name
)
{
return
Py_FindMethod
(
WordSequence_methods
,
(
PyObject
*
)
self
,
name
);
}
static
char
WordSequenceType__doc__
[]
=
""
;
static
PyTypeObject
WordSequenceType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"WordSequence"
,
/*tp_name*/
sizeof
(
WordSequence
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
WordSequence_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
WordSequence_getattr
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
&
WordSequence_as_sequence
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
/* Space for future expansion */
0L
,
0L
,
0L
,
0L
,
WordSequenceType__doc__
/* Documentation string */
};
static
PyObject
*
get_WordSequence
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
text
=
NULL
,
*
doc
,
*
synstop
=
NULL
,
*
wordletters
=
NULL
,
*
res
=
NULL
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|OO"
,
&
doc
,
&
synstop
,
&
wordletters
))
{
goto
finally
;
}
UNLESS
(
text
=
PyObject_Str
(
doc
))
{
goto
finally
;
}
if
(
wordletters
&&
!
PyString_Check
(
wordletters
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Thirst argument to WordSequence "
"must be string"
);
goto
finally
;
}
res
=
(
PyObject
*
)
newWordSequence
(
text
,
synstop
,
wordletters
);
finally:
Py_XDECREF
(
text
);
return
res
;
}
static
struct
PyMethodDef
WordSequence_module_methods
[]
=
{
{
"WordSequence"
,
(
PyCFunction
)
get_WordSequence
,
1
,
""
},
{
NULL
,
NULL
}
};
static
char
WordSequence_module_documentation
[]
=
"Parse source strings into sequences of words
\n
"
"
\n
"
"for use in an inverted index
\n
"
"
\n
"
"$Id: WordSequence.c,v 1.9 1997/07/31 22:31:58 jim Exp $
\n
"
;
void
initWordSequence
()
{
PyObject
*
m
,
*
string
;
UNLESS
(
default_wordletters
=
PyString_FromString
(
"abcdefghijklmnopqrstuvwxyz0123456789/"
))
{
return
;
}
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"WordSequence"
,
WordSequence_module_methods
,
WordSequence_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
string
=
PyImport_ImportModule
(
"string"
);
string_lower
=
PyObject_GetAttrString
(
string
,
"lower"
);
Py_INCREF
(
string_lower
);
Py_DECREF
(
string
);
if
(
PyErr_Occurred
())
{
Py_FatalError
(
"can't initialize module WordSequence"
);
}
}
lib/python/SearchIndex/intSet.c
deleted
100644 → 0
View file @
b823b5cb
/***********************************************************
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.5 1997/11/13 20:47:13 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
;
PER_PREVENT_DEACTIVATION
(
self
);
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
(
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
)
{
/* Note that this implementation is broken, in that it doesn't
account for subclass needs. */
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"
},
{
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
),
};
static
struct
PyMethodDef
module_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
void
initintSet
()
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.5 $"
;
UNLESS
(
ExtensionClassImported
)
return
;
if
(
cPersistenceCAPI
=
PyCObject_Import
(
"cPersistence"
,
"CAPI"
))
{
static
PyMethodChain
m
;
m
.
methods
=
intSetType
.
methods
.
methods
;
intSetType
.
methods
.
methods
=
cPersistenceCAPI
->
methods
->
methods
;
intSetType
.
methods
.
link
=&
m
;
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.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 ***
**************************************************************************/
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