docs: update master-worker

This commit is contained in:
Ilkka Seppälä
2024-05-07 15:54:49 +03:00
parent a3b582f993
commit 9dbffa269a
22 changed files with 157 additions and 118 deletions
+149
View File
@@ -0,0 +1,149 @@
---
title: Master-Worker
category: Concurrency
language: en
tag:
- Multithreading
- Performance
- Scalability
---
## Also known as
* Master-Slave
* Controller-Worker
## Intent
The Master-Worker pattern is designed to perform parallel computations through the division of labor between coordinating 'master' processes and multiple 'worker' processes.
## Explanation
Real World Example
> Imagine a large restaurant kitchen where the head chef acts as the "master" and the line cooks serve as "workers." The head chef receives the orders from the dining area and breaks down each order into specific tasks, such as grilling meat, preparing salads, and cooking desserts. Each task is assigned to a different line cook based on their expertise and current workload. The line cooks work in parallel to prepare their portion of the order, while the head chef oversees the process, ensuring everything is prepared correctly and timely. Once each component of the order is ready, the head chef gathers all parts, gives them a final check, and then plates the dishes for service. This kitchen operation mimics the Master-Worker pattern by distributing and managing tasks to optimize efficiency and output.
In Plain Words
> The Master-Worker pattern involves a master process delegating tasks to multiple worker processes, which execute them concurrently and report back, optimizing parallel task processing and throughput.
Wikipedia Says
> Masterslave is a model of asymmetric communication or control where one device or process (the master) controls one or more other devices or processes (the slaves) and serves as their communication hub. In some systems, a master is selected from a group of eligible devices, with the other devices acting in the role of slaves.
**Programmatic Example**
The Master-Worker pattern is a design pattern that is used for parallel processing. It involves a master component that divides a task into subtasks and distributes them among worker components. The workers process the subtasks independently and return the results to the master, which then aggregates the results to form the final output.
```java
// The MasterWorker class acts as the main entry point for the Master-Worker system.
public class MasterWorker {
private Master master;
public MasterWorker(Master master) {
this.master = master;
}
public Result getResult(Input input) {
return master.computeResult(input);
}
}
```
In this code, the `MasterWorker` class is initialized with a `Master` object. The `getResult` method is used to start the computation process.
```java
// The Master class is responsible for dividing the work among the workers.
public abstract class Master {
protected List<Worker> workers;
public Master(List<Worker> workers) {
this.workers = workers;
}
public abstract Result computeResult(Input input);
}
```
The `Master` class has a list of `Worker` objects. The `computeResult` method is abstract and should be implemented in a subclass to define how the work is divided and how the results are aggregated.
```java
// The Worker class is responsible for performing the actual computation.
public abstract class Worker extends Thread {
protected Input input;
public void setInput(Input input) {
this.input = input;
}
public abstract Result compute();
}
```
The `Worker` class extends `Thread`, allowing it to perform computations in parallel. The `compute` method is abstract and should be implemented in a subclass to define the actual computation logic.
```java
// The Input and Result classes are used to encapsulate the input data and the result 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);
}
public abstract class Result<T> {
public final T data;
public Result(T data) {
this.data = data;
}
}
```
The `Input` class has a `divideData` method that is used to divide the input data into subtasks. The `Result` class simply encapsulates the result data.
## Class diagram
![Master-Worker](./etc/master-worker-pattern.urm.png "Master-Worker pattern class diagram")
## Applicability
* Suitable for scenarios where a task can be decomposed into smaller, independent tasks.
* Useful in applications requiring concurrent execution to enhance performance.
* Applicable in distributed computing where tasks need to be processed by multiple processors or machines.
## Known Uses
* Implemented in distributed systems to manage tasks across different computing resources.
* Used in server architectures to process multiple client requests simultaneously.
* Utilized in scientific computation frameworks where large datasets require parallel processing.
## Consequences
Benefits:
* Enhances performance by parallelizing tasks.
* Increases responsiveness of systems handling large volumes of requests.
* Provides a clear separation of concerns between task coordination and task execution, simplifying design.
Trade-offs:
* Complexity in managing synchronization and state consistency between master and workers.
* Overhead of managing communication between master and workers, especially in distributed environments.
## Related Patterns
* Task Parallelism and Data Parallelism: Master-Worker utilizes these patterns to divide work into tasks or data segments.
* Producer-Consumer: Similar in structure but focuses on balancing production and consumption rates; Master-Worker is more about task distribution and aggregation.
* Pipeline: Both organize processing steps but Pipeline arranges them linearly whereas Master-Worker may not impose such a sequence.
## Credits
* [Distributed Systems: Principles and Paradigms](https://amzn.to/3UN2vbH)
* [Java Concurrency in Practice](https://amzn.to/4aRMruW)
* [Pattern-Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects](https://amzn.to/3UgC24V)
* [Master-Worker Pattern](https://docs.gigaspaces.com/sbp/master-worker-pattern.html)
* [The Master-Slave Design Pattern](https://www.cs.sjsu.edu/~pearce/oom/patterns/behavioral/masterslave.htm)
Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

@@ -0,0 +1,78 @@
@startuml
package com.iluwatar.masterworker.system.systemmaster {
class ArrayTransposeMaster {
+ ArrayTransposeMaster(numOfWorkers : int)
~ aggregateData() : ArrayResult
~ setWorkers(num : int) : ArrayList<Worker>
}
abstract class Master {
- allResultData : Hashtable<Integer, Result<T>>
- expectedNumResults : int
- finalResult : Result<T>
- numOfWorkers : int
- workers : ArrayList<Worker>
~ Master(numOfWorkers : int)
~ aggregateData() : Result<T> {abstract}
- collectResult(data : Result<T>, workerId : int)
- divideWork(input : Input<T>)
+ doWork(input : Input<T>)
~ getAllResultData() : Hashtable<Integer, Result<T>>
~ getExpectedNumResults() : int
+ getFinalResult() : Result<T>
~ getWorkers() : ArrayList<Worker>
+ receiveData(data : Result<T>, w : Worker)
~ setWorkers(int) : ArrayList<Worker> {abstract}
}
}
package com.iluwatar.masterworker.system {
class ArrayTransposeMasterWorker {
+ ArrayTransposeMasterWorker()
~ setMaster(numOfWorkers : int) : Master
}
abstract class MasterWorker {
- master : Master
+ MasterWorker(numOfWorkers : int)
+ getResult(input : Input<T>) : Result<T>
~ setMaster(int) : Master {abstract}
}
}
package com.iluwatar.masterworker {
class App {
- LOGGER : Logger {static}
+ App()
+ main(args : String[]) {static}
}
class ArrayInput {
+ ArrayInput(data : int[][])
+ divideData(num : int) : ArrayList<Input<T>>
~ makeDivisions(data : int[][], num : int) : int[] {static}
}
class ArrayResult {
+ ArrayResult(data : int[][])
}
class ArrayUtilityMethods {
- LOGGER : Logger {static}
- RANDOM : Random {static}
+ ArrayUtilityMethods()
+ arraysSame(a1 : int[], a2 : int[]) : boolean {static}
+ createRandomIntMatrix(rows : int, columns : int) : int[][] {static}
+ matricesSame(m1 : int[][], m2 : int[][]) : boolean {static}
+ printMatrix(matrix : int[][]) {static}
}
abstract class Input<T> {
+ data : T
+ Input<T>(data : T)
+ divideData(int) : ArrayList<Input<T>> {abstract}
}
abstract class Result<T> {
+ data : T
+ Result<T>(data : T)
}
}
Master --> "-finalResult" Result
MasterWorker --> "-master" Master
ArrayInput --|> Input
ArrayResult --|> Result
ArrayTransposeMasterWorker --|> MasterWorker
ArrayTransposeMaster --|> Master
@enduml
+62
View File
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.26.0-SNAPSHOT</version>
</parent>
<artifactId>master-worker</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<mainClass>com.iluwatar.masterworker.App</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -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;
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -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();
}
@@ -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);
}
}
@@ -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);
}
}
@@ -0,0 +1,62 @@
/*
* 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 static com.iluwatar.masterworker.ArrayUtilityMethods.matricesSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Random;
import org.junit.jupiter.api.Test;
/**
* Testing divideData method in {@link ArrayInput} class.
*/
class ArrayInputTest {
@Test
void divideDataTest() {
var rows = 10;
var columns = 10;
var inputMatrix = new int[rows][columns];
var rand = new Random();
for (var i = 0; i < rows; i++) {
for (var j = 0; j < columns; j++) {
inputMatrix[i][j] = rand.nextInt(10);
}
}
var i = new ArrayInput(inputMatrix);
var table = i.divideData(4);
var division1 = new int[][]{inputMatrix[0], inputMatrix[1], inputMatrix[2]};
var division2 = new int[][]{inputMatrix[3], inputMatrix[4], inputMatrix[5]};
var division3 = new int[][]{inputMatrix[6], inputMatrix[7]};
var division4 = new int[][]{inputMatrix[8], inputMatrix[9]};
assertTrue(matricesSame(table.get(0).data, division1)
&& matricesSame(table.get(1).data, division2)
&& matricesSame(table.get(2).data, division3)
&& matricesSame(table.get(3).data, division4));
}
}
@@ -0,0 +1,51 @@
/*
* 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 static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/**
* Testing utility methods in {@link ArrayUtilityMethods} class.
*/
class ArrayUtilityMethodsTest {
@Test
void arraysSameTest() {
var arr1 = new int[]{1, 4, 2, 6};
var arr2 = new int[]{1, 4, 2, 6};
assertTrue(ArrayUtilityMethods.arraysSame(arr1, arr2));
}
@Test
void matricesSameTest() {
var matrix1 = new int[][]{{1, 4, 2, 6}, {5, 8, 6, 7}};
var matrix2 = new int[][]{{1, 4, 2, 6}, {5, 8, 6, 7}};
assertTrue(ArrayUtilityMethods.matricesSame(matrix1, matrix2));
}
}
@@ -0,0 +1,61 @@
/*
* 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 static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.masterworker.ArrayInput;
import com.iluwatar.masterworker.ArrayResult;
import com.iluwatar.masterworker.ArrayUtilityMethods;
import org.junit.jupiter.api.Test;
/**
* Testing getResult method in {@link ArrayTransposeMasterWorker} class.
*/
class ArrayTransposeMasterWorkerTest {
@Test
void getResultTest() {
var atmw = new ArrayTransposeMasterWorker();
var 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}
};
var 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}
};
var i = new ArrayInput(matrix);
var r = (ArrayResult) atmw.getResult(i);
assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose));
}
}
@@ -0,0 +1,52 @@
/*
* 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 static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.masterworker.ArrayInput;
import com.iluwatar.masterworker.ArrayUtilityMethods;
import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
import org.junit.jupiter.api.Test;
/**
* Testing executeOperation method in {@link ArrayTransposeWorker} class.
*/
class ArrayTransposeWorkerTest {
@Test
void executeOperationTest() {
var atm = new ArrayTransposeMaster(1);
var atw = new ArrayTransposeWorker(atm, 1);
var matrix = new int[][]{{2, 4}, {3, 5}};
var matrixTranspose = new int[][]{{2, 3}, {4, 5}};
var i = new ArrayInput(matrix);
atw.setReceivedData(atm, i);
var r = atw.executeOperation();
assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose));
}
}