Skip to content

Commit c1a180f

Browse files
committed
preliminary code for iter_block
1 parent 436ce29 commit c1a180f

File tree

2 files changed

+102
-4
lines changed

2 files changed

+102
-4
lines changed

src/__init__.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class BlockIndex:
5959
ascending: bool = False,
6060
reduce: bool = False,
6161
) -> tp.Iterator[tp.Tuple[int, tp.Union[slice, int]]]: ...
62-
62+
def iter_block(self) -> tp.Iterator[tp.Tuple[int, slice]]: ...
6363

6464
def iterable_str_to_array_1d(
6565
iterable: tp.Iterable[str],

src/_arraykit.c

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4484,7 +4484,6 @@ BIIterSeq_iternext_index(BIIterSeqObject *self)
44844484
return t;
44854485
}
44864486

4487-
44884487
static PyObject *
44894488
BIIterSeq_iternext(BIIterSeqObject *self)
44904489
{
@@ -4701,6 +4700,7 @@ static PyTypeObject BIIterBoolType = {
47014700

47024701
//------------------------------------------------------------------------------
47034702
// BI Iterator Contigous
4703+
47044704
static PyTypeObject BIIterContiguousType;
47054705

47064706
typedef struct BIIterContiguousObject {
@@ -4885,6 +4885,94 @@ static PyTypeObject BIIterContiguousType = {
48854885
.tp_name = "arraykit.BlockIndexContiguousIterator",
48864886
};
48874887

4888+
//------------------------------------------------------------------------------
4889+
// BI Iterator Block Slice
4890+
4891+
static PyTypeObject BIIterBlockType;
4892+
4893+
typedef struct BIIterBlockObject {
4894+
PyObject_HEAD
4895+
BlockIndexObject *bi;
4896+
bool reversed;
4897+
Py_ssize_t pos; // current index state, mutated in-place
4898+
PyObject* null_slice;
4899+
} BIIterBlockObject;
4900+
4901+
static PyObject *
4902+
BIIterBlock_new(BlockIndexObject *bi, bool reversed) {
4903+
BIIterBlockObject *bii = PyObject_New(BIIterBlockObject, &BIIterBlockType);
4904+
if (!bii) {
4905+
return NULL;
4906+
}
4907+
Py_INCREF((PyObject*)bi);
4908+
bii->bi = bi;
4909+
bii->reversed = reversed;
4910+
bii->pos = 0;
4911+
4912+
// create a new ref of the null slice
4913+
4914+
return (PyObject *)bii;
4915+
}
4916+
4917+
static void
4918+
BIIterBlock_dealloc(BIIterBlockObject *self) {
4919+
Py_DECREF((PyObject*)self->bi);
4920+
PyObject_Del((PyObject*)self);
4921+
}
4922+
4923+
static PyObject*
4924+
BIIterBlock_iter(BIIterBlockObject *self) {
4925+
Py_INCREF(self);
4926+
return (PyObject*)self;
4927+
}
4928+
4929+
static PyObject *
4930+
BIIterBlock_iternext(BIIterBlockObject *self) {
4931+
Py_ssize_t i;
4932+
if (self->reversed) {
4933+
i = self->bi->block_count - ++self->pos;
4934+
if (i < 0) {
4935+
return NULL;
4936+
}
4937+
}
4938+
else {
4939+
i = self->pos++;
4940+
}
4941+
if (self->bi->block_count <= i) {
4942+
return NULL;
4943+
}
4944+
Py_RETURN_NONE;
4945+
// return AK_BI_item(self->bi, i); // return new ref
4946+
}
4947+
4948+
static PyObject *
4949+
BIIterBlock_reversed(BIIterBlockObject *self) {
4950+
return BIIterBlock_new(self->bi, !self->reversed);
4951+
}
4952+
4953+
static PyObject *
4954+
BIIterBlock_length_hint(BIIterBlockObject *self) {
4955+
// this works for reversed as we use self->pos to subtract from length
4956+
Py_ssize_t len = Py_MAX(0, self->bi->block_count - self->pos);
4957+
return PyLong_FromSsize_t(len);
4958+
}
4959+
4960+
static PyMethodDef BIIterBlock_methods[] = {
4961+
{"__length_hint__", (PyCFunction)BIIterBlock_length_hint, METH_NOARGS, NULL},
4962+
{"__reversed__", (PyCFunction)BIIterBlock_reversed, METH_NOARGS, NULL},
4963+
{NULL},
4964+
};
4965+
4966+
static PyTypeObject BIIterBlockType = {
4967+
PyVarObject_HEAD_INIT(NULL, 0)
4968+
.tp_basicsize = sizeof(BIIterBlockObject),
4969+
.tp_dealloc = (destructor) BIIterBlock_dealloc,
4970+
.tp_iter = (getiterfunc) BIIterBlock_iter,
4971+
.tp_iternext = (iternextfunc) BIIterBlock_iternext,
4972+
.tp_methods = BIIterBlock_methods,
4973+
.tp_name = "arraykit.BlockIndexBlockIterator",
4974+
};
4975+
48884976
//------------------------------------------------------------------------------
48894977

48904978
// NOTE: this constructor returns one of three different PyObject types. We do this to consolidate error reporting and type checks.
@@ -5490,14 +5578,21 @@ BlockIndex_iter_contiguous(BlockIndexObject *self, PyObject *args, PyObject *kwa
54905578
)) {
54915579
return NULL;
54925580
}
5493-
PyObject* iter = BIIterSelector_new(self, selector, 0, BIIS_UNKNOWN, ascending);
5581+
PyObject* iter = BIIterSelector_new(self, selector, false, BIIS_UNKNOWN, ascending);
54945582
if (iter == NULL) {
54955583
return NULL; // exception set
54965584
}
5497-
PyObject* biiter = BIIterContiguous_new(self, 0, iter, reduce); // might be NULL, steals iter ref
5585+
PyObject* biiter = BIIterContiguous_new(self, false, iter, reduce); // might be NULL, steals iter ref
54985586
return biiter;
54995587
}
55005588

5589+
// Given key, return an iterator of a selection.
5590+
static PyObject*
5591+
BlockIndex_iter_block(BlockIndexObject *self){
5592+
return BIIterBlock_new(self, false);
5593+
}
5594+
5595+
55015596
//------------------------------------------------------------------------------
55025597
// slot / method def
55035598

@@ -5522,6 +5617,7 @@ static PyMethodDef BlockIndex_methods[] = {
55225617
(PyCFunction) BlockIndex_iter_contiguous,
55235618
METH_VARARGS | METH_KEYWORDS,
55245619
NULL},
5620+
{"iter_block", (PyCFunction) BlockIndex_iter_block, METH_NOARGS, NULL},
55255621
// {"__getnewargs__", (PyCFunction)BlockIndex_getnewargs, METH_NOARGS, NULL},
55265622
{NULL},
55275623
};
@@ -5899,6 +5995,8 @@ PyInit__arraykit(void)
58995995
PyType_Ready(&BIIterSeqType) ||
59005996
PyType_Ready(&BIIterSliceType) ||
59015997
PyType_Ready(&BIIterBoolType) ||
5998+
PyType_Ready(&BIIterContiguousType) ||
5999+
PyType_Ready(&BIIterBlockType) ||
59026000
PyType_Ready(&ArrayGOType) ||
59036001
PyModule_AddObject(m, "BlockIndex", (PyObject *) &BlockIndexType) ||
59046002
PyModule_AddObject(m, "ArrayGO", (PyObject *) &ArrayGOType) ||

0 commit comments

Comments
 (0)