-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
245 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
service/src/main/java/app/prime/service/CachedPrimeFactorService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* Cache prime factors calculation results. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Service | ||
@WithCache | ||
public class CachedPrimeFactorService implements PrimeFactorService { | ||
private final PrimeFactorService primeFactorService; | ||
private final Map<Long, List<Long>> cache; | ||
|
||
@Autowired | ||
@WithOutCache | ||
public CachedPrimeFactorService(PrimeFactorService primeFactorService) { | ||
this(primeFactorService, new ConcurrentHashMap<>()); | ||
} | ||
|
||
CachedPrimeFactorService(PrimeFactorService primeFactorService, Map<Long, List<Long>> cache) { | ||
this.primeFactorService = primeFactorService; | ||
this.cache = cache; | ||
} | ||
|
||
/** | ||
* Expand a number into prime factors. | ||
*/ | ||
public List<Long> findPrimeFactors(long number) { | ||
if (cache.containsKey(number)) { | ||
return cache.get(number); | ||
} | ||
List<Long> factors = primeFactorService.findPrimeFactors(number); | ||
cache.put(number, factors); | ||
return factors; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
service/src/main/java/app/prime/service/CachedPrimeService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* Cache prime calculation results. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Service | ||
@WithCache | ||
public class CachedPrimeService implements PrimeService { | ||
private final PrimeService primeService; | ||
private final Map<Long, Boolean> cache; | ||
|
||
@Autowired | ||
@WithOutCache | ||
public CachedPrimeService(PrimeService primeService) { | ||
this(primeService, new ConcurrentHashMap<>()); | ||
} | ||
|
||
CachedPrimeService(PrimeService primeService, Map<Long, Boolean> cache) { | ||
this.primeService = primeService; | ||
this.cache = cache; | ||
} | ||
|
||
/** | ||
* Check a number is prime. | ||
*/ | ||
public boolean isPrime(final long number) { | ||
if (cache.containsKey(number)) { | ||
return cache.get(number); | ||
} | ||
boolean prime = primeService.isPrime(number); | ||
cache.put(number, prime); | ||
return prime; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.cache.annotation.Cacheable; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.ArrayList; | ||
|
@@ -13,34 +12,39 @@ | |
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Service | ||
@WithOutCache | ||
public class SimplePrimeFactorService implements PrimeFactorService { | ||
final PrimeService primeService; | ||
|
||
@Autowired | ||
@WithCache | ||
public SimplePrimeFactorService(PrimeService primeService) { | ||
this.primeService = primeService; | ||
} | ||
|
||
/** | ||
* List prime factors. | ||
*/ | ||
@Cacheable | ||
public List<Long> findPrimeFactors(final long number) { | ||
|
||
final List<Long> primes = new ArrayList<>(); | ||
|
||
long divide = number; | ||
for (long l = 2; l <= number; l++) { | ||
for (long factor = 2; factor <= number; factor++) { | ||
if (divide == 1) { | ||
break; | ||
} | ||
if (!primeService.isPrime(l)) { | ||
if (!primeService.isPrime(factor)) { | ||
continue; | ||
} | ||
if (primeService.isPrime(divide)) { | ||
primes.add(divide); | ||
break; | ||
} | ||
|
||
while (divide % l == 0) { | ||
divide /= l; | ||
primes.add(l); | ||
while (divide % factor == 0) { | ||
divide /= factor; | ||
primes.add(factor); | ||
} | ||
} | ||
return primes; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.cache.annotation.Cacheable; | ||
import org.springframework.stereotype.Service; | ||
|
||
/** | ||
|
@@ -9,11 +8,11 @@ | |
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Service | ||
@WithOutCache | ||
public class SimplePrimeService implements PrimeService { | ||
/** | ||
* Check a number is prime. | ||
*/ | ||
@Cacheable | ||
public boolean isPrime(final long number) { | ||
for (long l = 2; l < number; l++) { | ||
if (number % l == 0) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.beans.factory.annotation.Qualifier; | ||
|
||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
|
||
/** | ||
* Select cached version. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Qualifier | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface WithCache { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package app.prime.service; | ||
|
||
import org.springframework.beans.factory.annotation.Qualifier; | ||
|
||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
|
||
/** | ||
* Select cached version. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
@Qualifier | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface WithOutCache { | ||
} |
59 changes: 59 additions & 0 deletions
59
service/src/test/java/app/prime/service/CachedPrimeFactorServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package app.prime.service; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import static java.util.Arrays.asList; | ||
import static java.util.Collections.singletonList; | ||
import static org.hamcrest.CoreMatchers.is; | ||
import static org.junit.Assert.assertThat; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* Test cached prime favors service. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
public class CachedPrimeFactorServiceTest { | ||
private CachedPrimeFactorService primeFactorService; | ||
private ConcurrentHashMap<Long, List<Long>> cache; | ||
|
||
@Before | ||
public void setUp() { | ||
cache = new ConcurrentHashMap<>(); | ||
primeFactorService = new CachedPrimeFactorService( | ||
new SimplePrimeFactorService( | ||
new SimplePrimeService() | ||
), | ||
cache | ||
); | ||
} | ||
|
||
@Test | ||
public void testFindPrimeFactors() { | ||
checkPrimeFactors(-1, Collections.emptyList()); | ||
checkPrimeFactors(0, Collections.emptyList()); | ||
checkPrimeFactors(1, Collections.emptyList()); | ||
checkPrimeFactors(2, singletonList(2L)); | ||
checkPrimeFactors(3, singletonList(3L)); | ||
checkPrimeFactors(4, asList(2L, 2L)); | ||
checkPrimeFactors(5, singletonList(5L)); | ||
checkPrimeFactors(6, asList(2L, 3L)); | ||
checkPrimeFactors(7, singletonList(7L)); | ||
checkPrimeFactors(8, asList(2L, 2L, 2L)); | ||
checkPrimeFactors(9, asList(3L, 3L)); | ||
checkPrimeFactors(10, asList(2L, 5L)); | ||
checkPrimeFactors(10, asList(2L, 5L)); | ||
checkPrimeFactors(9999998, asList(2L, 4999999L)); | ||
} | ||
|
||
private void checkPrimeFactors(long n, List<Long> factors) { | ||
assertThat("Prime factor for " + n + " is " + factors, primeFactorService.findPrimeFactors(n), is(factors)); | ||
assertTrue("Cache contain number " + n, cache.containsKey(n)); | ||
assertThat("Valid prime factor cached result for " + n + " is " + factors, cache.get(n), is(factors)); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
service/src/test/java/app/prime/service/CachedPrimeServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package app.prime.service; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* Test cached prime service. | ||
* | ||
* @author Vladimir Ivanov ([email protected]) | ||
*/ | ||
public class CachedPrimeServiceTest { | ||
private CachedPrimeService primeService; | ||
private ConcurrentHashMap<Long, Boolean> cache; | ||
|
||
@Before | ||
public void setUp() { | ||
cache = new ConcurrentHashMap<>(); | ||
primeService = new CachedPrimeService(new SimplePrimeService(), cache); | ||
} | ||
|
||
@Test | ||
public void testIsPrime() { | ||
|
||
checkNotPrime(-1); | ||
checkNotPrime(0); | ||
checkNotPrime(4); | ||
checkNotPrime(10); | ||
checkNotPrime(10); | ||
|
||
checkPrime(1); | ||
checkPrime(2); | ||
checkPrime(3); | ||
checkPrime(5); | ||
checkPrime(7); | ||
checkPrime(7); | ||
} | ||
|
||
private void checkNotPrime(long n) { | ||
assertFalse("Not prime number " + n, primeService.isPrime(n)); | ||
assertTrue("Cache contain number " + n, cache.containsKey(n)); | ||
assertFalse("Valid not prime cached result for " + n, cache.get(n)); | ||
} | ||
|
||
private void checkPrime(long n) { | ||
assertTrue("Prime number " + n, primeService.isPrime(n)); | ||
assertTrue("Cache contain number " + n, cache.containsKey(n)); | ||
assertTrue("Valid prime cached result for " + n, cache.get(n)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters