Commit 58112635 authored by Tim Peters's avatar Tim Peters

Fleshed out the existing text, reorganized, and added a blurb about the

new MULTI_INT_UNION.
parent 73e5a696
This document provides information for developers who maintain or This document provides information for developers who maintain or
extend BTrees. extend BTrees.
Macros
======
BTrees are defined using a "template", roughly akin to a a C++ BTrees are defined using a "template", roughly akin to a a C++
template. To create a new family of BTrees, create a source file that template. To create a new family of BTrees, create a source file that
defined macros used to handle differences in key and value types: defines macros used to handle differences in key and value types:
MASTER_ID provides a string to hold an RCS/CVS Id key to be included
in compiled binaries.
MOD_NAME_PREFIX provides the prefix used for the module. This gets Configuration Macros
used to generate type names and the internal module name string.
DEFAULT_MAX_BUCKET_SIZE The maximum bucket size. Someday this will MASTER_ID
be tunable on BTree instances. A string to hold an RCS/CVS Id key to be included in compiled binaries.
DEFAULT_MAX_BTREE_SIZE The maximum btree size (number of MOD_NAME_PREFIX
children). Someday this will be tunable on BTree instances. A string (like "IO" or "OO") that provides the prefix used for the
module. This gets used to generate type names and the internal module
name string.
KEY_TYPE The C type declaration for the key data (e.g. "int", DEFAULT_MAX_BUCKET_SIZE
"PyObject *"). An int giving the maximum bucket size (number of key/value pairs).
When a bucket gets larger than this due to an insertion *into a BTREE*,
it splits. Inserting into a bucket directly doesn't split, and
functions that produce a bucket output (e.g., union()) also have no
bound on how large a bucket may get. Someday this will be tunable
on BTree instances.
KEY_CHECK(K) Macro that tests whether a Python Object, K, can be DEFAULT_MAX_BTREE_SIZE
converted to the (C) key type (KEY_TYPE). This macro should return a An int giving the maximum size (number of children) of an internal
bollean. An exception will generally be raised if this returns false. btree node. Someday this will be tunable on BTree instances.
TEST_KEY(K, T) Compares (ala Python cmp) K & T, where K & T are C
data values (of type KEY_TYPE). Returns -1 for K < T, 0 for K == T,
or -1 if K > T.
DECREF_KEY(K) DECREFs the key of KEY_TYPE is PyObject* or is a no Macros for Keys
op.
INCREF_KEY(K) DECREFs the key of KEY_TYPE is PyObject* or is a no KEY_TYPE
op. The C type declaration for keys (e.g., int or PyObject*).
COPY_KEY(K, E) Copy a key's value from E to K. Note that this KEY_CHECK(K)
doesn't INCREF when KEY_TYPE is PyObject*. Tests whether the PyObject* K can be converted to the (C) key type
(KEY_TYPE). The macro should return a boolean (zero for false,
non-zero for true). When it returns false, its caller should probably
set a TypeError exception.
COPY_KEY_TO_OBJECT(O, K) Sets the PyObject* O to a PyObject* TEST_KEY(K, T)
representation of K. Note that this is a new reference, so we INCREF Like Python's cmp(). Compares K(ey) to T(arget), where K & T are C
when KEY_TYPE is PyObject*. data values of type KEY_TYPE). Return an int
< 0 if K < T
== 0 if K == T
> 0 if K > T
COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) Copy an rgument to the target DECREF_KEY(K)
without creating a new reference to ARG. If this can't be done, set K is a value of KEY_TYPE. If KEY_TYPE is a flavor of PyObject*, write
a Python error and set status to 0. If there is no error, status is this to do Py_DECREF(K). Else (e.g., KEY_TYPE is int) make it a nop.
unchanged.
INCREF_KEY(K)
K is a value of KEY_TYPE. If KEY_TYPE is a flavor of PyObject*, write
this to do Py_INCREF(K). Else (e.g., KEY_TYPE is int) make it a nop.
COPY_KEY(K, E)
Like K=E. Copy a key from E to K, both of KEY_TYPE. Note that this
doesn't decref K or incref E when KEY_TYPE is a PyObject*; the caller
is responsible for keeping refcounts straight.
VALUE_TYPE The C type declaration for the value data (e.g. "int", COPY_KEY_TO_OBJECT(O, K)
"PyObject *"). Roughly like O=K. O is a PyObject*, and the macro must build a Python
object form of K, assign it to O, and ensure that O owns the reference
to its new value. It may do this by creating a new Python object based
on K (e.g., PyInt_FromLong(K) when KEY_TYPE is int), or simply by doing
Py_INCREF(K) if KEY_TYPE is a PyObject*.
TEST_VALUE(K, T) Compares (ala Python cmp) K & T, where K & T are C COPY_KEY_FROM_ARG(TARGET, ARG, STATUS)
data values (of type VALUE_TYPE). Returns -1 for K < T, 0 for K == T, Copy an argument to the target without creating a new reference to ARG.
or -1 if K > T. ARG is a PyObject*, and TARGET is of type KEY_TYPE. If this can't be
done (for example, KEY_CHECK(ARG) returns false), set a Python error
and set status to 0. If there is no error, leave status alone.
DECREF_VALUE(K) DECREFs the value of VALUE_TYPE is PyObject* or is a no
op.
INCREF_VALUE(K) DECREFs the value of VALUE_TYPE is PyObject* or is a no Macros for Values
op.
COPY_VALUE(K, E) Copy a value's value from E to K. Note that this VALUE_TYPE
doesn't INCREF when VALUE_TYPE is PyObject*. The C type declaration for values (e.g., int or PyObject*).
COPY_VALUE_TO_OBJECT(O, K) Sets the PyObject* O to a PyObject* TEST_VALUE(K, T)
representation of K. Note that this is a new reference, so we INCREF Like TEST_KEY, except applied to values of VALUE_TYPE.
when VALUE_TYPE is PyObject*.
COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) Copy an rgument to the target DECREF_VALUE(K)
without creating a new reference to ARG. If this can't be done, set Like DECREF_KEY, except applied to values of VALUE_TYPE.
a Python error and set status to 0. If there is no error, status is
unchanged.
NORMALIZE_VALUE(V, MIN) Normalize the value, V, using the parameter INCREF_VALUE(K)
MIN. This almost vertainly a YAGNI. It is a no op for most Like INCREF_KEY, except applied to values of VALUE_TYPE.
types. For integers, V is replaced by V/MIN only if MIN > 0.
MERGE_DEFAULT is a macro that should be set to the default value for COPY_VALUE(K, E)
sets when sets are are merged with mappings via weighed union or Like COPY_KEY, except applied to values of VALUE_TYPE.
intersection.
MERGE(O1, w1, O2, w2) This macro performs a weighted merge of two COPY_VALUE_TO_OBJECT(O, K)
values, O1 and O2 using weights w1 and w2. Note that weighted unions Like COPY_KEY_TO_OBJECT, except applied to values of VALUE_TYPE.
and intersections are not enabled if this macro is undefined.
MERGE_WEIGHT(O, w) Computes a weighted value for O. This is used for COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS)
"filling out" weighted unions. Like COPY_KEY_FROM_ARG, except applied to values of VALUE_TYPE.
NORMALIZE_VALUE(V, MIN)
Normalize the value, V, using the parameter MIN. This is almost
certainly a YAGNI. It is a no op for most types. For integers, V is
replaced by V/MIN only if MIN > 0.
Macros for Set Operations
MERGE_DEFAULT
A value of VALUE_TYPE specifying the value to associate with set
elements when sets are merged with mappings via weighed union or
weighted intersection.
MERGE(O1, w1, O2, w2)
Performs a weighted merge of two values, O1 and O2, using weights w1
and w2. The result must be of VALUE_TYPE. Note that weighted unions
and weighted intersections are not enabled if this macro is left
undefined.
MERGE_WEIGHT(O, w)
Computes a weighted value for O. The result must be of VALUE_TYPE.
This is used for "filling out" weighted unions, i.e. to compute a
weighted value for keys that appear in only one of the input
mappings. If left undefined, MERGE_WEIGHT defaults to
#define MERGE_WEIGHT(O, w) (O)
MULTI_INT_UNION
The value doesn't matter. If defined, SetOpTemplate.c compiles
code for a multiunion() function (compute a union of many input sets
at high speed). This currently makes sense only for II sets, so
only _IIBTree.c defines it.
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment