[#2178] Improve FieldList. Avoid creating excessive array lists, where

simple (immutable) Field<?>[] are sufficient - Removed unnecessary
FieldList
This commit is contained in:
Lukas Eder 2013-02-09 11:26:18 +01:00
parent 058151a756
commit 345c44f656
16 changed files with 99 additions and 154 deletions

View File

@ -41,8 +41,10 @@ import static org.jooq.impl.Factory.notExists;
import static org.jooq.impl.Factory.selectDistinct;
import static org.jooq.impl.Factory.selectOne;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.jooq.Condition;
import org.jooq.DivideByOnConditionStep;
@ -62,17 +64,17 @@ implements
DivideByOnStep,
DivideByOnConditionStep {
private final Table<?> dividend;
private final Table<?> divisor;
private final ConditionProviderImpl condition;
private final FieldList returning;
private final Table<?> dividend;
private final Table<?> divisor;
private final ConditionProviderImpl condition;
private final QueryPartList<Field<?>> returning;
DivideBy(Table<?> dividend, Table<?> divisor) {
this.dividend = dividend;
this.divisor = divisor;
this.condition = new ConditionProviderImpl();
this.returning = new FieldList();
this.returning = new QueryPartList<Field<?>>();
}
// ------------------------------------------------------------------------
@ -90,7 +92,7 @@ implements
*/
private final Table<Record> table() {
ConditionProviderImpl selfJoin = new ConditionProviderImpl();
FieldList select = new FieldList();
List<Field<?>> select = new ArrayList<Field<?>>();
Table<?> outer = dividend.as("dividend");
for (Field<?> field : returning) {

View File

@ -1599,12 +1599,12 @@ public class Executor implements Configuration {
catch (IOException ignore) {}
}
FieldList fields = new FieldList();
if (all.size() == 0) {
return new ResultImpl<Record>(this, fields);
return new ResultImpl<Record>(this);
}
else {
List<Field<?>> fields = new ArrayList<Field<?>>();
for (String name : all.get(0)) {
fields.add(fieldByName(String.class, name));
}

View File

@ -69,7 +69,6 @@ import static org.jooq.impl.Factory.two;
import static org.jooq.impl.Factory.val;
import java.sql.Timestamp;
import java.util.Arrays;
import org.jooq.BindContext;
import org.jooq.Configuration;
@ -90,19 +89,18 @@ class Expression<T> extends AbstractFunction<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = -5522799070693019771L;
private static final long serialVersionUID = -5522799070693019771L;
private final Field<T> lhs;
private final FieldList rhs;
private final ExpressionOperator operator;
private final Field<T> lhs;
private final QueryPartList<Field<?>> rhs;
private final ExpressionOperator operator;
Expression(ExpressionOperator operator, Field<T> lhs, Field<?>... rhs) {
super(operator.toSQL(), lhs.getDataType(), Utils.combine(lhs, rhs));
this.operator = operator;
this.lhs = lhs;
this.rhs = new FieldList();
this.rhs.addAll(Arrays.asList(rhs));
this.rhs = new QueryPartList<Field<?>>(rhs);
}
@Override

View File

@ -57,6 +57,7 @@ import java.sql.Date;
import java.sql.ResultSetMetaData;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -4615,7 +4616,7 @@ public class Factory {
WrappedList[] array = new WrappedList[fieldSets.length];
for (int i = 0; i < fieldSets.length; i++) {
array[i] = new WrappedList(new FieldList(fieldSets[i]));
array[i] = new WrappedList(new QueryPartList<Field<?>>(fieldSets[i]));
}
return new Function<Object>("grouping sets", SQLDataType.OTHER, array);
@ -6860,7 +6861,7 @@ public class Factory {
*/
@Support
public static List<Field<?>> vals(Object... values) {
FieldList result = new FieldList();
List<Field<?>> result = new ArrayList<Field<?>>();
if (values != null) {
for (Object value : values) {
@ -6883,7 +6884,7 @@ public class Factory {
*/
@Support
public static List<Field<?>> vals(Object[] values, Field<?>[] fields) {
FieldList result = new FieldList();
List<Field<?>> result = new ArrayList<Field<?>>();
if (values != null && fields != null) {
for (int i = 0; i < values.length && i < fields.length; i++) {
@ -6899,7 +6900,7 @@ public class Factory {
*/
@Support
public static List<Field<?>> vals(Object[] values, Class<?>[] types) {
FieldList result = new FieldList();
List<Field<?>> result = new ArrayList<Field<?>>();
if (values != null && types != null) {
for (int i = 0; i < values.length && i < types.length; i++) {
@ -6915,7 +6916,7 @@ public class Factory {
*/
@Support
public static List<Field<?>> vals(Object[] values, DataType<?>[] types) {
FieldList result = new FieldList();
List<Field<?>> result = new ArrayList<Field<?>>();
if (values != null && types != null) {
for (int i = 0; i < values.length && i < types.length; i++) {

View File

@ -1,61 +0,0 @@
/**
* Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.impl;
import java.util.Collection;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
class FieldList extends QueryPartList<Field<?>> {
private static final long serialVersionUID = -6911012275707591576L;
FieldList() {
super();
}
FieldList(Collection<? extends Field<?>> wrappedList) {
super(wrappedList);
}
FieldList(Field<?>... wrappedList) {
super(wrappedList);
}
}

View File

@ -36,7 +36,9 @@
package org.jooq.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.jooq.BindContext;
import org.jooq.Field;
@ -48,7 +50,7 @@ import org.jooq.RenderContext;
*
* @author Lukas Eder
*/
class Fields extends AbstractQueryPart {
class Fields extends AbstractQueryPart implements Iterable<Field<?>> {
private static final long serialVersionUID = -6911012275707591576L;
Field<?>[] fields;
@ -135,20 +137,28 @@ class Fields extends AbstractQueryPart {
@Override
public final void toSQL(RenderContext context) {
new FieldList(fields).toSQL(context);
new QueryPartList<Field<?>>(fields).toSQL(context);
}
@Override
public final void bind(BindContext context) {
new FieldList(fields).bind(context);
new QueryPartList<Field<?>>(fields).bind(context);
}
final void add(Field<?> field) {
int length = fields.length;
// -------------------------------------------------------------------------
// XXX: List-like API
// -------------------------------------------------------------------------
Field<?>[] result = new Field[length + 1];
System.arraycopy(fields, 0, result, 0, length);
result[length] = field;
@Override
public final Iterator<Field<?>> iterator() {
return Arrays.asList(fields).iterator();
}
final void add(Field<?> f) {
Field<?>[] result = new Field[fields.length + 1];
System.arraycopy(fields, 0, result, 0, fields.length);
result[fields.length] = f;
fields = result;
}

View File

@ -97,7 +97,7 @@ class Function<T> extends AbstractField<T> implements
private final boolean distinct;
private final SortFieldList withinGroupOrderBy;
private final SortFieldList keepDenseRankOrderBy;
private final FieldList partitionBy;
private final QueryPartList<Field<?>> partitionBy;
private final SortFieldList orderBy;
private boolean first;
@ -108,7 +108,6 @@ class Function<T> extends AbstractField<T> implements
private Integer rowsStart;
private Integer rowsEnd;
// -------------------------------------------------------------------------
// XXX Constructors
// -------------------------------------------------------------------------
@ -129,7 +128,7 @@ class Function<T> extends AbstractField<T> implements
this.arguments = new QueryPartList<QueryPart>(arguments);
this.keepDenseRankOrderBy = new SortFieldList();
this.withinGroupOrderBy = new SortFieldList();
this.partitionBy = new FieldList();
this.partitionBy = new QueryPartList<Field<?>>();
this.orderBy = new SortFieldList();
}
@ -141,7 +140,7 @@ class Function<T> extends AbstractField<T> implements
this.arguments = new QueryPartList<QueryPart>(arguments);
this.keepDenseRankOrderBy = new SortFieldList();
this.withinGroupOrderBy = new SortFieldList();
this.partitionBy = new FieldList();
this.partitionBy = new QueryPartList<Field<?>>();
this.orderBy = new SortFieldList();
}

View File

@ -76,21 +76,21 @@ import org.jooq.exception.SQLDialectNotSupportedException;
*/
class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements InsertQuery<R> {
private static final long serialVersionUID = 4466005417945353842L;
private static final long serialVersionUID = 4466005417945353842L;
private final FieldMapForUpdate updateMap;
private final FieldMapsForInsert insertMaps;
private final FieldList returning;
private Result<R> returned;
private boolean onDuplicateKeyUpdate;
private boolean onDuplicateKeyIgnore;
private final FieldMapForUpdate updateMap;
private final FieldMapsForInsert insertMaps;
private final QueryPartList<Field<?>> returning;
private Result<R> returned;
private boolean onDuplicateKeyUpdate;
private boolean onDuplicateKeyIgnore;
InsertQueryImpl(Configuration configuration, Table<R> into) {
super(configuration, into);
updateMap = new FieldMapForUpdate();
insertMaps = new FieldMapsForInsert();
returning = new FieldList();
returning = new QueryPartList<Field<?>>();
}
@Override

View File

@ -86,26 +86,26 @@ class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, Ta
/**
* Generated UID
*/
private static final long serialVersionUID = 8377996833996498178L;
private static final long serialVersionUID = 8377996833996498178L;
private final Table<?> lhs;
private final Table<?> rhs;
private final FieldList rhsPartitionBy;
private final Table<?> lhs;
private final Table<?> rhs;
private final QueryPartList<Field<?>> rhsPartitionBy;
private final JoinType type;
private final ConditionProviderImpl condition;
private final FieldList using;
private final JoinType type;
private final ConditionProviderImpl condition;
private final QueryPartList<Field<?>> using;
JoinTable(TableLike<?> lhs, TableLike<?> rhs, JoinType type) {
super("join");
this.lhs = lhs.asTable();
this.rhs = rhs.asTable();
this.rhsPartitionBy = new FieldList();
this.rhsPartitionBy = new QueryPartList<Field<?>>();
this.type = type;
this.condition = new ConditionProviderImpl();
this.using = new FieldList();
this.using = new QueryPartList<Field<?>>();
}
// ------------------------------------------------------------------------

View File

@ -44,11 +44,13 @@ import static org.jooq.impl.Factory.val;
import static org.jooq.impl.Factory.vals;
import static org.jooq.tools.Convert.convert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -215,9 +217,9 @@ implements
// Objects for the H2-specific syntax
private boolean h2Style;
private Fields h2Fields;
private FieldList h2Keys;
private FieldList h2Values;
private QueryPartList<Field<?>> h2Fields;
private QueryPartList<Field<?>> h2Keys;
private QueryPartList<Field<?>> h2Values;
private Select<?> h2Select;
MergeImpl(Configuration configuration, Table<R> table) {
@ -232,7 +234,7 @@ implements
if (fields != null) {
h2Style = true;
h2Fields = new Fields(fields);
h2Fields = new QueryPartList<Field<?>>(fields);
}
}
@ -240,25 +242,25 @@ implements
// H2-specific MERGE API
// -------------------------------------------------------------------------
Fields getH2Fields() {
QueryPartList<Field<?>> getH2Fields() {
if (h2Fields == null) {
h2Fields = new Fields(table.fields());
h2Fields = new QueryPartList<Field<?>>(table.fields());
}
return h2Fields;
}
FieldList getH2Keys() {
QueryPartList<Field<?>> getH2Keys() {
if (h2Keys == null) {
h2Keys = new FieldList();
h2Keys = new QueryPartList<Field<?>>();
}
return h2Keys;
}
FieldList getH2Values() {
QueryPartList<Field<?>> getH2Values() {
if (h2Values == null) {
h2Values = new FieldList();
h2Values = new QueryPartList<Field<?>>();
}
return h2Values;
@ -518,7 +520,7 @@ implements
// syntax, in case of which, the USING() was not added
if (using == null) {
h2Style = true;
getH2Values().addAll(vals(convert(values, getH2Fields().fields())));
getH2Values().addAll(vals(convert(values, getH2Fields().toArray(new Field[0]))));
}
else {
Field<?>[] fields = notMatchedInsert.keySet().toArray(new Field[0]);
@ -893,7 +895,7 @@ implements
// ------------------------------
Table<?> src;
if (h2Select != null) {
FieldList v = new FieldList();
List<Field<?>> v = new ArrayList<Field<?>>();
Row row = h2Select.fieldsRow();
for (int i = 0; i < row.size(); i++) {
@ -905,7 +907,7 @@ implements
src = create(config).select(v).from(h2Select).asTable("src");
}
else {
FieldList v = new FieldList();
List<Field<?>> v = new ArrayList<Field<?>>();
for (int i = 0; i < getH2Values().size(); i++) {
v.add(getH2Values().get(i).as("s" + (i + 1)));
@ -967,11 +969,11 @@ implements
for (int i = 0; i < src.fieldsRow().size(); i++) {
// Oracle does not allow to update fields from the ON clause
if (!onFields.contains(getH2Fields().field(i))) {
update.put(getH2Fields().field(i), src.field(i));
if (!onFields.contains(getH2Fields().get(i))) {
update.put(getH2Fields().get(i), src.field(i));
}
insert.put(getH2Fields().field(i), src.field(i));
insert.put(getH2Fields().get(i), src.field(i));
}
return create(config).mergeInto(table)
@ -1137,7 +1139,7 @@ implements
context.declareTables(true)
.bind(table)
.declareTables(false)
.bind(getH2Fields())
.bind((QueryPart) getH2Fields())
.bind((QueryPart) getH2Keys())
.bind(h2Select)
.bind((QueryPart) getH2Values());

View File

@ -38,7 +38,9 @@ package org.jooq.impl;
import static org.jooq.impl.Factory.trueCondition;
import static org.jooq.impl.Factory.vals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jooq.BindContext;
import org.jooq.Condition;
@ -141,9 +143,9 @@ implements
}
private Table<Record> select(Context<?> context) {
FieldList groupingFields = new FieldList();
FieldList aliasedGroupingFields = new FieldList();
FieldList aggregatedFields = new FieldList();
List<Field<?>> groupingFields = new ArrayList<Field<?>>();
List<Field<?>> aliasedGroupingFields = new ArrayList<Field<?>>();
List<Field<?>> aggregatedFields = new ArrayList<Field<?>>();
Table<?> pivot = table.as("pivot_outer");
@ -173,7 +175,7 @@ implements
}
// The product {aggregateFunctions} x {in}
FieldList aggregationSelects = new FieldList();
List<Field<?>> aggregationSelects = new ArrayList<Field<?>>();
for (Field<?> inField : in) {
for (Field<?> aggregateFunction : aggregateFunctions) {
Condition join = trueCondition();

View File

@ -103,7 +103,7 @@ class ReferenceImpl<R extends Record, O extends Record> extends AbstractKey<R> i
@Override
public final Result<O> fetchParents(Collection<? extends R> records) {
if (records == null || records.size() == 0) {
return new ResultImpl<O>(new DefaultConfiguration(), new FieldList(key.getFields()));
return new ResultImpl<O>(new DefaultConfiguration(), key.getFields());
}
else {
return fetch(records, key.getTable(), key.getFieldsArray(), getFieldsArray());
@ -113,7 +113,7 @@ class ReferenceImpl<R extends Record, O extends Record> extends AbstractKey<R> i
@Override
public final Result<R> fetchChildren(Collection<? extends O> records) {
if (records == null || records.size() == 0) {
return new ResultImpl<R>(new DefaultConfiguration(), new FieldList(getFields()));
return new ResultImpl<R>(new DefaultConfiguration(), getFields());
}
else {
return fetch(records, getTable(), getFieldsArray(), key.getFieldsArray());

View File

@ -732,19 +732,17 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
}
Map<Record, R> map = new LinkedHashMap<Record, R>();
FieldList keyList = new FieldList(keys);
for (R record : this) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Record key = new RecordImpl(keyList);
Record key = new RecordImpl(keys);
for (Field<?> field : keys) {
Utils.setValue(key, field, record, field);
}
if (map.put(key, record) != null) {
throw new InvalidResultException("Key list " + keyList + " is not unique in Result for " + this);
throw new InvalidResultException("Key list " + Arrays.asList(keys) + " is not unique in Result for " + this);
}
}
@ -840,12 +838,10 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
}
Map<Record, Result<R>> map = new LinkedHashMap<Record, Result<R>>();
FieldList keyList = new FieldList(keys);
for (R record : this) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Record key = new RecordImpl(keyList);
Record key = new RecordImpl(keys);
for (Field<?> field : keys) {
Utils.setValue(key, field, record, field);
@ -891,12 +887,10 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
}
Map<Record, List<E>> map = new LinkedHashMap<Record, List<E>>();
FieldList keyList = new FieldList(keys);
for (R record : this) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Record key = new RecordImpl(keyList);
Record key = new RecordImpl(keys);
for (Field<?> field : keys) {
Utils.setValue(key, field, record, field);

View File

@ -35,7 +35,6 @@
*/
package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.impl.Factory.field;
import static org.jooq.impl.Factory.function;
@ -61,7 +60,7 @@ class Rollup extends AbstractFunction<Object> {
switch (configuration.getDialect()) {
case CUBRID:
case MYSQL:
return field("{0} {with rollup}", new FieldList(asList(getArguments())));
return field("{0} {with rollup}", new QueryPartList<Field<?>>(getArguments()));
default:
return function("rollup", Object.class, getArguments());

View File

@ -96,7 +96,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
private String hint;
private boolean distinct;
private boolean forUpdate;
private final FieldList forUpdateOf;
private final QueryPartList<Field<?>> forUpdateOf;
private final TableList forUpdateOfTables;
private ForUpdateMode forUpdateMode;
private int forUpdateWait;
@ -143,7 +143,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
this.from.add(from.asTable());
}
this.forUpdateOf = new FieldList();
this.forUpdateOf = new QueryPartList<Field<?>>();
this.forUpdateOfTables = new TableList();
}

View File

@ -38,7 +38,6 @@ package org.jooq.impl;
import org.jooq.BindContext;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.RenderContext;
import org.jooq.Row;
@ -60,11 +59,11 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
private final Schema schema;
private final String name;
private final FieldList fields;
private final Fields fields;
private transient DataType<R> type;
public UDTImpl(String name, Schema schema) {
this.fields = new FieldList();
this.fields = new Fields();
this.name = name;
this.schema = schema;
}
@ -79,7 +78,7 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
return name;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({ "rawtypes" })
@Override
public final Row fieldsRow() {
return new RowImpl(fields);
@ -105,7 +104,7 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
return fieldsRow().fields();
}
final FieldList fields0() {
final Fields fields0() {
return fields;
}
@ -134,7 +133,7 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
@Override
public final void bind(BindContext context) {
context.bind((QueryPart) fields);
context.bind(fields);
}
/**