diff --git a/.travis.yml b/.travis.yml
index 8a29df8..f4ff54d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
language: java
jdk: oraclejdk8
-install:
-- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
+before_install:
+ - chmod +x buildscript
script: ./buildscript
os: linux
\ No newline at end of file
diff --git a/buildscript b/buildscript
old mode 100644
new mode 100755
index d806e9e..2bd19ce
--- a/buildscript
+++ b/buildscript
@@ -1 +1,9 @@
-mvn test -B
\ No newline at end of file
+rootdir=$(pwd)
+for dir in $(find . -maxdepth 1 -type d); do
+ if [ "$dir" != "." ] && [ "$dir" != "./.git" ]; then
+ cd $dir
+ mvn test -B
+ cd $rootdir
+ fi
+done
+
diff --git a/hw1pool/.idea/checkstyle-idea.xml b/hw1pool/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000..7b2331a
--- /dev/null
+++ b/hw1pool/.idea/checkstyle-idea.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/.idea/compiler.xml b/hw1pool/.idea/compiler.xml
new file mode 100644
index 0000000..f1eb2ae
--- /dev/null
+++ b/hw1pool/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/.idea/misc.xml b/hw1pool/.idea/misc.xml
new file mode 100644
index 0000000..462106b
--- /dev/null
+++ b/hw1pool/.idea/misc.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/.idea/modules.xml b/hw1pool/.idea/modules.xml
new file mode 100644
index 0000000..a384a3a
--- /dev/null
+++ b/hw1pool/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/.idea/uiDesigner.xml b/hw1pool/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/hw1pool/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/hw1pool.iml b/hw1pool/hw1pool.iml
new file mode 100644
index 0000000..57bbe94
--- /dev/null
+++ b/hw1pool/hw1pool.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hw1pool/pom.xml b/hw1pool/pom.xml
new file mode 100644
index 0000000..b8d16a7
--- /dev/null
+++ b/hw1pool/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+ ru.spbau.group202.sharkova
+ hw1pool
+ 1.0-SNAPSHOT
+
+
+
+
+ junit
+ junit
+ 4.9
+ test
+
+
+
+ com.github.stefanbirkner
+ system-rules
+ 1.16.0
+ test
+
+
+
+
+ com.intellij
+ annotations
+ 12.0
+
+
+
+
+ 1.8
+ 1.8
+
+
+
\ No newline at end of file
diff --git a/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightExecutionException.java b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightExecutionException.java
new file mode 100644
index 0000000..dcaa81e
--- /dev/null
+++ b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightExecutionException.java
@@ -0,0 +1,11 @@
+package ru.spbau.group202.sharkova.hw1pool;
+
+/**
+ * This exception is thrown by LightFuture get() method
+ * whenever an exception occurred during supplier get() method execution.
+ */
+public class LightExecutionException extends Exception {
+ LightExecutionException(Exception e) {
+ super(e);
+ }
+}
diff --git a/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightFuture.java b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightFuture.java
new file mode 100644
index 0000000..0a650b2
--- /dev/null
+++ b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/LightFuture.java
@@ -0,0 +1,33 @@
+package ru.spbau.group202.sharkova.hw1pool;
+
+import java.util.function.Function;
+
+/**
+ * This interface represents a task for a thread pool.
+ * Available methods: check if the task is completed,
+ * get task result, chain the execution result to another task.
+ * @param task execution result type parameter
+ * */
+public interface LightFuture {
+ /**
+ * Indicates the state of the task.
+ * @return true if the task is completed.
+ */
+ boolean isReady();
+
+ /**
+ * Returns task execution result;
+ * if not completed, waits until the execution is finished.
+ * @throws LightExecutionException if the corresponding supplier
+ * throws an exception.
+ * */
+ T get() throws LightExecutionException;
+
+ /**
+ * Takes current task result and applies a given Function object
+ * to it, creating a new task.
+ * @param function the task that uses the current task result
+ * @return a new task
+ * */
+ LightFuture thenApply(Function function);
+}
diff --git a/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/ThreadPool.java b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/ThreadPool.java
new file mode 100644
index 0000000..4158566
--- /dev/null
+++ b/hw1pool/src/main/java/ru/spbau/group202/sharkova/hw1pool/ThreadPool.java
@@ -0,0 +1,129 @@
+package ru.spbau.group202.sharkova.hw1pool;
+
+import java.util.ArrayList;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * Thread pool implementation.
+ * Uses a given number of threads to execute LightFuture tasks.
+ * @param task return type parameter
+ */
+public class ThreadPool {
+ private ArrayList threads = new ArrayList<>();
+ private final Queue tasks = new ConcurrentLinkedQueue<>();
+
+ public ThreadPool(int numberOfThreads) {
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads.add(new Thread(new ThreadPoolTask()));
+ threads.get(i).setDaemon(true);
+ threads.get(i).start();
+ }
+ }
+
+ /**
+ * Add a new task to the queue.
+ * @param supplier provides a job to be executed
+ * @return LightFuture task encapsulating the provided supplier
+ */
+ public LightFuture add(Supplier supplier) {
+ LightFutureTask task = new LightFutureTask(supplier);
+
+ synchronized (tasks) {
+ tasks.add(task);
+ }
+
+ return task;
+ }
+
+ /**
+ * Interrupts all threads in the pool.
+ */
+ public void shutdown() {
+ for (Thread thread : threads) {
+ thread.interrupt();
+ }
+ }
+
+ /**
+ * Utility class implementing LightFuture interface.
+ */
+ private class LightFutureTask implements LightFuture{
+ private boolean isReady;
+ private T result;
+ private Exception exception;
+ private Supplier supplier;
+
+ public LightFutureTask(Supplier supplier) {
+ this.supplier = supplier;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isReady() {
+ return isReady;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T get() throws LightExecutionException {
+ while (!isReady()) {
+ Thread.yield();
+ }
+
+ if (exception != null) {
+ throw new LightExecutionException(exception);
+ }
+
+ return result;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LightFuture thenApply(Function function) {
+ return add(() -> {
+ try {
+ return function.apply(get());
+ } catch (LightExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+ }
+
+ /**
+ * Utility class used for queue task executing.
+ */
+ private class ThreadPoolTask implements Runnable {
+ @Override
+ public void run() {
+ while (!Thread.interrupted()) {
+ LightFutureTask task = null;
+ synchronized (ThreadPool.this) {
+ if (!tasks.isEmpty()) {
+ task = tasks.poll();
+ }
+ }
+
+ if (task != null) {
+ try {
+ task.result = task.supplier.get();
+ } catch (Exception e) {
+ task.exception = e;
+ }
+
+ task.isReady = true;
+ }
+ }
+ }
+ }
+}
diff --git a/hw1pool/src/test/java/ru/spbau/group202/sharkova/hw1pool/ThreadPoolTest.java b/hw1pool/src/test/java/ru/spbau/group202/sharkova/hw1pool/ThreadPoolTest.java
new file mode 100644
index 0000000..db64e4f
--- /dev/null
+++ b/hw1pool/src/test/java/ru/spbau/group202/sharkova/hw1pool/ThreadPoolTest.java
@@ -0,0 +1,168 @@
+package ru.spbau.group202.sharkova.hw1pool;
+
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.function.Supplier;
+
+import static org.junit.Assert.*;
+
+/**
+ * This class tests ThreadPool methods tests
+ * and correctness of LightFuture methods implementation
+ * used inside ThreadPool.
+ */
+public class ThreadPoolTest {
+
+ private static final int numberOfIterations = 10;
+ private static final int numberOfThreads = 10;
+
+ @Test
+ public void testBasicIntegerSupplier() throws LightExecutionException {
+ ThreadPool threadPool = new ThreadPool<>(numberOfThreads);
+ LightFuture lf = threadPool.add(() -> 16);
+ assertEquals(new Integer(16), lf.get());
+ }
+
+ @Test
+ public void testIncrementalSupplier() throws LightExecutionException {
+ ThreadPool threadPool = new ThreadPool<>(numberOfThreads);
+ LightFuture lf1 = threadPool.add(new IncrementalSupplier());
+ assertEquals(new Integer(0), lf1.get());
+ threadPool.shutdown();
+ threadPool = new ThreadPool<>(1);
+ LightFuture lf2 = threadPool.add(new IncrementalSupplier());
+ assertEquals(lf1.get(), lf2.get());
+ }
+
+ @Test
+ public void testIncrementalSupplierMultipleQueries() throws LightExecutionException {
+ ThreadPool threadPool = new ThreadPool<>(numberOfThreads);
+ LightFuture lf = threadPool.add(new IncrementalSupplier());
+ for (int i = 0; i < numberOfIterations; i++) {
+ assertEquals(new Integer(0), lf.get());
+ }
+ }
+
+ @Test
+ public void testMultipleTasksMultipleQueries() throws LightExecutionException {
+ ThreadPool threadPool = new ThreadPool<>(numberOfThreads);
+ LightFuture lf1 = threadPool.add(() -> 20 * 30 * 40 - 50 + 60 - 70 + 80 * 90);
+ LightFuture lf2 = threadPool.add(() -> 31140);
+ Supplier supplier = new IncrementalSupplier();
+ LightFuture lf3 = threadPool.add(supplier);
+ LightFuture lf4 = threadPool.add(supplier);
+ LightFuture lf5 = threadPool.add(new IncrementalSupplier());
+
+ for (int i = 0; i < numberOfIterations; i++) {
+ assertEquals(lf2.get(), lf1.get());
+ }
+
+ for (int i = 0; i < numberOfIterations; i++) {
+ assertEquals(new Integer(0), lf3.get());
+ }
+
+ for (int i = 0; i < numberOfIterations; i++) {
+ assertEquals(lf3.get(), lf5.get());
+ }
+
+ for (int i = 0; i < numberOfIterations; i++) {
+ assertEquals(new Integer(1), lf4.get());
+ }
+ }
+
+ @Test
+ public void testNullSupplier() throws LightExecutionException {
+ ThreadPool