Skip to content

Commit

Permalink
Merge 3cbf0dc into 87599a7
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Mar 5, 2020
2 parents 87599a7 + 3cbf0dc commit 15f9350
Show file tree
Hide file tree
Showing 57 changed files with 7,216 additions and 452 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ script:
- python --version
- |
if [[ "$WITH_COVERAGE" == "1" ]]; then
coverage run -m zope.testrunner --test-path=. --auto-color --auto-progress --verbose
python -m coverage run -m zope.testrunner --test-path=. --auto-color --auto-progress --verbose
else
zope-testrunner --test-path=. --auto-color --auto-progress --verbose
python -m zope.testrunner --test-path=. --auto-color --auto-progress --verbose
fi
- python setup.py -q bdist_wheel

after_success:
- if [[ "$WITH_COVERAGE" == "1" ]]; then coveralls; fi
- if [[ "$WITH_COVERAGE" == "1" ]]; then python -m coveralls; fi
- |
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
# macpython 3.5 doesn't support recent TLS protocols which causes twine
Expand Down
139 changes: 112 additions & 27 deletions BTrees/BTreeModuleTemplate.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,28 +77,117 @@ static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;}
#error "PY_LONG_LONG required but not defined"
#endif

static int
longlong_handle_overflow(PY_LONG_LONG result, int overflow)
{
if (overflow)
{
/* Python 3 tends to have an exception already set, Python 2 not so much */
if (!PyErr_Occurred())
PyErr_SetString(PyExc_OverflowError, "couldn't convert integer to C long long");
return 0;
}
else if (result == -1 && PyErr_Occurred())
/* An exception has already been raised. */
return 0;
return 1;
}


#ifdef NEED_LONG_LONG_KEYS

#if defined(ZODB_UNSIGNED_VALUE_INTS) || defined(ZODB_UNSIGNED_KEY_INTS)
static int
ulonglong_check(PyObject *ob)
{
#ifndef PY3K
if (PyInt_Check(ob))
{
long tmp;
tmp = PyInt_AS_LONG(ob);
if (tmp < 0) {
PyErr_SetString(PyExc_OverflowError, "unsigned value less than 0");
return 0;
}
return 1;
}
#endif

if (!PyLong_Check(ob))
{
return 0;
}

if (PyLong_AsUnsignedLongLong(ob) == (unsigned long long)-1 && PyErr_Occurred())
{
return 0;
}
return 1;
}
#endif /* defined(ZODB_UNSIGNED_VALUE_INTS) || defined(ZODB_UNSIGNED_KEY_INTS) */

static int
longlong_check(PyObject *ob)
{
if (INT_CHECK(ob))
#ifndef PY3K
/* Python's small integers can always fit into a long long. */
if (PyInt_Check(ob))
return 1;
#endif

if (PyLong_Check(ob)) {
int overflow;
(void)PyLong_AsLongLongAndOverflow(ob, &overflow);
if (overflow)
goto overflow;
return 1;
PY_LONG_LONG result;
result = PyLong_AsLongLongAndOverflow(ob, &overflow);
return longlong_handle_overflow(result, overflow);
}
return 0;
overflow:
PyErr_SetString(PyExc_ValueError,
"longlong_check: long integer out of range");
return 0;
}

#endif

#if defined(ZODB_UNSIGNED_VALUE_INTS) || defined(ZODB_UNSIGNED_KEY_INTS)
static PyObject *
ulonglong_as_object(unsigned PY_LONG_LONG val)
{
if ((val > LONG_MAX))
return PyLong_FromUnsignedLongLong(val);
return UINT_FROM_LONG((unsigned long)val);
}

static int
ulonglong_convert(PyObject *ob, unsigned PY_LONG_LONG *value)
{
unsigned PY_LONG_LONG val;

#ifndef PY3K
if (PyInt_Check(ob))
{
long tmp;
tmp = PyInt_AS_LONG(ob);
if (tmp < 0) {
PyErr_SetString(PyExc_OverflowError, "unsigned value less than 0");
return 0;
}
(*value) = (unsigned PY_LONG_LONG)tmp;
return 1;
}
#endif

if (!PyLong_Check(ob))
{
PyErr_SetString(PyExc_TypeError, "expected integer key");
return 0;
}

val = PyLong_AsUnsignedLongLong(ob);
if (val == (unsigned long long)-1 && PyErr_Occurred())
return 0;
(*value) = val;
return 1;
}
#endif /* defined(ZODB_UNSIGNED_VALUE_INTS) || defined(ZODB_UNSIGNED_KEY_INTS) */

static PyObject *
longlong_as_object(PY_LONG_LONG val)
{
Expand All @@ -107,10 +196,11 @@ longlong_as_object(PY_LONG_LONG val)
return INT_FROM_LONG((long)val);
}


static int
longlong_convert(PyObject *ob, PY_LONG_LONG *value)
{
PY_LONG_LONG val;
int overflow;
#ifndef PY3K
if (PyInt_Check(ob))
{
Expand All @@ -124,20 +214,15 @@ longlong_convert(PyObject *ob, PY_LONG_LONG *value)
PyErr_SetString(PyExc_TypeError, "expected integer key");
return 0;
}
else
val = PyLong_AsLongLongAndOverflow(ob, &overflow);
if (!longlong_handle_overflow(val, overflow))
{
PY_LONG_LONG val;
int overflow;
val = PyLong_AsLongLongAndOverflow(ob, &overflow);
if (overflow)
goto overflow;
(*value) = val;
return 1;
return 0;
}
overflow:
PyErr_SetString(PyExc_ValueError, "long integer out of range");
return 0;
(*value) = val;
return 1;
}

