Skip to content

Commit df010ba

Browse files
authored
Merge ac753c8 into sapling-pr-archive-ktf
2 parents 3ef90f0 + ac753c8 commit df010ba

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

Framework/Core/test/test_ASoA.cxx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,3 +1440,49 @@ TEST_CASE("TestCombinedGetter")
14401440
++count;
14411441
}
14421442
}
1443+
1444+
TEST_CASE("TestWritingCursorLastIndexAndReserve")
1445+
{
1446+
// Nails down the WritingCursor semantics the AOD-producer reserves depend on:
1447+
// lastIndex() returns the *last index* (rows - 1), not the row count, and
1448+
// reserve(newRows + lastIndex() + 1) reserves exactly the post-batch total so a
1449+
// fully-filled, no-skip batch neither overruns (the fwdTrkCls crash) nor trips
1450+
// the release() / per-row UnsafeAppend guard.
1451+
Produces<o2::aod::Points> cursor; // Points has two persistent columns: X, Y
1452+
auto* builder = new TableBuilder();
1453+
cursor.resetCursor(LifetimeHolder<TableBuilder>(builder));
1454+
1455+
// Empty cursor: no row written, so the last index is -1 and rows == lastIndex()+1 == 0.
1456+
REQUIRE(cursor.lastIndex() == -1);
1457+
1458+
// operator() increments before the append, but only to the index of the row it
1459+
// writes: after N writes lastIndex() == N - 1, NOT N.
1460+
cursor(10, 20);
1461+
REQUIRE(cursor.lastIndex() == 0);
1462+
cursor(11, 21);
1463+
REQUIRE(cursor.lastIndex() == 1);
1464+
cursor(12, 22);
1465+
REQUIRE(cursor.lastIndex() == 2);
1466+
REQUIRE(cursor.lastIndex() + 1 == 3); // rows-so-far == last index + 1
1467+
1468+
// Reserve a second batch the correct way: total = newRows + rowsSoFar
1469+
// = newRows + (lastIndex() + 1).
1470+
// The (buggy) newRows + lastIndex() would reserve 4 here and under-reserve the
1471+
// 5th row; the + 1 makes it exactly 5.
1472+
int64_t const newRows = 2;
1473+
int64_t const reserved = newRows + cursor.lastIndex() + 1; // correct total -> reserve(5)
1474+
cursor.reserve(reserved);
1475+
cursor(13, 23); // row index 3
1476+
cursor(14, 24); // row index 4 — fills the batch exactly (5 rows total)
1477+
REQUIRE(cursor.lastIndex() == 4);
1478+
1479+
// The contract release() enforces: rows filled (lastIndex()+1) must not exceed
1480+
// what was reserved. Correct (+1) gives reserved == 5 -> 5 <= 5 (green); the buggy
1481+
// newRows + lastIndex() reserves only 4 -> 5 <= 4 fails (red).
1482+
REQUIRE(cursor.lastIndex() + 1 <= reserved);
1483+
1484+
auto table = builder->finalize();
1485+
REQUIRE(table->num_rows() == 5);
1486+
REQUIRE(table->num_columns() == 2);
1487+
delete builder;
1488+
}

0 commit comments

Comments
 (0)