Skip to content

Commit ff184de

Browse files
committed
implemented iter_block, added tests, code cleanup
1 parent c1a180f commit ff184de

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

src/_arraykit.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,14 +3282,15 @@ AK_build_pair_ssize_t(Py_ssize_t a, Py_ssize_t b)
32823282
Py_DECREF(py_a);
32833283
return NULL;
32843284
}
3285+
// steals refs
32853286
PyTuple_SET_ITEM(t, 0, py_a);
32863287
PyTuple_SET_ITEM(t, 1, py_b);
32873288
return t;
32883289
}
32893290

32903291
// Returns NULL on error. Returns a new reference. Note that a reference is stolen from the PyObject argument.
32913292
static inline PyObject*
3292-
AK_build_pair_ssize_t_slice(Py_ssize_t a, PyObject* py_b)
3293+
AK_build_pair_ssize_t_pyo(Py_ssize_t a, PyObject* py_b)
32933294
{
32943295
if (py_b == NULL) { // construction failed
32953296
return NULL;
@@ -3303,6 +3304,7 @@ AK_build_pair_ssize_t_slice(Py_ssize_t a, PyObject* py_b)
33033304
Py_DECREF(t);
33043305
return NULL;
33053306
}
3307+
// steals refs
33063308
PyTuple_SET_ITEM(t, 0, py_a);
33073309
PyTuple_SET_ITEM(t, 1, py_b);
33083310
return t;
@@ -4497,7 +4499,7 @@ BIIterSeq_iternext(BIIterSeqObject *self)
44974499
static PyObject *
44984500
BIIterSeq_reversed(BIIterSeqObject *self)
44994501
{
4500-
return BIIterSelector_new(self->bi, self->selector, !self->reversed, BIIS_SEQ, 0);
4502+
return BIIterSelector_new(self->bi, self->selector, !self->reversed, BIIS_SEQ, false);
45014503
}
45024504

45034505
static PyObject *
@@ -4579,7 +4581,7 @@ BIIterSlice_iternext(BIIterSliceObject *self) {
45794581
static PyObject *
45804582
BIIterSlice_reversed(BIIterSliceObject *self)
45814583
{
4582-
return BIIterSelector_new(self->bi, self->selector, !self->reversed, BIIS_SLICE, 0);
4584+
return BIIterSelector_new(self->bi, self->selector, !self->reversed, BIIS_SLICE, false);
45834585
}
45844586

45854587
static PyObject *
@@ -4834,7 +4836,7 @@ BIIterContiguous_iternext(BIIterContiguousObject *self)
48344836
if (self->last_block == -1) { // iter produced no values, terminate
48354837
break;
48364838
}
4837-
return AK_build_pair_ssize_t_slice( // steals ref
4839+
return AK_build_pair_ssize_t_pyo( // steals ref
48384840
self->last_block,
48394841
AK_build_slice_inclusive(slice_start,
48404842
self->last_column,
@@ -4859,7 +4861,7 @@ BIIterContiguous_iternext(BIIterContiguousObject *self)
48594861
}
48604862
self->next_block = block;
48614863
self->next_column = column;
4862-
return AK_build_pair_ssize_t_slice( // steals ref
4864+
return AK_build_pair_ssize_t_pyo( // steals ref
48634865
self->last_block,
48644866
AK_build_slice_inclusive(slice_start,
48654867
self->last_column,
@@ -4910,13 +4912,18 @@ BIIterBlock_new(BlockIndexObject *bi, bool reversed) {
49104912
bii->pos = 0;
49114913

49124914
// create a new ref of the null slice
4913-
4915+
PyObject* ns = AK_build_slice(-1, -1, 1); // get all null; new ref
4916+
if (ns == NULL) {
4917+
return NULL;
4918+
}
4919+
bii->null_slice = ns;
49144920
return (PyObject *)bii;
49154921
}
49164922

49174923
static void
49184924
BIIterBlock_dealloc(BIIterBlockObject *self) {
49194925
Py_DECREF((PyObject*)self->bi);
4926+
Py_DECREF(self->null_slice);
49204927
PyObject_Del((PyObject*)self);
49214928
}
49224929

@@ -4941,8 +4948,14 @@ BIIterBlock_iternext(BIIterBlockObject *self) {
49414948
if (self->bi->block_count <= i) {
49424949
return NULL;
49434950
}
4944-
Py_RETURN_NONE;
4945-
// return AK_BI_item(self->bi, i); // return new ref
4951+
// AK_build_pair_ssize_t_pyo steals the reference to the object; so incref here
4952+
Py_INCREF(self->null_slice);
4953+
PyObject* t = AK_build_pair_ssize_t_pyo(i, self->null_slice); // return new ref
4954+
if (t == NULL) {
4955+
// if tuple creation failed need to undo incref
4956+
Py_DECREF(self->null_slice);
4957+
}
4958+
return t;
49464959
}
49474960

49484961
static PyObject *
@@ -5551,7 +5564,7 @@ BlockIndex_iter(BlockIndexObject* self) {
55515564
// Given key, return an iterator of a selection.
55525565
static PyObject*
55535566
BlockIndex_iter_select(BlockIndexObject *self, PyObject *selector){
5554-
return BIIterSelector_new(self, selector, 0, BIIS_UNKNOWN, 0);
5567+
return BIIterSelector_new(self, selector, false, BIIS_UNKNOWN, false);
55555568
}
55565569

55575570
static char *iter_contiguous_kargs_names[] = {
@@ -5566,7 +5579,7 @@ static PyObject*
55665579
BlockIndex_iter_contiguous(BlockIndexObject *self, PyObject *args, PyObject *kwargs)
55675580
{
55685581
PyObject* selector;
5569-
int ascending = 0;
5582+
int ascending = 0; // must be int for parsing to "p"
55705583
int reduce = 0;
55715584

55725585
if (!PyArg_ParseTupleAndKeywords(args, kwargs,

test/test_block_index.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,3 +816,37 @@ def test_block_index_iter_contiguous_i2(self) -> None:
816816

817817
self.assertEqual(list(bi1.iter_select(np.full(len(bi1), False))), [])
818818
self.assertEqual(list(bi1.iter_contiguous(np.full(len(bi1), False))), [])
819+
820+
821+
822+
#---------------------------------------------------------------------------
823+
824+
def test_block_index_iter_block_a(self) -> None:
825+
bi1 = BlockIndex()
826+
bi1.register(np.arange(6).reshape(2,3))
827+
bi1.register(np.arange(2))
828+
bi1.register(np.arange(6).reshape(2,3))
829+
830+
slc = slice(None)
831+
self.assertEqual(list(bi1.iter_block()), [(0, slc), (1, slc), (2, slc)])
832+
self.assertEqual(list(reversed(bi1.iter_block())), [(2, slc), (1, slc), (0, slc)])
833+
834+
835+
def test_block_index_iter_block_b(self) -> None:
836+
bi1 = BlockIndex()
837+
self.assertEqual(list(bi1.iter_block()), [])
838+
839+
840+
def test_block_index_iter_block_c(self) -> None:
841+
bi1 = BlockIndex()
842+
bi1.register(np.arange(2))
843+
bi1.register(np.arange(2))
844+
bi1.register(np.arange(2))
845+
bi1.register(np.arange(2))
846+
bi1.register(np.arange(2))
847+
bi1.register(np.arange(2))
848+
bi1.register(np.arange(2))
849+
bi1.register(np.arange(2))
850+
851+
slc = slice(None)
852+
self.assertEqual(list(bi1.iter_block()), [(i, slc) for i in range(8)])

0 commit comments

Comments
 (0)