org.eclipse.persistence.internal.sessions.ArrayRecord Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.sessions;
import java.io.StringWriter;
import java.util.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.internal.helper.DatabaseField;
/**
* PERF: Optimized record implementation using arrays instead of Vector.
* Currently only used when fetch rows from the database.
*/
public class ArrayRecord extends DatabaseRecord {
protected DatabaseField[] fieldsArray;
protected Object[] valuesArray;
protected ArrayRecord() {
super();
}
public ArrayRecord(Vector fields, DatabaseField[] fieldsArray, Object[] valuesArray) {
super(fields, null, fieldsArray.length);
this.fieldsArray = fieldsArray;
this.valuesArray = valuesArray;
}
/**
* Reset the fields and values from the arrays.
* This removes the optimization if a non-optimized method is called.
*/
protected void checkValues() {
if (this.values == null) {
this.values = new NonSynchronizedVector(this.valuesArray.length);
for (Object value : this.valuesArray) {
this.values.add(value);
}
}
}
/**
* INTERNAL:
* Add the field-value pair to the row. Will not check,
* will simply add to the end of the row
*/
public void add(DatabaseField key, Object value) {
checkValues();
this.fieldsArray = null;
this.valuesArray = null;
super.add(key, value);
}
/**
* PUBLIC:
* Clear the contents of the row.
*/
public void clear() {
this.fieldsArray = null;
this.valuesArray = null;
super.clear();
}
/**
* INTERNAL:
* Clone the row and its values.
*/
public AbstractRecord clone() {
checkValues();
return super.clone();
}
/**
* INTERNAL:
* Check if the field is contained in the row.
*/
public boolean containsKey(DatabaseField key) {
if (this.fieldsArray != null) {
// Optimize check.
int index = key.index;
if ((index >= 0) && (index < this.size)) {
DatabaseField field = this.fieldsArray[index];
if ((field == key) || field.equals(key)) {
return true;
}
}
for (DatabaseField field : this.fieldsArray) {
if ((field == key) || field.equals(key)) {
return true;
}
}
return false;
} else {
return super.containsKey(key);
}
}
/**
* PUBLIC:
* Check if the value is contained in the row.
*/
public boolean containsValue(Object value) {
if (this.valuesArray != null) {
for (Object rowValue : this.valuesArray) {
if ((value == rowValue) || rowValue.equals(value)) {
return true;
}
}
return false;
} else {
return super.containsValue(value);
}
}
/**
* INTERNAL:
* Retrieve the value for the field. If missing null is returned.
*/
public Object get(DatabaseField key) {
if (this.fieldsArray != null) {
// Optimize check.
int index = key.index;
if ((index >= 0) && (index < this.size)) {
DatabaseField field = this.fieldsArray[index];
if ((field == key) || field.equals(key)) {
return this.valuesArray[index];
}
}
for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
DatabaseField field = this.fieldsArray[fieldIndex];
if ((field == key) || field.equals(key)) {
// PERF: If the fields index was not set, then set it.
if (index == -1) {
key.setIndex(fieldIndex);
}
return this.valuesArray[fieldIndex];
}
}
return null;
} else {
return super.get(key);
}
}
/**
* INTERNAL:
* Retrieve the value for the field. If missing DatabaseRow.noEntry is returned.
*/
public Object getIndicatingNoEntry(DatabaseField key) {
if (this.fieldsArray != null) {
// Optimize check.
int index = key.index;
if ((index >= 0) && (index < this.size)) {
DatabaseField field = this.fieldsArray[index];
if ((field == key) || field.equals(key)) {
return this.valuesArray[index];
}
}
for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
DatabaseField field = this.fieldsArray[fieldIndex];
if ((field == key) || field.equals(key)) {
// PERF: If the fields index was not set, then set it.
if (index == -1) {
key.setIndex(fieldIndex);
}
return this.valuesArray[fieldIndex];
}
}
return AbstractRecord.noEntry;
} else {
return super.get(key);
}
}
/**
* INTERNAL:
* Returns the row's field with the same name.
*/
public DatabaseField getField(DatabaseField key) {
if (this.fieldsArray != null) {
// Optimize check.
int index = key.index;
if ((index >= 0) && (index < this.size)) {
DatabaseField field = this.fieldsArray[index];
if ((field == key) || field.equals(key)) {
return field;
}
}
for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
DatabaseField field = this.fieldsArray[fieldIndex];
if ((field == key) || field.equals(key)) {
return field;
}
}
return null;
} else {
return super.getField(key);
}
}
/**
* INTERNAL:
*/
public Vector getFields() {
checkValues();
return super.getFields();
}
/**
* INTERNAL:
*/
public Vector getValues() {
checkValues();
return super.getValues();
}
/**
* INTERNAL:
* Add the field-value pair to the row.
*/
public Object put(DatabaseField key, Object value) {
checkValues();
this.fieldsArray = null;
this.valuesArray = null;
return super.put(key, value);
}
/**
* INTERNAL:
* Remove the field key from the row.
*/
public Object remove(DatabaseField key) {
checkValues();
this.fieldsArray = null;
this.valuesArray = null;
return super.remove(key);
}
/**
* INTERNAL:
* replaces the value at index with value
*/
public void replaceAt(Object value, int index) {
if (this.valuesArray != null) {
this.valuesArray[index] = value;
} else {
super.replaceAt(value, index);
}
}
/**
* INTERNAL:
* replaces the value at field with value
*/
public void replaceAt(Object value, DatabaseField key) {
if (this.fieldsArray != null) {
// Optimize check.
int index = key.index;
if ((index >= 0) && (index < this.size)) {
DatabaseField field = this.fieldsArray[index];
if ((field == key) || field.equals(key)) {
this.valuesArray[index] = value;
return;
}
}
for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
DatabaseField field = this.fieldsArray[fieldIndex];
if ((field == key) || field.equals(key)) {
// PERF: If the fields index was not set, then set it.
if (index == -1) {
key.setIndex(fieldIndex);
}
this.valuesArray[fieldIndex] = value;
return;
}
}
} else {
super.replaceAt(value, key);
}
}
protected void setFields(Vector fields) {
checkValues();
this.fieldsArray = null;
this.valuesArray = null;
super.setFields(fields);
}
protected void setValues(Vector values) {
checkValues();
this.fieldsArray = null;
this.valuesArray = null;
super.setValues(values);
}
/**
* PUBLIC:
* Return the number of field/value pairs in the row.
*/
public int size() {
if (this.fieldsArray == null) {
return this.fields.size();
} else {
return this.fieldsArray.length;
}
}
@Override
public String toString() {
if (this.valuesArray != null) {
StringWriter writer = new StringWriter();
writer.write(Helper.getShortClassName(getClass()));
writer.write("(");
writer.write(toStringAditional());
for (int index = 0; index < this.fieldsArray.length; index++) {
writer.write(Helper.cr());
writer.write("\t");
writer.write(String.valueOf(this.fieldsArray[index]));
writer.write(" => ");
writer.write(String.valueOf(this.valuesArray[index]));
}
if (this.sopObject != null) {
writer.write(Helper.cr());
writer.write(" sopObject = ");
writer.write(this.sopObject.toString());
}
writer.write(")");
return writer.toString();
} else {
return super.toString();
}
}
protected String toStringAditional() {
return "";
}
}