Author: [log in to unmask]
Date: Thu Nov 13 19:50:23 2014
New Revision: 1514
Log:
Patch from Sho to fix slow conditions loading. Replaces internal ArrayList with LinkedHashSet.
Modified:
java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsObjectCollection.java
Modified: java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsObjectCollection.java
=============================================================================
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsObjectCollection.java (original)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsObjectCollection.java Thu Nov 13 19:50:23 2014
@@ -1,170 +1,167 @@
-package org.hps.conditions;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-public class ConditionsObjectCollection<ObjectType extends ConditionsObject> implements Iterable<ObjectType> {
-
- protected List<ObjectType> objects = new ArrayList<ObjectType>();
- protected TableMetaData tableMetaData;
- protected int collectionId = -1;
- protected boolean isReadOnly;
- protected boolean isDirty;
- protected boolean isNew;
- protected ConditionsRecord conditionsRecord;
-
- protected ConditionsObjectCollection() {
- }
-
- public ConditionsObjectCollection(TableMetaData tableMetaData, int collectionId, boolean isReadOnly) {
- this.tableMetaData = tableMetaData;
- this.collectionId = collectionId;
- this.isReadOnly = isReadOnly;
- if (collectionId == -1) {
- this.isNew = true;
- }
- }
-
- public ConditionsRecord getConditionsRecord() {
- return conditionsRecord;
- }
-
- public ObjectType get(int index) {
- return objects.get(index);
- }
-
- public List<ObjectType> getObjects() {
- return Collections.unmodifiableList(objects);
- }
-
- public boolean contains(Object object) {
- return getObjects().contains(object);
- }
-
- // TODO: Should check here if object has an existing collection ID that is
- // different
- // from this collection's, in which case this collection becomes "mixed" and
- // it should
- // be
- // flagged as read only.
- public void add(ObjectType object) throws ConditionsObjectException {
- if (objects.contains(object)) {
- throw new IllegalArgumentException("Collection already contains this object.");
- }
- try {
- // Only assign a collection ID to the object if this collection has
- // a valid ID
- // and the object does not have one already.
- if (getCollectionId() != -1)
- object.setCollectionId(getCollectionId());
- } catch (ConditionsObjectException x) {
- throw new IllegalArgumentException("Error assigning collection ID to object.", x);
- }
- // Set the table meta data on the object if it does not have any.
- if (object.getTableMetaData() == null && tableMetaData != null)
- object.setTableMetaData(tableMetaData);
- objects.add(object);
- if (!isNew())
- setIsDirty(true);
- }
-
- public TableMetaData getTableMetaData() {
- return tableMetaData;
- }
-
- public int getCollectionId() {
- return collectionId;
- }
-
- // TODO: Should this also insert new records that do not exist?
- // TODO: This operation should lock the table.
- public void update() throws ConditionsObjectException {
- for (ConditionsObject object : objects) {
- object.update();
- }
- setIsDirty(false);
- }
-
- // TODO: This does not need to loop. It should just call delete on the
- // collection ID
- // value.
- public void delete() throws ConditionsObjectException {
- if (isReadOnly()) {
- throw new ConditionsObjectException("Collection is read only.");
- }
- for (ConditionsObject object : objects) {
- object.delete();
- }
- }
-
- // TODO: This should not loop. It should select all the objects with a
- // matching
- // collection ID
- // from the database.
- public void select() throws ConditionsObjectException, SQLException {
- for (ConditionsObject object : objects) {
- object.select();
- }
- }
-
- // TODO: This method needs to get the next collection ID from the conditions
- // manager.
- // TODO: This operation should lock the table.
- public void insert() throws ConditionsObjectException, SQLException {
- if (!isNew()) {
- throw new ConditionsObjectException("Collection already exists in the database.");
- }
- for (ConditionsObject object : objects) {
- // if (object.isNew()) {
- object.insert();
- // }
- }
- isNew = false;
- }
-
- public boolean isDirty() {
- return isDirty;
- }
-
- public boolean isReadOnly() {
- return isReadOnly;
- }
-
- void setIsDirty(boolean isDirty) {
- this.isDirty = isDirty;
- }
-
- // TODO: This can probably just check if collection ID is not valid e.g.
- // equals -1.
- public boolean isNew() {
- return isNew;
- }
-
- public void setCollectionId(int collectionId) throws ConditionsObjectException {
- if (this.collectionId != -1)
- throw new ConditionsObjectException("The collection ID is already set.");
- this.collectionId = collectionId;
- }
-
- public void setTableMetaData(TableMetaData tableMetaData) {
- this.tableMetaData = tableMetaData;
- }
-
- public void setIsReadOnly(boolean isReadOnly) {
- this.isReadOnly = isReadOnly;
- }
-
- public void setConditionsRecord(ConditionsRecord conditionsRecord) throws ConditionsObjectException {
- if (this.conditionsRecord != null)
- throw new ConditionsObjectException("The ConditionsRecord is already set on this collection.");
- this.conditionsRecord = conditionsRecord;
- }
-
- @Override
- public Iterator<ObjectType> iterator() {
- return objects.iterator();
- }
-}
+package org.hps.conditions;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class ConditionsObjectCollection<ObjectType extends ConditionsObject> implements Iterable<ObjectType> {
+
+ protected Set<ObjectType> objects = new LinkedHashSet<ObjectType>();
+ protected TableMetaData tableMetaData;
+ protected int collectionId = -1;
+ protected boolean isReadOnly;
+ protected boolean isDirty;
+ protected boolean isNew;
+ protected ConditionsRecord conditionsRecord;
+
+ protected ConditionsObjectCollection() {
+ }
+
+ public ConditionsObjectCollection(TableMetaData tableMetaData, int collectionId, boolean isReadOnly) {
+ this.tableMetaData = tableMetaData;
+ this.collectionId = collectionId;
+ this.isReadOnly = isReadOnly;
+ if (collectionId == -1) {
+ this.isNew = true;
+ }
+ }
+
+ public ConditionsRecord getConditionsRecord() {
+ return conditionsRecord;
+ }
+
+ public ObjectType get(int index) {
+ Iterator<ObjectType> iterator = objects.iterator();
+ ObjectType current = iterator.next();
+ for (int i = 0; i < index; i++) {
+ current = iterator.next();
+ }
+ return current;
+ }
+
+ public Set<ObjectType> getObjects() {
+ return Collections.unmodifiableSet(objects);
+ }
+
+ public boolean contains(Object object) {
+ return getObjects().contains(object);
+ }
+
+ // TODO: Should check here if object has an existing collection ID that is
+ // different from this collection's, in which case this collection becomes "mixed" and
+ // it should be flagged as read only.
+ public void add(ObjectType object) throws ConditionsObjectException {
+ if (objects.contains(object)) {
+ throw new IllegalArgumentException("Collection already contains this object.");
+ }
+ try {
+ // Only assign a collection ID to the object if this collection has a valid ID
+ // and the object does not have one already.
+ if (getCollectionId() != -1)
+ object.setCollectionId(getCollectionId());
+ } catch (ConditionsObjectException x) {
+ throw new IllegalArgumentException("Error assigning collection ID to object.", x);
+ }
+ // Set the table meta data on the object if it does not have any.
+ if (object.getTableMetaData() == null && tableMetaData != null)
+ object.setTableMetaData(tableMetaData);
+ objects.add(object);
+ if (!isNew())
+ setIsDirty(true);
+ }
+
+ public TableMetaData getTableMetaData() {
+ return tableMetaData;
+ }
+
+ public int getCollectionId() {
+ return collectionId;
+ }
+
+ // TODO: Should this also insert new records that do not exist?
+ // TODO: This operation should lock the table.
+ public void update() throws ConditionsObjectException {
+ for (ConditionsObject object : objects) {
+ object.update();
+ }
+ setIsDirty(false);
+ }
+
+ // TODO: This does not need to loop. It should just call delete on the
+ // collection ID value.
+ public void delete() throws ConditionsObjectException {
+ if (isReadOnly()) {
+ throw new ConditionsObjectException("Collection is read only.");
+ }
+ for (ConditionsObject object : objects) {
+ object.delete();
+ }
+ }
+
+ // TODO: This should not loop. It should select all the objects with a
+ // matching collection ID from the database.
+ public void select() throws ConditionsObjectException, SQLException {
+ for (ConditionsObject object : objects) {
+ object.select();
+ }
+ }
+
+ // TODO: This method needs to get the next collection ID from the conditions
+ // manager.
+ // TODO: This operation should lock the table.
+ public void insert() throws ConditionsObjectException, SQLException {
+ if (!isNew()) {
+ throw new ConditionsObjectException("Collection already exists in the database.");
+ }
+ for (ConditionsObject object : objects) {
+ // if (object.isNew()) {
+ object.insert();
+ // }
+ }
+ isNew = false;
+ }
+
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ void setIsDirty(boolean isDirty) {
+ this.isDirty = isDirty;
+ }
+
+ // TODO: This can probably just check if collection ID is not valid e.g. equals -1.
+ public boolean isNew() {
+ return isNew;
+ }
+
+ public void setCollectionId(int collectionId) throws ConditionsObjectException {
+ if (this.collectionId != -1)
+ throw new ConditionsObjectException("The collection ID is already set.");
+ this.collectionId = collectionId;
+ }
+
+ public void setTableMetaData(TableMetaData tableMetaData) {
+ this.tableMetaData = tableMetaData;
+ }
+
+ public void setIsReadOnly(boolean isReadOnly) {
+ this.isReadOnly = isReadOnly;
+ }
+
+ public void setConditionsRecord(ConditionsRecord conditionsRecord) throws ConditionsObjectException {
+ if (this.conditionsRecord != null)
+ throw new ConditionsObjectException("The ConditionsRecord is already set on this collection.");
+ this.conditionsRecord = conditionsRecord;
+ }
+
+ @Override
+ public Iterator<ObjectType> iterator() {
+ return objects.iterator();
+ }
+}
|