-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSieveActor.java
88 lines (79 loc) · 2.6 KB
/
SieveActor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package edu.coursera.concurrent;
import edu.rice.pcdp.Actor;
import edu.rice.pcdp.PCDP;
import java.util.ArrayList;
import java.util.List;
/**
* An actor-based implementation of the Sieve of Eratosthenes.
* countPrimes to determine the number of primes <= limit.
*/
public final class SieveActor extends Sieve {
/**
* {@inheritDoc}
*
* limit in parallel. You might consider how you can model the Sieve of
* Eratosthenes as a pipeline of actors, each corresponding to a single
* prime number.
*/
@Override
public int countPrimes(final int limit) {
final SieveActorActor sieveActor = new SieveActorActor(2);
PCDP.finish(() -> {
for (int i = 3; i<= limit; i+=2) {
sieveActor.send(i);
}
sieveActor.send(0);
});
int numPrimes = 0;
SieveActorActor loopActor = sieveActor;
while (loopActor != null) {
numPrimes += loopActor.numPrimes;
loopActor = loopActor.nextActor;
}
return numPrimes;
}
/**
* An actor class that helps implement the Sieve of Eratosthenes in
* parallel.
*/
public static final class SieveActorActor extends Actor {
/**
* Process a single message sent to this actor.
* @param msg Received message
*/
private static final int MAX_LOCAL_PRIMES = 500;
private List<Integer> primes;
private int numPrimes;
private SieveActorActor nextActor;
public SieveActorActor(final int localPrime) {
primes = new ArrayList<>();
primes.add(localPrime);
this.nextActor = null;
this.numPrimes = 1;
}
@Override
public void process(final Object msg) {
final int candidate = (Integer) msg;
if (candidate <= 0) { }
else {
final boolean locallyPrime = isLocallyPrime(candidate);
if (locallyPrime) {
if (primes.size() <= MAX_LOCAL_PRIMES) {
primes.add(candidate);
numPrimes++;
} else if (nextActor == null) {
nextActor = new SieveActorActor(candidate);
} else {
nextActor.send(msg);
}
}
}
}
private boolean isLocallyPrime(final Integer candidate) {
return primes
.stream()
//.parallel()
.noneMatch(prime -> candidate % prime == 0);
}
}
}