[jOOQ/jOOQ#11099] Cache RecordDelegate instance in CursorImpl

This commit is contained in:
Lukas Eder 2020-12-10 16:52:30 +01:00
parent d30784526a
commit c0ca4527cc
3 changed files with 37 additions and 36 deletions

View File

@ -1551,7 +1551,7 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
/**
* The (potentially) pre-fetched next record
*/
private R next;
private R next;
/**
* Whether the underlying {@link ResultSet} has a next record. This
@ -1562,12 +1562,15 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
* <li>false: there aren't any next records</li>
* </ul>
*/
private Boolean hasNext;
private Boolean hasNext;
/**
* [#11099] Cache this instance for the entire cursor.
*/
private final CursorRecordInitialiser initialiser = new CursorRecordInitialiser(fields, 0);
private final CursorRecordInitialiser initialiser = new CursorRecordInitialiser(fields, 0);
@SuppressWarnings("unchecked")
private final RecordDelegate<AbstractRecord> recordDelegate = Tools.newRecord(true, (F0<AbstractRecord>) factory, ((DefaultExecuteContext) ctx).originalConfiguration());
@Override
public final boolean hasNext() {
@ -1601,9 +1604,7 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> implements Cu
try {
if (!isClosed && rs.next()) {
record = Tools.newRecord(true, (F0<AbstractRecord>) factory, ((DefaultExecuteContext) ctx).originalConfiguration())
.operate(initialiser.reset());
record = recordDelegate.operate(initialiser.reset());
rows++;
}
}

View File

@ -62,29 +62,47 @@ import org.jooq.exception.ControlFlowSignal;
final class RecordDelegate<R extends Record> {
private final Configuration configuration;
private final R record;
private final F0<R> recordSupplier;
private final Boolean fetched;
private final RecordLifecycleType type;
RecordDelegate(Configuration configuration, R record) {
this(configuration, record, LOAD);
RecordDelegate(Configuration configuration, F0<R> recordSupplier, Boolean fetched) {
this(configuration, recordSupplier, fetched, LOAD);
}
RecordDelegate(Configuration configuration, R record, RecordLifecycleType type) {
RecordDelegate(Configuration configuration, F0<R> recordSupplier, Boolean fetched, RecordLifecycleType type) {
this.configuration = configuration;
this.record = record;
this.recordSupplier = recordSupplier;
this.fetched = fetched;
this.type = type;
}
static final <R extends Record> RecordDelegate<R> delegate(Configuration configuration, R record) {
return new RecordDelegate<>(configuration, record);
}
static final <R extends Record> RecordDelegate<R> delegate(Configuration configuration, R record, RecordLifecycleType type) {
return new RecordDelegate<>(configuration, record, type);
static final <R extends Record> RecordDelegate<R> delegate(
final Configuration configuration,
final R record,
final RecordLifecycleType type
) {
return new RecordDelegate<>(
configuration,
new F0<R>() {
@Override
public R apply() {
return record;
}
},
null,
type
);
}
@SuppressWarnings("unchecked")
final <E extends Exception> R operate(RecordOperation<? super R, E> operation) throws E {
R record = recordSupplier.apply();
// [#3300] Records that were fetched from the database
if (fetched != null && record instanceof AbstractRecord)
((AbstractRecord) record).fetched = fetched;
RecordListenerProvider[] providers = null;
RecordListener[] listeners = null;
DefaultRecordContext ctx = null;

View File

@ -881,13 +881,6 @@ final class Tools {
return newRecord(fetched, type, fields, null);
}
/**
* Create a new record
*/
static final <R extends Record> RecordDelegate<R> newRecord(boolean fetched, Table<R> type) {
return newRecord(fetched, type, null);
}
/**
* Create a new record
*/
@ -921,18 +914,7 @@ final class Tools {
* Create a new record.
*/
static final <R extends Record> RecordDelegate<R> newRecord(boolean fetched, F0<R> factory, Configuration configuration) {
try {
R record = factory.apply();
// [#3300] Records that were fetched from the database
if (record instanceof AbstractRecord)
((AbstractRecord) record).fetched = fetched;
return new RecordDelegate<>(configuration, record);
}
catch (Exception e) {
throw new IllegalStateException("Could not construct new record", e);
}
return new RecordDelegate<>(configuration, factory, fetched);
}
static final AbstractRow row0(FieldsImpl<?> fields) {