Master worker pattern #799 (#831)

* master worker pattern

* Update App.java

* Adding new line to README.md

* Adding new line to pom.xml

* Adding new line to ArrayEquality.java

* Adding new line to Input.java

* Adding new line to Result.java

* Adding new line to ArrayTransposeMasterWorker.java

* Adding new line to ArrayTransposeMaster.java

* Adding new line to ArrayTransposeWorker.java

* Adding new line to Worker.java

* Adding new line to ArrayInputTest.java

* Adding new line ArrayTransposeMasterWorkerTest.java

* Adding new line to ArrayResult.java

* Review changes

* Update README.md
This commit is contained in:
AnaghaSasikumar
2019-02-14 02:34:16 +05:30
committed by Ilkka Seppälä
parent 55c7579983
commit 7a25c57474
19 changed files with 1016 additions and 0 deletions

View File

@ -0,0 +1,71 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
import com.iluwatar.masterworker.system.ArrayTransposeMasterWorker;
/**
* <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 {
/**
* Program entry point.
* @param args command line args
*/
public static void main(String[] args) {
ArrayTransposeMasterWorker mw = new ArrayTransposeMasterWorker();
int rows = 10;
int columns = 20;
int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows,columns);
ArrayInput input = new ArrayInput(inputMatrix);
ArrayResult result = (ArrayResult) mw.getResult(input);
if (result != null) {
ArrayUtilityMethods.printMatrix(inputMatrix);
System.out.println("");
ArrayUtilityMethods.printMatrix(result.data);
} else {
System.out.println("Please enter non-zero input");
}
}
}

View File

@ -0,0 +1,86 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
import java.util.ArrayList;
import java.util.Arrays;
/**
*Class ArrayInput extends abstract class {@link Input} and contains data
*of type int[][].
*/
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];
Arrays.fill(divisions, initialDivision);
if (initialDivision * num != data.length) {
int extra = data.length - initialDivision * num;
int l = 0;
//equally dividing extra among all parts
while (extra > 0) {
divisions[l] = divisions[l] + 1;
extra--;
if (l == num - 1) {
l = 0;
} else {
l++;
}
}
}
return divisions;
}
@Override
public ArrayList<Input> divideData(int num) {
if (this.data == null) {
return null;
} else {
int[] divisions = makeDivisions(this.data, num);
ArrayList<Input> result = new ArrayList<Input>(num);
int rowsDone = 0; //number of rows divided so far
for (int i = 0; i < num; i++) {
int rows = divisions[i];
if (rows != 0) {
int[][] divided = new int[rows][this.data[0].length];
for (int j = 0; j < rows; j++) {
divided[j] = this.data[rowsDone + j];
}
rowsDone += rows;
ArrayInput dividedInput = new ArrayInput(divided);
result.add(dividedInput);
} else {
break; //rest of divisions will also be 0
}
}
return result;
}
}
}

View File

@ -0,0 +1,36 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
/**
*Class ArrayResult extends abstract class {@link Result} and contains data
*of type int[][].
*/
public class ArrayResult extends Result<int[][]> {
public ArrayResult(int[][] data) {
super(data);
}
}

View File

@ -0,0 +1,110 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
import java.util.Random;
/**
*Class ArrayUtilityMethods has some utility methods for matrices and arrays.
*/
public class ArrayUtilityMethods {
/**
* 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) {
//compares if 2 arrays have the same value
if (a1.length != a2.length) {
return false;
} else {
boolean answer = false;
for (int i = 0; i < a1.length; i++) {
if (a1[i] == a2[i]) {
answer = true;
} else {
answer = false;
break;
}
}
return answer;
}
}
/**
* 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;
} else {
boolean answer = false;
for (int i = 0; i < m1.length; i++) {
if (arraysSame(m1[i], m2[i])) {
answer = true;
} else {
answer = false;
break;
}
}
return answer;
}
}
/**
* 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];
Random rand = new Random();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
//filling cells in matrix
matrix[i][j] = rand.nextInt(10);
}
}
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++) {
for (int j = 0; j < matrix[0].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println("");
}
}
}

View File

@ -0,0 +1,43 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
import java.util.ArrayList;
/**
*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);
}

View File

@ -0,0 +1,39 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
/**
*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) {
this.data = data;
}
}

View File

@ -0,0 +1,44 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system;
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.
*/
public class ArrayTransposeMasterWorker extends MasterWorker {
public ArrayTransposeMasterWorker() {
super(4);
}
@Override
Master setMaster(int numOfWorkers) {
return new ArrayTransposeMaster(numOfWorkers);
}
}

View File

@ -0,0 +1,48 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system;
import com.iluwatar.masterworker.Input;
import com.iluwatar.masterworker.Result;
import com.iluwatar.masterworker.system.systemmaster.Master;
/**
*The abstract MasterWorker class which contains reference to master.
*/
public abstract class MasterWorker {
private final Master master;
public MasterWorker(int numOfWorkers) {
this.master = setMaster(numOfWorkers);
}
abstract Master setMaster(int numOfWorkers);
public Result getResult(Input input) {
this.master.doWork(input);
return this.master.getFinalResult();
}
}

View File

@ -0,0 +1,77 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
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;
/**
*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 {
public ArrayTransposeMaster(int numOfWorkers) {
super(numOfWorkers);
}
@Override
ArrayList<Worker> setWorkers(int num) {
ArrayList<Worker> ws = new ArrayList<Worker>(num);
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();) {
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;
for (int m = 0; m < work.length; m++) {
//m = row number, n = columns number
for (int n = 0; n < work[0].length; n++) {
resultData[m][columnsDone + n] = work[m][n];
}
}
columnsDone += work[0].length;
}
return new ArrayResult(resultData);
}
}

View File

@ -0,0 +1,103 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
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;
/**
*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 {
private final int numOfWorkers;
private final ArrayList<Worker> workers;
private int expectedNumResults;
private Hashtable<Integer, Result> allResultData;
private Result finalResult;
Master(int numOfWorkers) {
this.numOfWorkers = numOfWorkers;
this.workers = setWorkers(numOfWorkers);
this.expectedNumResults = 0;
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++) {
//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) {
//all data received
this.finalResult = aggregateData();
}
}
abstract Result aggregateData();
}

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system.systemworkers;
import com.iluwatar.masterworker.ArrayInput;
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.
*/
public class ArrayTransposeWorker extends Worker {
public ArrayTransposeWorker(Master master, int id) {
super(master, id);
}
@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++) {
//flipping element positions along diagonal
resultData[j][i] = ((ArrayInput) this.getReceivedData()).data[i][j];
}
}
return new ArrayResult(resultData);
}
}

