Resolves checkstyle errors for remaining m (#1090)
* Reduces checkstyle errors in marker * Reduces checkstyle errors in master-worker-pattern * Reduces checkstyle errors in mediator * Reduces checkstyle errors in memento * Reduces checkstyle errors in model-view-controller * Reduces checkstyle errors in model-view-presenter * Reduces checkstyle errors in module * Reduces checkstyle errors in monad * Reduces checkstyle errors in monostate * Reduces checkstyle errors in multiton * Reduces checkstyle errors in mute-idiom * Reduces checkstyle errors in mutex
This commit is contained in:
committed by
Ilkka Seppälä
parent
3ccc9baa1a
commit
1fdc650545
@ -28,30 +28,37 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* <p>The <b><em>Master-Worker</em></b> pattern is used when the problem at hand can be solved by dividing into
|
||||
* multiple parts which need to go through the same computation and may need to be aggregated to get final result.
|
||||
* Parallel processing is performed using a system consisting of a master and some number of workers, where a
|
||||
* master divides the work among the workers, gets the result back from them and assimilates all the results to
|
||||
* give final result. The only communication is between the master and the worker - none of the workers communicate
|
||||
* among one another and the user only communicates with the master to get required job done.</p>
|
||||
* <p>In our example, we have generic abstract classes {@link MasterWorker}, {@link Master} and {@link Worker} which
|
||||
* have to be extended by the classes which will perform the specific job at hand (in this case finding transpose of
|
||||
* matrix, done by {@link ArrayTransposeMasterWorker}, {@link ArrayTransposeMaster} and {@link ArrayTransposeWorker}).
|
||||
* The Master class divides the work into parts to be given to the workers, collects the results from the workers and
|
||||
* aggregates it when all workers have responded before returning the solution. The Worker class extends the Thread
|
||||
* class to enable parallel processing, and does the work once the data has been received from the Master. The
|
||||
* MasterWorker contains a reference to the Master class, gets the input from the App and passes it on to the Master.
|
||||
* These 3 classes define the system which computes the result. We also have 2 abstract classes {@link Input} and
|
||||
* {@link Result}, which contain the input data and result data respectively. The Input class also has an abstract
|
||||
* method divideData which defines how the data is to be divided into segments. These classes are extended by
|
||||
* {@link ArrayInput} and {@link ArrayResult}.</p>
|
||||
* <p>The <b><em>Master-Worker</em></b> pattern is used when the problem at hand can be solved by
|
||||
* dividing into
|
||||
* multiple parts which need to go through the same computation and may need to be aggregated to get
|
||||
* final result. Parallel processing is performed using a system consisting of a master and some
|
||||
* number of workers, where a master divides the work among the workers, gets the result back from
|
||||
* them and assimilates all the results to give final result. The only communication is between the
|
||||
* master and the worker - none of the workers communicate among one another and the user only
|
||||
* communicates with the master to get required job done.</p>
|
||||
* <p>In our example, we have generic abstract classes {@link MasterWorker}, {@link Master} and
|
||||
* {@link Worker} which
|
||||
* have to be extended by the classes which will perform the specific job at hand (in this case
|
||||
* finding transpose of matrix, done by {@link ArrayTransposeMasterWorker}, {@link
|
||||
* ArrayTransposeMaster} and {@link ArrayTransposeWorker}). The Master class divides the work into
|
||||
* parts to be given to the workers, collects the results from the workers and aggregates it when
|
||||
* all workers have responded before returning the solution. The Worker class extends the Thread
|
||||
* class to enable parallel processing, and does the work once the data has been received from the
|
||||
* Master. The MasterWorker contains a reference to the Master class, gets the input from the App
|
||||
* and passes it on to the Master. These 3 classes define the system which computes the result. We
|
||||
* also have 2 abstract classes {@link Input} and {@link Result}, which contain the input data and
|
||||
* result data respectively. The Input class also has an abstract method divideData which defines
|
||||
* how the data is to be divided into segments. These classes are extended by {@link ArrayInput} and
|
||||
* {@link ArrayResult}.</p>
|
||||
*/
|
||||
|
||||
public class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
|
||||
@ -59,9 +66,9 @@ public class App {
|
||||
ArrayTransposeMasterWorker mw = new ArrayTransposeMasterWorker();
|
||||
int rows = 10;
|
||||
int columns = 20;
|
||||
int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows,columns);
|
||||
int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows, columns);
|
||||
ArrayInput input = new ArrayInput(inputMatrix);
|
||||
ArrayResult result = (ArrayResult) mw.getResult(input);
|
||||
ArrayResult result = (ArrayResult) mw.getResult(input);
|
||||
if (result != null) {
|
||||
ArrayUtilityMethods.printMatrix(inputMatrix);
|
||||
ArrayUtilityMethods.printMatrix(result.data);
|
||||
|
@ -27,8 +27,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*Class ArrayInput extends abstract class {@link Input} and contains data
|
||||
*of type int[][].
|
||||
* Class ArrayInput extends abstract class {@link Input} and contains data of type int[][].
|
||||
*/
|
||||
|
||||
public class ArrayInput extends Input<int[][]> {
|
||||
@ -36,7 +35,7 @@ public class ArrayInput extends Input<int[][]> {
|
||||
public ArrayInput(int[][] data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
|
||||
static int[] makeDivisions(int[][] data, int num) {
|
||||
int initialDivision = data.length / num; //equally dividing
|
||||
int[] divisions = new int[num];
|
||||
@ -81,6 +80,6 @@ public class ArrayInput extends Input<int[][]> {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,7 @@
|
||||
package com.iluwatar.masterworker;
|
||||
|
||||
/**
|
||||
*Class ArrayResult extends abstract class {@link Result} and contains data
|
||||
*of type int[][].
|
||||
* Class ArrayResult extends abstract class {@link Result} and contains data of type int[][].
|
||||
*/
|
||||
|
||||
public class ArrayResult extends Result<int[][]> {
|
||||
|
@ -23,23 +23,23 @@
|
||||
|
||||
package com.iluwatar.masterworker;
|
||||
|
||||
import java.util.Random;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
*Class ArrayUtilityMethods has some utility methods for matrices and arrays.
|
||||
* Class ArrayUtilityMethods has some utility methods for matrices and arrays.
|
||||
*/
|
||||
|
||||
public class ArrayUtilityMethods {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ArrayUtilityMethods.class);
|
||||
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* Method arraysSame compares 2 arrays @param a1 and @param a2
|
||||
* and @return whether their values are equal (boolean).
|
||||
* Method arraysSame compares 2 arrays @param a1 and @param a2 and @return whether their values
|
||||
* are equal (boolean).
|
||||
*/
|
||||
|
||||
public static boolean arraysSame(int[] a1, int[] a2) {
|
||||
@ -61,10 +61,10 @@ public class ArrayUtilityMethods {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method matricesSame compares 2 matrices @param m1 and @param m2
|
||||
* and @return whether their values are equal (boolean).
|
||||
* Method matricesSame compares 2 matrices @param m1 and @param m2 and @return whether their
|
||||
* values are equal (boolean).
|
||||
*/
|
||||
|
||||
|
||||
public static boolean matricesSame(int[][] m1, int[][] m2) {
|
||||
if (m1.length != m2.length) {
|
||||
return false;
|
||||
@ -81,12 +81,12 @@ public class ArrayUtilityMethods {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method createRandomIntMatrix creates a random matrix of size @param rows
|
||||
* and @param columns @return it (int[][]).
|
||||
* Method createRandomIntMatrix creates a random matrix of size @param rows and @param columns.
|
||||
*
|
||||
* @return it (int[][]).
|
||||
*/
|
||||
|
||||
public static int[][] createRandomIntMatrix(int rows, int columns) {
|
||||
int[][] matrix = new int[rows][columns];
|
||||
for (int i = 0; i < rows; i++) {
|
||||
@ -97,11 +97,11 @@ public class ArrayUtilityMethods {
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method printMatrix prints input matrix @param matrix.
|
||||
*/
|
||||
|
||||
|
||||
public static void printMatrix(int[][] matrix) {
|
||||
//prints out int[][]
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
@ -111,5 +111,5 @@ public class ArrayUtilityMethods {
|
||||
LOGGER.info("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -26,18 +26,19 @@ package com.iluwatar.masterworker;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*The abstract Input class, having 1 public field which contains input data,
|
||||
*and abstract method divideData.
|
||||
* The abstract Input class, having 1 public field which contains input data, and abstract method
|
||||
* divideData.
|
||||
*
|
||||
* @param <T> T will be type of data.
|
||||
*/
|
||||
|
||||
public abstract class Input<T> {
|
||||
|
||||
|
||||
public final T data;
|
||||
|
||||
|
||||
public Input(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
public abstract ArrayList<Input> divideData(int num);
|
||||
}
|
||||
|
@ -24,13 +24,13 @@
|
||||
package com.iluwatar.masterworker;
|
||||
|
||||
/**
|
||||
*The abstract Result class, which contains 1 public field containing result
|
||||
*data.
|
||||
* The abstract Result class, which contains 1 public field containing result data.
|
||||
*
|
||||
* @param <T> T will be type of data.
|
||||
*/
|
||||
|
||||
public abstract class Result<T> {
|
||||
|
||||
|
||||
public final T data;
|
||||
|
||||
public Result(T data) {
|
||||
|
@ -27,8 +27,8 @@ import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
|
||||
/**
|
||||
*Class ArrayTransposeMasterWorker extends abstract class {@link MasterWorker} and
|
||||
*specifically solves the problem of finding transpose of input array.
|
||||
* Class ArrayTransposeMasterWorker extends abstract class {@link MasterWorker} and specifically
|
||||
* solves the problem of finding transpose of input array.
|
||||
*/
|
||||
|
||||
public class ArrayTransposeMasterWorker extends MasterWorker {
|
||||
|
@ -28,7 +28,7 @@ import com.iluwatar.masterworker.Result;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
|
||||
/**
|
||||
*The abstract MasterWorker class which contains reference to master.
|
||||
* The abstract MasterWorker class which contains reference to master.
|
||||
*/
|
||||
|
||||
public abstract class MasterWorker {
|
||||
|
@ -23,16 +23,15 @@
|
||||
|
||||
package com.iluwatar.masterworker.system.systemmaster;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import com.iluwatar.masterworker.ArrayResult;
|
||||
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
|
||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
*Class ArrayTransposeMaster extends abstract class {@link Master} and contains
|
||||
*definition of aggregateData, which will obtain final result from all
|
||||
*data obtained and for setWorkers.
|
||||
* Class ArrayTransposeMaster extends abstract class {@link Master} and contains definition of
|
||||
* aggregateData, which will obtain final result from all data obtained and for setWorkers.
|
||||
*/
|
||||
|
||||
public class ArrayTransposeMaster extends Master {
|
||||
@ -43,26 +42,29 @@ public class ArrayTransposeMaster extends Master {
|
||||
@Override
|
||||
ArrayList<Worker> setWorkers(int num) {
|
||||
ArrayList<Worker> ws = new ArrayList<Worker>(num);
|
||||
for (int i = 0; i < num ; i++) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
ws.add(new ArrayTransposeWorker(this, i + 1));
|
||||
//i+1 will be id
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
ArrayResult aggregateData() {
|
||||
//number of rows in final result is number of rows in any of obtained results obtained from workers
|
||||
int rows = ((ArrayResult) this.getAllResultData().get(this.getAllResultData().keys().nextElement())).data.length;
|
||||
int columns = 0; //number of columns is sum of number of columns in all results obtained from workers
|
||||
for (Enumeration<Integer> e = this.getAllResultData().keys(); e.hasMoreElements();) {
|
||||
// number of rows in final result is number of rows in any of obtained results from workers
|
||||
int rows = ((ArrayResult) this.getAllResultData()
|
||||
.get(this.getAllResultData().keys().nextElement())).data.length;
|
||||
int columns =
|
||||
0; //number of columns is sum of number of columns in all results obtained from workers
|
||||
for (Enumeration<Integer> e = this.getAllResultData().keys(); e.hasMoreElements(); ) {
|
||||
columns += ((ArrayResult) this.getAllResultData().get(e.nextElement())).data[0].length;
|
||||
}
|
||||
int[][] resultData = new int[rows][columns];
|
||||
int columnsDone = 0; //columns aggregated so far
|
||||
for (int i = 0; i < this.getExpectedNumResults(); i++) {
|
||||
//result obtained from ith worker
|
||||
int[][] work = ((ArrayResult) this.getAllResultData().get(this.getWorkers().get(i).getWorkerId())).data;
|
||||
int[][] work =
|
||||
((ArrayResult) this.getAllResultData().get(this.getWorkers().get(i).getWorkerId())).data;
|
||||
for (int m = 0; m < work.length; m++) {
|
||||
//m = row number, n = columns number
|
||||
for (int n = 0; n < work[0].length; n++) {
|
||||
@ -73,5 +75,5 @@ public class ArrayTransposeMaster extends Master {
|
||||
}
|
||||
return new ArrayResult(resultData);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,18 +23,17 @@
|
||||
|
||||
package com.iluwatar.masterworker.system.systemmaster;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import com.iluwatar.masterworker.Input;
|
||||
import com.iluwatar.masterworker.Result;
|
||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
*The abstract Master class which contains private fields numOfWorkers
|
||||
*(number of workers), workers (arraylist of workers), expectedNumResults
|
||||
*(number of divisions of input data, same as expected number of results),
|
||||
*allResultData (hashtable of results obtained from workers, mapped by
|
||||
*their ids) and finalResult (aggregated from allResultData).
|
||||
* The abstract Master class which contains private fields numOfWorkers (number of workers), workers
|
||||
* (arraylist of workers), expectedNumResults (number of divisions of input data, same as expected
|
||||
* number of results), allResultData (hashtable of results obtained from workers, mapped by their
|
||||
* ids) and finalResult (aggregated from allResultData).
|
||||
*/
|
||||
|
||||
public abstract class Master {
|
||||
@ -43,7 +42,7 @@ public abstract class Master {
|
||||
private int expectedNumResults;
|
||||
private Hashtable<Integer, Result> allResultData;
|
||||
private Result finalResult;
|
||||
|
||||
|
||||
Master(int numOfWorkers) {
|
||||
this.numOfWorkers = numOfWorkers;
|
||||
this.workers = setWorkers(numOfWorkers);
|
||||
@ -51,46 +50,46 @@ public abstract class Master {
|
||||
this.allResultData = new Hashtable<Integer, Result>(numOfWorkers);
|
||||
this.finalResult = null;
|
||||
}
|
||||
|
||||
|
||||
public Result getFinalResult() {
|
||||
return this.finalResult;
|
||||
}
|
||||
|
||||
|
||||
Hashtable<Integer, Result> getAllResultData() {
|
||||
return this.allResultData;
|
||||
}
|
||||
|
||||
|
||||
int getExpectedNumResults() {
|
||||
return this.expectedNumResults;
|
||||
}
|
||||
|
||||
|
||||
ArrayList<Worker> getWorkers() {
|
||||
return this.workers;
|
||||
}
|
||||
|
||||
|
||||
abstract ArrayList<Worker> setWorkers(int num);
|
||||
|
||||
|
||||
public void doWork(Input input) {
|
||||
divideWork(input);
|
||||
}
|
||||
|
||||
|
||||
private void divideWork(Input input) {
|
||||
ArrayList<Input> dividedInput = input.divideData(numOfWorkers);
|
||||
if (dividedInput != null) {
|
||||
this.expectedNumResults = dividedInput.size();
|
||||
for (int i = 0; i < this.expectedNumResults; i++) {
|
||||
for (int i = 0; i < this.expectedNumResults; i++) {
|
||||
//ith division given to ith worker in this.workers
|
||||
this.workers.get(i).setReceivedData(this, dividedInput.get(i));
|
||||
this.workers.get(i).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void receiveData(Result data, Worker w) {
|
||||
//check if can receive..if yes:
|
||||
collectResult(data, w.getWorkerId());
|
||||
}
|
||||
|
||||
|
||||
private void collectResult(Result data, int workerId) {
|
||||
this.allResultData.put(workerId, data);
|
||||
if (this.allResultData.size() == this.expectedNumResults) {
|
||||
@ -98,6 +97,6 @@ public abstract class Master {
|
||||
this.finalResult = aggregateData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract Result aggregateData();
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ import com.iluwatar.masterworker.ArrayResult;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
|
||||
/**
|
||||
*Class ArrayTransposeWorker extends abstract class {@link Worker} and defines method
|
||||
*executeOperation(), to be performed on data received from master.
|
||||
* Class ArrayTransposeWorker extends abstract class {@link Worker} and defines method
|
||||
* executeOperation(), to be performed on data received from master.
|
||||
*/
|
||||
|
||||
public class ArrayTransposeWorker extends Worker {
|
||||
@ -41,12 +41,14 @@ public class ArrayTransposeWorker extends Worker {
|
||||
@Override
|
||||
ArrayResult executeOperation() {
|
||||
//number of rows in result matrix is equal to number of columns in input matrix and vice versa
|
||||
int[][] resultData = new int[((ArrayInput) this.getReceivedData()).data[0].length]
|
||||
[((ArrayInput) this.getReceivedData()).data.length];
|
||||
for (int i = 0; i < ((ArrayInput) this.getReceivedData()).data.length; i++) {
|
||||
for (int j = 0; j < ((ArrayInput) this.getReceivedData()).data[0].length; j++) {
|
||||
ArrayInput arrayInput = (ArrayInput) this.getReceivedData();
|
||||
final int rows = arrayInput.data[0].length;
|
||||
final int cols = arrayInput.data.length;
|
||||
int[][] resultData = new int[rows][cols];
|
||||
for (int i = 0; i < cols; i++) {
|
||||
for (int j = 0; j < rows; j++) {
|
||||
//flipping element positions along diagonal
|
||||
resultData[j][i] = ((ArrayInput) this.getReceivedData()).data[i][j];
|
||||
resultData[j][i] = arrayInput.data[i][j];
|
||||
}
|
||||
}
|
||||
return new ArrayResult(resultData);
|
||||
|
@ -28,9 +28,8 @@ import com.iluwatar.masterworker.Result;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
|
||||
/**
|
||||
*The abstract Worker class which extends Thread class to enable parallel
|
||||
*processing. Contains fields master(holding reference to master), workerId
|
||||
*(unique id) and receivedData(from master).
|
||||
* The abstract Worker class which extends Thread class to enable parallel processing. Contains
|
||||
* fields master(holding reference to master), workerId (unique id) and receivedData(from master).
|
||||
*/
|
||||
|
||||
public abstract class Worker extends Thread {
|
||||
@ -61,7 +60,7 @@ public abstract class Worker extends Thread {
|
||||
|
||||
private void sendToMaster(Result data) {
|
||||
this.master.receiveData(data, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() { //from Thread class
|
||||
Result work = executeOperation();
|
||||
|
Reference in New Issue
Block a user