mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-15 06:58:41 +00:00
docs: update master-worker
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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;
|
||||
import com.iluwatar.masterworker.system.MasterWorker;
|
||||
import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
|
||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <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>
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
|
||||
public static void main(String[] args) {
|
||||
var mw = new ArrayTransposeMasterWorker();
|
||||
var rows = 10;
|
||||
var columns = 20;
|
||||
var inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows, columns);
|
||||
var input = new ArrayInput(inputMatrix);
|
||||
var result = (ArrayResult) mw.getResult(input);
|
||||
if (result != null) {
|
||||
ArrayUtilityMethods.printMatrix(inputMatrix);
|
||||
ArrayUtilityMethods.printMatrix(result.data);
|
||||
} else {
|
||||
LOGGER.info("Please enter non-zero input");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
var initialDivision = data.length / num; //equally dividing
|
||||
var divisions = new int[num];
|
||||
Arrays.fill(divisions, initialDivision);
|
||||
if (initialDivision * num != data.length) {
|
||||
var extra = data.length - initialDivision * num;
|
||||
var 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 List<Input<int[][]>> divideData(int num) {
|
||||
if (this.data == null) {
|
||||
return null;
|
||||
} else {
|
||||
var divisions = makeDivisions(this.data, num);
|
||||
var result = new ArrayList<Input<int[][]>>(num);
|
||||
var rowsDone = 0; //number of rows divided so far
|
||||
for (var i = 0; i < num; i++) {
|
||||
var rows = divisions[i];
|
||||
if (rows != 0) {
|
||||
var divided = new int[rows][this.data[0].length];
|
||||
System.arraycopy(this.data, rowsDone, divided, 0, rows);
|
||||
rowsDone += rows;
|
||||
var dividedInput = new ArrayInput(divided);
|
||||
result.add(dividedInput);
|
||||
} else {
|
||||
break; //rest of divisions will also be 0
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.security.SecureRandom;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Class ArrayUtilityMethods has some utility methods for matrices and arrays.
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class ArrayUtilityMethods {
|
||||
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
var answer = false;
|
||||
for (var 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 {
|
||||
var answer = false;
|
||||
for (var 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) {
|
||||
var matrix = new int[rows][columns];
|
||||
for (var i = 0; i < rows; i++) {
|
||||
for (var j = 0; j < columns; j++) {
|
||||
//filling cells in matrix
|
||||
matrix[i][j] = RANDOM.nextInt(10);
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method printMatrix prints input matrix @param matrix.
|
||||
*/
|
||||
|
||||
public static void printMatrix(int[][] matrix) {
|
||||
//prints out int[][]
|
||||
for (var ints : matrix) {
|
||||
for (var j = 0; j < matrix[0].length; j++) {
|
||||
LOGGER.info(ints[j] + " ");
|
||||
}
|
||||
LOGGER.info("");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.List;
|
||||
|
||||
/**
|
||||
* 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 List<Input<T>> divideData(int num);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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();
|
||||
}
|
||||
}
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 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.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
//i+1 will be id
|
||||
return IntStream.range(0, num)
|
||||
.mapToObj(i -> new ArrayTransposeWorker(this, i + 1))
|
||||
.collect(Collectors.toCollection(() -> new ArrayList<>(num)));
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayResult aggregateData() {
|
||||
// number of rows in final result is number of rows in any of obtained results from workers
|
||||
var allResultData = this.getAllResultData();
|
||||
var rows = ((ArrayResult) allResultData.elements().nextElement()).data.length;
|
||||
var elements = allResultData.elements();
|
||||
var columns = 0; // columns = sum of number of columns in all results obtained from workers
|
||||
while (elements.hasMoreElements()) {
|
||||
columns += ((ArrayResult) elements.nextElement()).data[0].length;
|
||||
}
|
||||
var resultData = new int[rows][columns];
|
||||
var columnsDone = 0; //columns aggregated so far
|
||||
var workers = this.getWorkers();
|
||||
for (var i = 0; i < this.getExpectedNumResults(); i++) {
|
||||
//result obtained from ith worker
|
||||
var worker = workers.get(i);
|
||||
var workerId = worker.getWorkerId();
|
||||
var work = ((ArrayResult) allResultData.get(workerId)).data;
|
||||
for (var m = 0; m < work.length; m++) {
|
||||
//m = row number, n = columns number
|
||||
System.arraycopy(work[m], 0, resultData[m], columnsDone, work[0].length);
|
||||
}
|
||||
columnsDone += work[0].length;
|
||||
}
|
||||
return new ArrayResult(resultData);
|
||||
}
|
||||
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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 com.iluwatar.masterworker.Input;
|
||||
import com.iluwatar.masterworker.Result;
|
||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 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 List<Worker> workers;
|
||||
private final Hashtable<Integer, Result<?>> allResultData;
|
||||
private int expectedNumResults;
|
||||
@Getter
|
||||
private Result<?> finalResult;
|
||||
|
||||
Master(int numOfWorkers) {
|
||||
this.numOfWorkers = numOfWorkers;
|
||||
this.workers = setWorkers(numOfWorkers);
|
||||
this.expectedNumResults = 0;
|
||||
this.allResultData = new Hashtable<>(numOfWorkers);
|
||||
this.finalResult = null;
|
||||
}
|
||||
|
||||
Hashtable<Integer, Result<?>> getAllResultData() {
|
||||
return this.allResultData;
|
||||
}
|
||||
|
||||
int getExpectedNumResults() {
|
||||
return this.expectedNumResults;
|
||||
}
|
||||
|
||||
List<Worker> getWorkers() {
|
||||
return this.workers;
|
||||
}
|
||||
|
||||
abstract List<Worker> setWorkers(int num);
|
||||
|
||||
public void doWork(Input<?> input) {
|
||||
divideWork(input);
|
||||
}
|
||||
|
||||
private void divideWork(Input<?> input) {
|
||||
var dividedInput = input.divideData(numOfWorkers);
|
||||
if (dividedInput != null) {
|
||||
this.expectedNumResults = dividedInput.size();
|
||||
for (var 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).start();
|
||||
}
|
||||
for (var i = 0; i < this.expectedNumResults; i++) {
|
||||
try {
|
||||
this.workers.get(i).join();
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("Error while executing thread");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void receiveData(Result<?> data, Worker w) {
|
||||
// check if we 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();
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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
|
||||
var arrayInput = (ArrayInput) this.getReceivedData();
|
||||
final var rows = arrayInput.data[0].length;
|
||||
final var cols = arrayInput.data.length;
|
||||
var resultData = new int[rows][cols];
|
||||
for (var i = 0; i < cols; i++) {
|
||||
for (var j = 0; j < rows; j++) {
|
||||
//flipping element positions along diagonal
|
||||
resultData[j][i] = arrayInput.data[i][j];
|
||||
}
|
||||
}
|
||||
return new ArrayResult(resultData);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@Getter
|
||||
private final int workerId;
|
||||
private Input<?> receivedData;
|
||||
|
||||
Worker(Master master, int id) {
|
||||
this.master = master;
|
||||
this.workerId = id;
|
||||
this.receivedData = null;
|
||||
}
|
||||
|
||||
Input<?> getReceivedData() {
|
||||
return this.receivedData;
|
||||
}
|
||||
|
||||
public void setReceivedData(Master m, Input<?> i) {
|
||||
// check if we are 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
|
||||
var work = executeOperation();
|
||||
sendToMaster(work);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user