Commit 8e58685d authored by Cristina Cocho's avatar Cristina Cocho

First Commit of new branch called improveGetServerArrayPropertyValue.

In this branch we are testing the use of threads in order to parallelize
the obtaining of values from server that take really long times due to
its size. The idea is to unload the main GUI thread from this work.
parent e142ebf0
......@@ -38,22 +38,35 @@ public abstract class ArrayProperty extends Property {
}
/**
* Createa PVerifyListener used to ensure that Text fields allow only certain characters
* Create PVerifyListener used to ensure that Text fields allow only certain characters
* to be entered.
*/
public void setPVerifyListener() {
// do nothing for the moment.
}
public void propertyChanged(ServerPropertyChangeEvent event) {
// PREVIOUS VERSION
// if (event.getId() == id) {
// double delay = getDelay();
// double diff = System.currentTimeMillis() - lastPropertyChangedTime;
// if (diff > delay) {
// Array array = getServerArray();
// sendPropertyChangedEvent();
// lastPropertyChangedTime = System.currentTimeMillis();
// }
// }
// NEW VERSION -> keep the event filtering
System.out.println("in propertyChanged of ArrayProperty");
if (event.getId() == id) {
System.out.println("In propertyChanged of ArrayProperty for propertyId = " + id);
double delay = getDelay();
double diff = System.currentTimeMillis() - lastPropertyChangedTime;
if (diff > delay) {
Array array = getServerArray();
sendPropertyChangedEvent();
AsyncArrayPropertyReader.getInstance().getServerArrayAsync(this);
lastPropertyChangedTime = System.currentTimeMillis();
}
}
......@@ -105,13 +118,17 @@ public abstract class ArrayProperty extends Property {
*/
public abstract Array getCurrentArray();
/**
* Abstract method to get the array in the server. Takes a ServerArray containing the
* primitive array.
*/
public abstract void setServerArray(Array array);
/**
* Abstract method to update the local array stored in the ArrayProperty with the last array obtained from the server.
*/
public abstract void updateServerArray(Array array);
public void setAutoApply() {
this.undoArrayState.setAutoApply();
......
package fr.ill.ics.core.property;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import fr.ill.ics.core.property.array.Array;
public class AsyncArrayPropertyReader {
private static AsyncArrayPropertyReader instance;
private ExecutorService executorService;
private Set<ArrayProperty> arrayPropertiesPending = new HashSet<ArrayProperty>();
private Set<ArrayDataSet> arrayDataSets = new HashSet<ArrayDataSet>();
private AsyncArrayPropertyReader() {
// Create the threadPool executor
executorService = Executors.newFixedThreadPool(10); // 10 threads to execute at a time
}
public static AsyncArrayPropertyReader getInstance() {
if(instance == null) {
instance = new AsyncArrayPropertyReader();
}
return instance;
}
/**
* This method is called by the propertyChange method of the class ArrayProperty
* @param arrayProperty
*/
public void getServerArrayAsync(ArrayProperty arrayProperty) {
synchronized (arrayPropertiesPending) {
if (!arrayPropertiesPending.contains(arrayProperty)) {
arrayPropertiesPending.add(arrayProperty);
System.out.println("In AsyncArrayPropertyReader -> adding data in arrayPropertiesPending, size " +arrayPropertiesPending.size() + " arrayProperty hascode " +arrayProperty.getPropertyID());
// Add it also to the threadPool
executorService.execute(new ServerArrayReader(arrayProperty));
}
}
}
public void onReadTerminated(ArrayProperty arrayProperty, Array arrayPropertyContent) {
synchronized (arrayDataSets) {
// Create an intermediate object that contains the data from server and the property to whom this data belongs to.
arrayDataSets.add(new ArrayDataSet(arrayProperty, arrayPropertyContent));
}
// Update queue arrayPropertiesPending
synchronized (arrayPropertiesPending) {
if (arrayPropertiesPending.contains(arrayProperty)) {
arrayPropertiesPending.remove(arrayProperty);
}
}
System.out.println("In AsyncArrayPropertyReader -> onReadTerminated for property " +arrayProperty.getPropertyID() + "size of arrayPropertiesPending " +arrayPropertiesPending.size() + " size of arrayDataSets "+arrayDataSets.size());
}
public void updateServerArrays() {
synchronized (arrayDataSets) {
Iterator<ArrayDataSet> it = arrayDataSets.iterator();
while (it.hasNext()) {
ArrayDataSet arrayDataSet = it.next();
arrayDataSet.getArrayProperty().updateServerArray(arrayDataSet.getArrayPropertyContent());
it.remove(); //!!!
System.out.println("in updateServerArrays, size of arrayDataSets "+arrayDataSets.size() + " size of arrayPropertiesPending "+arrayPropertiesPending.size());
}
}
}
private class ServerArrayReader implements Runnable {
private ArrayProperty arrayProperty;
public ServerArrayReader(ArrayProperty arrayProperty) {
this.arrayProperty = arrayProperty;
}
@Override
public void run() {
// Do the call the to server
Array array = arrayProperty.getServerArray();
// When call is finished, store the data obtained in the AsyncArrayPropertyReader class
AsyncArrayPropertyReader.getInstance().onReadTerminated(arrayProperty, array);
}
}
private class ArrayDataSet {
private ArrayProperty arrayProperty;
private Array arrayPropertyContent;
public ArrayDataSet(ArrayProperty arrayProperty, Array arrayPropertyContent) {
this.arrayProperty = arrayProperty;
this.arrayPropertyContent = arrayPropertyContent;
}
public ArrayProperty getArrayProperty() {
return arrayProperty;
}
public Array getArrayPropertyContent() {
return arrayPropertyContent;
}
}
}
......@@ -28,17 +28,31 @@ public class Float64ArrayProperty extends FloatArrayProperty {
public Float64ArrayProperty(int containerId, int id, boolean isCommandBox) {
super(containerId, id, isCommandBox);
getServerArray(); // must be left here
// getServerArray(); // must be left here
}
/**
* The method getServerArray should only be called by the AsyncArrayPropertyReader class (server event)
* In the rest of the cases, that is, when the call comes from the client, we HAVE to use the method getCurrentArray
*/
public Array getServerArray() {
// PREVIOUS VERSION
// if (isCommandBox) {
// //int databaseId = CommandBoxAccessor.getInstance(serverId).getDatabaseID(containerId);
// float64Array.setArray(DataAccessor.getInstance(serverId).getFloat64Array(getDatabaseID(), id));
// } else {
// float64Array.setArray(DataAccessor.getInstance(serverId).getFloat64Array(containerId, id));
// }
// arraySize = float64Array.getSize();
// return float64Array;
// NEW VERSION
Float64Array float64Array = new Float64Array(); //Use a local instance of the array
if (isCommandBox) {
//int databaseId = CommandBoxAccessor.getInstance(serverId).getDatabaseID(containerId);
float64Array.setArray(DataAccessor.getInstance(serverId).getFloat64Array(getDatabaseID(), id));
} else {
float64Array.setArray(DataAccessor.getInstance(serverId).getFloat64Array(containerId, id));
}
arraySize = float64Array.getSize();
return float64Array;
}
......@@ -56,6 +70,16 @@ public class Float64ArrayProperty extends FloatArrayProperty {
}
}
public void updateServerArray(Array array) {
// Copy here the array content
this.float64Array = (Float64Array)array; // TODO: verify cast
// Not clear if it is needed to update the arraySize class member
this.arraySize = array.getSize();
// Notify the fact that there is a new array available. TODO: verify that only the property modified is the one called
sendPropertyChangedEvent();
}
public float getMinValue() {
return float64Array.getMinValue();
......
......@@ -24,30 +24,43 @@ import fr.ill.ics.nscclient.dataprovider.DataAccessor;
public class Int32ArrayProperty extends IntegerArrayProperty {
Int32Array int32Array = new Int32Array();
private Int32Array int32Array = new Int32Array(); // Check if that is needed!
public Int32ArrayProperty(int containerId, int id, boolean isCommandBox) {
super(containerId, id, isCommandBox);
getServerArray(); // must be left here
// getServerArray(); // must be left here
}
/**
* The method getServerArray should only be called by the AsyncArrayPropertyReader class (server event)
* In the rest of the cases, that is, when the call comes from the client, we HAVE to use the method getCurrentArray
*/
public Array getServerArray() {
// PREVIOUS VERSION
// if (isCommandBox) {
// //int databaseId = CommandBoxAccessor.getInstance(serverId).getDatabaseID(containerId);
// int32Array.setArray(DataAccessor.getInstance(serverId).getInt32Array(getDatabaseID(), id));
// } else {
// // Here is where we should not access the server
// int32Array.setArray(DataAccessor.getInstance(serverId).getInt32Array(containerId, id));
// }
// arraySize = int32Array.getSize();
// return int32Array;
// NEW VERSION
Int32Array int32Array = new Int32Array(); //Use a local instance of the array
if (isCommandBox) {
//int databaseId = CommandBoxAccessor.getInstance(serverId).getDatabaseID(containerId);
int32Array.setArray(DataAccessor.getInstance(serverId).getInt32Array(getDatabaseID(), id));
} else {
int32Array.setArray(DataAccessor.getInstance(serverId).getInt32Array(containerId, id));
}
arraySize = int32Array.getSize();
return int32Array;
}
public Array getCurrentArray() {
return int32Array;
}
public void setServerArray(Array array) {
if (isCommandBox) {
//int databaseId = CommandBoxAccessor.getInstance(serverId).getDatabaseID(containerId);
......@@ -56,6 +69,17 @@ public class Int32ArrayProperty extends IntegerArrayProperty {
DataAccessor.getInstance(serverId).setInt32Array(containerId, id, int32Array.getArray());
}
}
public void updateServerArray(Array array) {
// Copy here the array content
this.int32Array = (Int32Array)array; // TODO: verify cast
// Not clear if it is needed to update the arraySize class member
this.arraySize = array.getSize();
// Notify the fact that there is a new array available. TODO: verify that only the property modified is the one called
sendPropertyChangedEvent();
}
public float getMinValue() {
return int32Array.getMinValue();
......
......@@ -27,6 +27,9 @@ public class Float64Array extends Array {
private double[] array;
public Float64Array() {
// Create a default array with size 1 and value 0
array = new double[1];
array[0] = 0;
}
public Float64Array(int initialisationType, int size) {
......@@ -42,7 +45,6 @@ public class Float64Array extends Array {
}
}
public int getSize() {
if (array != null) {
return array.length;
......@@ -63,25 +65,29 @@ public class Float64Array extends Array {
}
public float getMinValue() {
// If min value equals the maximum float value, that means that it hasn't been found yet
if (minValue == Float.MAX_VALUE) {
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] < minValue) {
minValue = (float)array[i];
if (array != null) {
// If min value equals the maximum float value, that means that it hasn't been found yet
if (minValue == Float.MAX_VALUE) {
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] < minValue) {
minValue = (float) array[i];
}
}
}
}
}
return minValue;
}
public float getMaxValue() {
// If max value equals the minimum float value or -maximum value, that means that it hasn't been found yet
if ((maxValue == Float.MIN_VALUE) || (maxValue == -Float.MAX_VALUE)) { //Whether is strictly positive or not
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] > maxValue) {
maxValue = (float)array[i];
if (array != null) {
// If max value equals the minimum float value or -maximum value, that means that it hasn't been found yet
if ((maxValue == Float.MIN_VALUE) || (maxValue == -Float.MAX_VALUE)) { // Whether is strictly positive or not
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] > maxValue) {
maxValue = (float) array[i];
}
}
}
}
......
......@@ -26,8 +26,11 @@ public class Int32Array extends Array {
private int[] array;
public Int32Array() {
}
public Int32Array() {
// Create a default array with size 1 and value 0
array = new int[1];
array[0] = 0;
}
public Int32Array(int initialisationType, int size) {
array = new int[size];
......@@ -64,7 +67,7 @@ public class Int32Array extends Array {
public float getMinValue() {
// If min value equals the maximum float value, that means that it hasn't been found yet
if (minValue == Float.MAX_VALUE) {
if (array != null && minValue == Float.MAX_VALUE) {
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] < minValue) {
......@@ -76,12 +79,14 @@ public class Int32Array extends Array {
}
public float getMaxValue() {
// If max value equals the minimum float value or -maximum value, that means that it hasn't been found yet
if ((maxValue == Float.MIN_VALUE) || (maxValue == -Float.MAX_VALUE)) { // Whether is strictly positive or not
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] > maxValue) {
maxValue = array[i];
if (array != null) {
// If max value equals the minimum float value or -maximum value, that means that it hasn't been found yet
if ((maxValue == Float.MIN_VALUE) || (maxValue == -Float.MAX_VALUE)) { // Whether is strictly positive or not
int size = array.length;
for (int i = 0; i < size; i++) {
if (array[i] > maxValue) {
maxValue = array[i];
}
}
}
}
......
......@@ -28,7 +28,7 @@ public class AutoApplyArrayState extends UndoArrayState {
}
public Array getArray() {
return arrayProperty.getServerArray();
return arrayProperty.getCurrentArray(); //Before getServerArray
}
public void setArray(Array array) {
......
......@@ -28,7 +28,7 @@ public class UndoableArrayState extends UndoArrayState {
}
public Array getArray() {
return arrayProperty.getServerArray();
return arrayProperty.getCurrentArray(); //Before getServerArray
}
public void setArray(Array array) {
......
......@@ -42,6 +42,7 @@ import fr.ill.ics.bridge.listeners.ServerConditionChangeListener;
import fr.ill.ics.bridge.listeners.ServerConfigurationChangeListener;
import fr.ill.ics.bridge.listeners.ServerProgressChangeListener;
import fr.ill.ics.bridge.listeners.ServerPropertyChangeListener;
import fr.ill.ics.core.property.AsyncArrayPropertyReader;
import fr.ill.ics.core.property.Property;
import fr.ill.ics.core.property.PropertyManager;
import fr.ill.ics.nscclient.dataprovider.CommandDatabase;
......@@ -426,6 +427,9 @@ public class DataNotificationClient {
notifyPropertyChangeListeners(propertyData.getDatabaseId(), propertyData.getPropertyId());
// ThreadPool mechanism in test for ArrayProperties
AsyncArrayPropertyReader.getInstance().updateServerArrays();
} else if (data instanceof CommandStateChangedNotificationData) {
CommandStateChangedNotificationData commandStateData = (CommandStateChangedNotificationData)data;
notifyCommandStateChangeListeners(commandStateData.getDatabaseId(), commandStateData.getCommandId(), commandStateData.getState());
......@@ -449,8 +453,7 @@ public class DataNotificationClient {
}
}
// copy pending error eventsto unblock any server calls
// copy pending error events to unblock any server calls
Set<ServerErrorEvent> events;
synchronized (pendingServerErrors) {
events = new LinkedHashSet<ServerErrorEvent>(pendingServerErrors);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment