@@ -495,9 +495,36 @@ private ResultSetResult(
495495
496496 @ Override
497497 <T > Publisher <T > publishSegments (Function <Segment , T > mappingFunction ) {
498- return adapter .publishRows (resultSet , jdbcReadable ->
499- mappingFunction .apply (
500- new RowSegmentImpl (createRow (jdbcReadable , metadata , adapter ))));
498+
499+ // Avoiding object allocating by reusing the same Row object
500+ ReusableJdbcReadable reusableJdbcReadable = new ReusableJdbcReadable ();
501+ Row row = createRow (reusableJdbcReadable , metadata , adapter );
502+
503+ return adapter .publishRows (resultSet , jdbcReadable -> {
504+ reusableJdbcReadable .current = jdbcReadable ;
505+ return mappingFunction .apply (new RowSegmentImpl (row ));
506+ });
507+ }
508+
509+ /**
510+ * Wraps an actual
511+ * {@link oracle.r2dbc.impl.ReactiveJdbcAdapter.JdbcReadable}. The actual
512+ * readable is set to {@link #current}. A single instance of
513+ * {@code OracleReadableImpl.RowImpl} can retain an instance of this class,
514+ * and the instance can read multiple rows by changing the value of
515+ * {@link #current} between invocations of a user defined row mapping
516+ * function. This is done to avoid allocating an object for each row of a
517+ * query result.
518+ */
519+ private static final class ReusableJdbcReadable
520+ implements ReactiveJdbcAdapter .JdbcReadable {
521+
522+ ReactiveJdbcAdapter .JdbcReadable current = null ;
523+
524+ @ Override
525+ public <T > T getObject (int index , Class <T > type ) {
526+ return current .getObject (index , type );
527+ }
501528 }
502529 }
503530
0 commit comments