@@ -4484,7 +4484,6 @@ BIIterSeq_iternext_index(BIIterSeqObject *self)
4484
4484
return t ;
4485
4485
}
4486
4486
4487
-
4488
4487
static PyObject *
4489
4488
BIIterSeq_iternext (BIIterSeqObject * self )
4490
4489
{
@@ -4701,6 +4700,7 @@ static PyTypeObject BIIterBoolType = {
4701
4700
4702
4701
//------------------------------------------------------------------------------
4703
4702
// BI Iterator Contigous
4703
+
4704
4704
static PyTypeObject BIIterContiguousType ;
4705
4705
4706
4706
typedef struct BIIterContiguousObject {
@@ -4885,6 +4885,94 @@ static PyTypeObject BIIterContiguousType = {
4885
4885
.tp_name = "arraykit.BlockIndexContiguousIterator" ,
4886
4886
};
4887
4887
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
+
4888
4976
//------------------------------------------------------------------------------
4889
4977
4890
4978
// 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
5490
5578
)) {
5491
5579
return NULL ;
5492
5580
}
5493
- PyObject * iter = BIIterSelector_new (self , selector , 0 , BIIS_UNKNOWN , ascending );
5581
+ PyObject * iter = BIIterSelector_new (self , selector , false , BIIS_UNKNOWN , ascending );
5494
5582
if (iter == NULL ) {
5495
5583
return NULL ; // exception set
5496
5584
}
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
5498
5586
return biiter ;
5499
5587
}
5500
5588
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
+
5501
5596
//------------------------------------------------------------------------------
5502
5597
// slot / method def
5503
5598
@@ -5522,6 +5617,7 @@ static PyMethodDef BlockIndex_methods[] = {
5522
5617
(PyCFunction ) BlockIndex_iter_contiguous ,
5523
5618
METH_VARARGS | METH_KEYWORDS ,
5524
5619
NULL },
5620
+ {"iter_block" , (PyCFunction ) BlockIndex_iter_block , METH_NOARGS , NULL },
5525
5621
// {"__getnewargs__", (PyCFunction)BlockIndex_getnewargs, METH_NOARGS, NULL},
5526
5622
{NULL },
5527
5623
};
@@ -5899,6 +5995,8 @@ PyInit__arraykit(void)
5899
5995
PyType_Ready (& BIIterSeqType ) ||
5900
5996
PyType_Ready (& BIIterSliceType ) ||
5901
5997
PyType_Ready (& BIIterBoolType ) ||
5998
+ PyType_Ready (& BIIterContiguousType ) ||
5999
+ PyType_Ready (& BIIterBlockType ) ||
5902
6000
PyType_Ready (& ArrayGOType ) ||
5903
6001
PyModule_AddObject (m , "BlockIndex" , (PyObject * ) & BlockIndexType ) ||
5904
6002
PyModule_AddObject (m , "ArrayGO" , (PyObject * ) & ArrayGOType ) ||
0 commit comments