Skip to content

Commit

Permalink
adapt to modern java syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
paxel committed Sep 24, 2023
1 parent 5732f7b commit fbda6ea
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 134 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ A: wrong. check that:

you will receive the value of x that is current at the point of time that the queued element is processed.

Q: well thats not very comfortable.
Q: well that's not very comfortable.
A: just use a CompletableFuture instead an IntConsumer and you can react to the value immediately

```java
Expand Down Expand Up @@ -163,7 +163,7 @@ The FrankenList has a single ArrayList, that contains LinkedLists.
Each LinkedList has a maximum size.
If a LinkedList reaches that size, it is split in half and the lower half inserted into the arraylist.
If a LinkedList is empty, it is removed from the ArrayList.
For each ArrayList a metaobject stores the global start index of the LinkedList.
For each ArrayList a meta-object stores the global start index of the LinkedList.

The benefit:
FrankenList has nearly random access:
Expand Down Expand Up @@ -246,7 +246,7 @@ The FrankenList has to copy all the LinkedLists to an Array and afterwards the s


### Searching an entry and use a ListFilter to manipulate the environment
The main usecase what the FrankenList was designed for was being used with a ListIterator
The main use-case what the FrankenList was designed for was being used with a ListIterator
to manipulate some values at a given position. e.g finding an entry, examining the surrounding entries and
eventually remove, replace and/or insert an entry.

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/paxel/bulkexecutor/SequentialProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public interface SequentialProcessor {
void awaitFinish() throws InterruptedException;

/**
* The Processor was aborted bcause a Runnable threw a Throwable, and the
* The Processor was aborted because a Runnable threw a Throwable, and the
* ErrorHandler decided to abort the process. The remaining Runnables were
* removed from the queue.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,39 +83,38 @@ private boolean addWithOptionalBackPressure(Runnable r, Integer threshold) {
reentrantLock.lock();
boolean offer = queue.offer(r);
// local copy to prevent changes in between.
int runStatusAfterAfterOffer = this.runStatus;
var runStatusAfterAfterOffer = this.runStatus;
if (offer) {
for (; ; ) {
switch (runStatusAfterAfterOffer) {
case IDLE: {
case IDLE -> {
/*
* There is currently no QueueRunner active for this
* Processor. We change the status and submit a QueueRunner.
*/
this.runStatus = QUEUED;
CompletableFuture<Void> future = new CompletableFuture<>();
final var future = new CompletableFuture<Void>();
// when the QueueRunner is finished, the finished method will be executed.
// adding the handle method before the submission makes sure the finished method is
// always called by the executor framework
future.handle((a, b) -> finished(b));
executorService.submit(new RunnableCompleter(queueRunner, future));
return true;
}
case QUEUED: {
case QUEUED -> {
/*
* There is currently a QueueRunner active.
* Either it already has grabbed our runnable or it will
* after it has finished.
*/
return true;
}
case ABORT: {
case ABORT -> {
// we don't accept any new jobs
queue.clear();
return false;
}
case FINISHED:
default: {
default -> {
// busy loop. the QueueRunner just finished and has to decide on the runStatus
runStatusAfterAfterOffer = this.runStatus;
}
Expand Down Expand Up @@ -185,7 +184,7 @@ The job has finished (successfully).
// mark queued after check
runStatus = QUEUED;
// we submit the QueueRunner again.
final CompletableFuture<Void> future = new CompletableFuture<>();
final var future = new CompletableFuture<Void>();
executorService.submit(new RunnableCompleter(queueRunner, future));
// and will go back into the finished method when it completes
future.handle((a, b) -> finished(b));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class QueueBatchRunner implements Runnable {
@Override
public void run() {
for (int i = 0; i < batch; i++) {
final Runnable poll = q.poll();
var poll = q.poll();
if (poll != null) {
queuePop.run();
poll.run();
Expand Down
169 changes: 64 additions & 105 deletions src/main/java/paxel/lib/Result.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
package paxel.lib;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* Rust like Result
* Rust-like Result
*
* @param <V> the value type of the Result.
* @param <E> the error type of the Result.
*/

public class Result<V, E> {

private final V value;
private final E error;
private final ResultStatus status;

public Result(V value, E error, ResultStatus status) {
this.value = value;
this.error = error;
this.status = status;
}
public record Result<V, E>(V value, E error, ResultStatus status) {

public static <V, E> Result<V, E> ok(V value) {
return new Result<>(value, null, ResultStatus.SUCCESS);
Expand All @@ -38,54 +29,41 @@ public boolean hasFailed() {
return !status.isSuccess();
}

public V getValue() {
switch (status) {
case SUCCESS:
return value;
case FAIL:
default:
throw new ResultException(String.format("No value in Result. Error was %s", verboseError()));
}
@Override
public V value() {
return switch (status) {
case SUCCESS -> value;
default -> throw new ResultException(String.format("No value in Result. Error was %s", verboseError()));
};
}

public V getValueOr(V fallBack) {
switch (status) {
case SUCCESS:
return value;
case FAIL:
default:
return fallBack;
}
return switch (status) {
case SUCCESS -> value;
default -> fallBack;
};
}

public V getValueOrGet(Supplier<V> fallBack) {
switch (status) {
case SUCCESS:
return value;
case FAIL:
default:
return fallBack.get();
}
return switch (status) {
case SUCCESS -> value;
default -> fallBack.get();
};
}

public <U, X> Result<U, X> map(Function<V, U> valueMapper, Function<E, X> errorMapper) {
switch (status) {
case SUCCESS:
return Result.ok(valueMapper.apply(value));
case FAIL:
default:
return Result.err(errorMapper.apply(error));
}
return switch (status) {
case SUCCESS -> Result.ok(valueMapper.apply(value));
default -> Result.err(errorMapper.apply(error));
};
}

public <U, X> Result<U, X> mapValue(Function<V, U> valueMapper) {
switch (status) {
case SUCCESS:
return Result.ok(valueMapper.apply(value));
case FAIL:
default:
throw new IllegalStateException(String.format("Can't map the value of a failed Result. Error was %s", verboseError()));
}
return switch (status) {
case SUCCESS -> Result.ok(valueMapper.apply(value));
default ->
throw new IllegalStateException(String.format("Can't map the value of a failed Result. Error was %s", verboseError()));
};
}

public <U, X> Result<U, X> mapResult(Function<Result<V, E>, Result<U, X>> valueMapper) {
Expand All @@ -103,26 +81,26 @@ public <U, X> Result<U, X> mapValueToError(Function<V, X> valueToErrorMapper) {
* @return the new Status
*/
public <U, X> Result<U, X> mapError(Function<E, X> errorMapper) {
switch (status) {
case FAIL:
return Result.err(errorMapper.apply(error));
case SUCCESS:
default:
throw new IllegalStateException(String.format("Can't map the error of a successful Result. Value was %s", verboseValue()));
}
return switch (status) {
case FAIL -> Result.err(errorMapper.apply(error));
default ->
throw new IllegalStateException(String.format("Can't map the error of a successful Result. Value was %s", verboseValue()));
};
}


private String verboseValue() {
if (value == null)
return "<null> value";
return String.format("%s: %s", value.getClass().getSimpleName(), value);
return switch (value) {
case null -> "<null> value";
default -> String.format("%s: %s", value.getClass().getSimpleName(), value);
};
}

private String verboseError() {
if (error == null)
return "<null> value";
return String.format("%s: %s", error.getClass().getSimpleName(), error);
return switch (error) {
case null -> "<null> error";
default -> String.format("%s: %s", error.getClass().getSimpleName(), error);
};
}

/**
Expand All @@ -131,50 +109,34 @@ private String verboseError() {
* @return the Error
* @throws ResultException if the Result is successful.
*/
public E getError() {
switch (status) {
case FAIL:
return error;
case SUCCESS:
default:
throw new ResultException("No error in Result. Value was " + value);
}
@Override
public E error() {
return switch (status) {
case FAIL -> error;
default -> throw new ResultException("No error in Result. Value was " + value);
};
}

public ResultStatus getStatus() {
return this.status;
}

public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Result)) return false;
final Result<?, ?> other = (Result<?, ?>) o;
if (!other.canEqual((Object) this)) return false;
final Object this$value = this.value;
final Object other$value = other.value;
if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
final Object this$error = this.error;
final Object other$error = other.error;
if (this$error == null ? other$error != null : !this$error.equals(other$error)) return false;
final Object this$status = this.status;
final Object other$status = other.status;
if (this$status == null ? other$status != null : !this$status.equals(other$status)) return false;
return true;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;

protected boolean canEqual(final Object other) {
return other instanceof Result;
if (!(o instanceof Result<?, ?> result))
return false;
if (!Objects.equals(value, result.value))
return false;
if (!Objects.equals(error, result.error))
return false;
return status == result.status;
}

@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $value = this.value;
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
final Object $error = this.error;
result = result * PRIME + ($error == null ? 43 : $error.hashCode());
final Object $status = this.status;
result = result * PRIME + ($status == null ? 43 : $status.hashCode());
int result = value != null ? value.hashCode() : 0;
result = 31 * result + (error != null ? error.hashCode() : 0);
result = 31 * result + status.hashCode();
return result;
}

Expand All @@ -194,13 +156,10 @@ public boolean isSuccess() {

@Override
public String toString() {
switch (status) {
case FAIL:
return "SUCCESS:" + verboseError();
case SUCCESS:
default:
return "FAILURE:" + verboseValue();
}
return switch (status) {
case SUCCESS -> "SUCCESS:" + verboseError();
default -> "FAILURE:" + verboseValue();
};
}


Expand Down
2 changes: 1 addition & 1 deletion src/test/java/paxel/lib/ExecutorCompletionServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void testFailRunnable() {
}

@Test
public void testFailRunableWithResult() {
public void testFailRunnableWithResult() {
ExecutorCompletionService completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(1));
// the Runnable throws an exception, that is verified and converted.
completionService.submit(() -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package paxel.lib;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
Expand Down
Loading

0 comments on commit fbda6ea

Please sign in to comment.