#endif /* NEED_LONG_LONG_SUPPORT */


Expand Down Expand Up @@ -424,30 +509,30 @@ static char *search_keywords[] = {"min", "max",

static struct PyMethodDef module_methods[] = {
{"difference", (PyCFunction) difference_m, METH_VARARGS,
"difference(o1, o2) -- "
"difference(o1, o2)\n"
"compute the difference between o1 and o2"
},
{"union", (PyCFunction) union_m, METH_VARARGS,
"union(o1, o2) -- compute the union of o1 and o2\n"
"union(o1, o2)\ncompute the union of o1 and o2\n"
},
{"intersection", (PyCFunction) intersection_m, METH_VARARGS,
"intersection(o1, o2) -- "
"intersection(o1, o2)\n"
"compute the intersection of o1 and o2"
},
#ifdef MERGE
{"weightedUnion", (PyCFunction) wunion_m, METH_VARARGS,
"weightedUnion(o1, o2 [, w1, w2]) -- compute the union of o1 and o2\n"
"weightedUnion(o1, o2 [, w1, w2])\ncompute the union of o1 and o2\n"
"\nw1 and w2 are weights."
},
{"weightedIntersection", (PyCFunction) wintersection_m, METH_VARARGS,
"weightedIntersection(o1, o2 [, w1, w2]) -- "
"weightedIntersection(o1, o2 [, w1, w2])\n"
"compute the intersection of o1 and o2\n"
"\nw1 and w2 are weights."
},
#endif
#ifdef MULTI_INT_UNION
{"multiunion", (PyCFunction) multiunion_m, METH_VARARGS,
"multiunion(seq) -- compute union of a sequence of integer sets.\n"
"multiunion(seq)\ncompute union of a sequence of integer sets.\n"
"\n"
"Each element of seq must be an integer set, or convertible to one\n"
"via the set iteration protocol. The union returned is an IISet."
Expand Down
113 changes: 113 additions & 0 deletions BTrees/IUBTree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
##############################################################################
#
# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################

__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
'IUBucket', 'IUSet', 'IUBTree', 'IUTreeSet',
'union', 'intersection', 'difference',
'weightedUnion', 'weightedIntersection', 'multiunion',
)

from zope.interface import moduleProvides

from .Interfaces import IIntegerUnsignedBTreeModule
from ._base import Bucket
from ._base import MERGE
from ._base import MERGE_WEIGHT_numeric
from ._base import MERGE_DEFAULT_int
from ._base import Set
from ._base import Tree as BTree
from ._base import TreeSet
from ._base import _TreeIterator
from ._base import difference as _difference
from ._base import intersection as _intersection
from ._base import multiunion as _multiunion
from ._base import set_operation as _set_operation
from ._base import to_int as _to_key
from ._base import to_uint as _to_value
from ._base import union as _union
from ._base import weightedIntersection as _weightedIntersection
from ._base import weightedUnion as _weightedUnion
from ._base import _fix_pickle
from ._compat import import_c_extension

_BUCKET_SIZE = 120
_TREE_SIZE = 500
using64bits = False


class IUBucketPy(Bucket):
_to_key = _to_key
_to_value = _to_value
MERGE = MERGE
MERGE_WEIGHT = MERGE_WEIGHT_numeric
MERGE_DEFAULT = MERGE_DEFAULT_int


class IUSetPy(Set):
_to_key = _to_key
MERGE = MERGE
MERGE_WEIGHT = MERGE_WEIGHT_numeric
MERGE_DEFAULT = MERGE_DEFAULT_int


class IUBTreePy(BTree):
max_leaf_size = _BUCKET_SIZE
max_internal_size = _TREE_SIZE
_to_key = _to_key
_to_value = _to_value
MERGE = MERGE
MERGE_WEIGHT = MERGE_WEIGHT_numeric
MERGE_DEFAULT = MERGE_DEFAULT_int


class IUTreeSetPy(TreeSet):
max_leaf_size = _BUCKET_SIZE
max_internal_size = _TREE_SIZE
_to_key = _to_key
MERGE = MERGE
MERGE_WEIGHT = MERGE_WEIGHT_numeric
MERGE_DEFAULT = MERGE_DEFAULT_int


class IUTreeIteratorPy(_TreeIterator):
pass


# Can't declare forward refs, so fix up afterwards:

IUBucketPy._mapping_type = IUBucketPy._bucket_type = IUBucketPy
IUBucketPy._set_type = IUSetPy

IUSetPy._mapping_type = IUBucketPy
IUSetPy._set_type = IUSetPy._bucket_type = IUSetPy

IUBTreePy._mapping_type = IUBTreePy._bucket_type = IUBucketPy
IUBTreePy._set_type = IUSetPy

IUTreeSetPy._mapping_type = IUBucketPy
IUTreeSetPy._set_type = IUTreeSetPy._bucket_type = IUSetPy


differencePy = _set_operation(_difference, IUSetPy)
unionPy = _set_operation(_union, IUSetPy)
intersectionPy = _set_operation(_intersection, IUSetPy)
multiunionPy = _set_operation(_multiunion, IUSetPy)
weightedUnionPy = _set_operation(_weightedUnion, IUSetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, IUSetPy)

import_c_extension(globals())

_fix_pickle(globals(), __name__)

moduleProvides(IIntegerUnsignedBTreeModule)

0 comments on commit 15f9350

Please sign in to comment.