View File

@ -0,0 +1,70 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system.systemworkers;
import com.iluwatar.masterworker.Input;
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).
*/
public abstract class Worker extends Thread {
private final Master master;
private final int workerId;
private Input receivedData;
Worker(Master master, int id) {
this.master = master;
this.workerId = id;
this.receivedData = null;
}
public int getWorkerId() {
return this.workerId;
}
Input getReceivedData() {
return this.receivedData;
}
public void setReceivedData(Master m, Input i) {
//check if ready to receive..if yes:
this.receivedData = i;
}
abstract Result executeOperation();
private void sendToMaster(Result data) {
this.master.receiveData(data, this);
}
public void run() { //from Thread class
Result work = executeOperation();
sendToMaster(work);
}
}

View File

@ -0,0 +1,60 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker;
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.Random;
import org.junit.jupiter.api.Test;
/**
* Testing divideData method in {@link ArrayInput} class.
*/
class ArrayInputTest {
@Test
void divideDataTest() {
int rows = 10;
int columns = 10;
int[][] inputMatrix = new int[rows][columns];
Random rand = new Random();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
inputMatrix[i][j] = rand.nextInt(10);
}
}
ArrayInput i = new ArrayInput(inputMatrix);
ArrayList<Input> table = i.divideData(4);
int[][] division1 = new int[][] {inputMatrix[0], inputMatrix[1], inputMatrix[2]};
int[][] division2 = new int[][] {inputMatrix[3], inputMatrix[4], inputMatrix[5]};
int[][] division3 = new int[][] {inputMatrix[6], inputMatrix[7]};
int[][] division4 = new int[][] {inputMatrix[8], inputMatrix[9]};
assertTrue(ArrayUtilityMethods.matricesSame((int[][]) table.get(0).data, division1)
&& ArrayUtilityMethods.matricesSame((int[][]) table.get(1).data, division2)
&& ArrayUtilityMethods.matricesSame((int[][]) table.get(2).data, division3)
&& ArrayUtilityMethods.matricesSame((int[][]) table.get(3).data, division4));
}
}

View File

@ -0,0 +1,27 @@
package com.iluwatar.masterworker;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* Testing utility methods in {@link ArrayUtilityMethods} class.
*/
class ArrayUtilityMethodsTest {
@Test
void arraysSameTest() {
int[] arr1 = new int[] {1,4,2,6};
int[] arr2 = new int[] {1,4,2,6};
assertTrue(ArrayUtilityMethods.arraysSame(arr1, arr2));
}
@Test
void matricesSameTest() {
int[][] matrix1 = new int[][] {{1,4,2,6},{5,8,6,7}};
int[][] matrix2 = new int[][] {{1,4,2,6},{5,8,6,7}};
assertTrue(ArrayUtilityMethods.matricesSame(matrix1, matrix2));
}
}

View File

@ -0,0 +1,47 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.iluwatar.masterworker.ArrayUtilityMethods;
import com.iluwatar.masterworker.ArrayInput;
import com.iluwatar.masterworker.ArrayResult;
/**
* Testing getResult method in {@link ArrayTransposeMasterWorker} class.
*/
class ArrayTransposeMasterWorkerTest {
@Test
void getResultTest() {
ArrayTransposeMasterWorker atmw = new ArrayTransposeMasterWorker();
int[][] matrix = new int[][] {{1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}};
int[][] matrixTranspose = new int[][] {{1,1,1,1,1}, {2,2,2,2,2}, {3,3,3,3,3}, {4,4,4,4,4}, {5,5,5,5,5}};
ArrayInput i = new ArrayInput(matrix);
ArrayResult r = (ArrayResult) atmw.getResult(i);
assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose));
}
}

View File

@ -0,0 +1,51 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.masterworker.system.systemworkers;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.iluwatar.masterworker.ArrayUtilityMethods;
import com.iluwatar.masterworker.ArrayInput;
import com.iluwatar.masterworker.ArrayResult;
import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
/**
* Testing executeOperation method in {@link ArrayTransposeWorker} class.
*/
class ArrayTransposeWorkerTest {
@Test
void executeOperationTest() {
ArrayTransposeMaster atm = new ArrayTransposeMaster(1);
ArrayTransposeWorker atw = new ArrayTransposeWorker(atm, 1);
int[][] matrix = new int[][] {{2,4}, {3,5}};
int[][] matrixTranspose = new int[][] {{2,3}, {4,5}};
ArrayInput i = new ArrayInput(matrix);
atw.setReceivedData(atm, i);
ArrayResult r = atw.executeOperation();
assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose));
}
}