Skip to content

Commit

Permalink
Updated to 2.12.0 - Big update to LRUCache
Browse files Browse the repository at this point in the history
  • Loading branch information
jdereg committed Jun 23, 2024
1 parent 759fc0b commit 2af75f8
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 24 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ java-util

Helpful Java utilities that are thoroughly tested and available on [Maven Central](https://central.sonatype.com/search?q=java-util&namespace=com.cedarsoftware).
This library has <b>no dependencies</b> on other libraries for runtime.
The`.jar`file is `260K` and works with`JDK 1.8`through`JDK 21`.
The '.jar' file classes are version 52 (`JDK 1.8`).
The`.jar`file is `290K` and works with `JDK 1.8` through `JDK 22`.
The `.jar` file classes are version 52 `(JDK 1.8)`
## Compatibility

### JPMS (Java Platform Module System)
Expand All @@ -25,15 +25,15 @@ Both of these features ensure that our library can be seamlessly integrated into
To include in your project:
##### Gradle
```groovy
implementation 'com.cedarsoftware:java-util:2.11.0'
implementation 'com.cedarsoftware:java-util:2.12.0'
```

##### Maven
```xml
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<version>2.11.0</version>
<version>2.12.0</version>
</dependency>
```
---
Expand All @@ -60,7 +60,7 @@ Included in java-util:
- **[CompactCILinkedMap](/src/main/java/com/cedarsoftware/util/CompactCILinkedMap.java)** - A small-footprint, case-insensitive `Map` that becomes a `LinkedHashMap`.
- **[CompactCIHashMap](/src/main/java/com/cedarsoftware/util/CompactCIHashMap.java)** - A compact, case-insensitive `Map` expanding to a `HashMap`.
- **[CaseInsensitiveMap](/src/main/java/com/cedarsoftware/util/CaseInsensitiveMap.java)** - Treats `String` keys in a case-insensitive manner.
- **[LRUCache](/src/main/java/com/cedarsoftware/util/LRUCache.java)** - A thread-safe LRU cache implementing the full Map API, managing items based on usage.
- **[LRUCache](/src/main/java/com/cedarsoftware/util/LRUCache.java)** - Thread-safe LRU cache which implements the Map API. Supports "locking" or "threaded" strategy (selectable).
- **[TrackingMap](/src/main/java/com/cedarsoftware/util/TrackingMap.java)** - Tracks access patterns to its keys, aiding in performance optimizations.
- **[SealableMap](/src/main/java/com/cedarsoftware/util/SealableMap.java)** - Allows toggling between sealed (read-only) and unsealed (writable) states, managed externally.
- **[SealableNavigableMap](/src/main/java/com/cedarsoftware/util/SealableNavigableMap.java)** - Extends `SealableMap` features to `NavigableMap`, managing state externally.
Expand Down
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
### Revision History
* 2.12.0
* `LRUCache` updated to support both "locking" and "threaded" implementation strategies.
* 2.11.0
* `LRUCache` re-written so that it operates in O(1) for `get(),` `put(),` and `remove()` methods without thread contention. When items are placed into (or removed from) the cache, it schedules a cleanup task to trim the cache to its capacity. This means that it will operate as fast as a `ConcurrentHashMap,` yet shrink to capacity quickly after modifications.
* 2.10.0
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<packaging>bundle</packaging>
<version>2.11.0</version>
<version>2.12.0</version>
<description>Java Utilities</description>
<url>https://github.com/jdereg/java-util</url>

Expand Down Expand Up @@ -37,7 +37,7 @@
<version.junit-jupiter-params>5.10.2</version.junit-jupiter-params>
<version.mockito-junit-jupiter>4.11.0</version.mockito-junit-jupiter>
<version.assertj-core>3.26.0</version.assertj-core>
<version.json-io>4.24.0</version.json-io>
<version.json-io>4.25.0</version.json-io>
<version.agrona>1.21.2</version.agrona>

<!-- Build maven-***-plugins -->
Expand Down
71 changes: 54 additions & 17 deletions src/main/java/com/cedarsoftware/util/LRUCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,53 @@ public enum StrategyType {
LOCKING
}

/**
* Create a "locking-based" LRUCache with the passed in capacity.
* @param capacity int maximum number of entries in the cache.
* @see com.cedarsoftware.util.cache.LockingLRUCacheStrategy
*/
public LRUCache(int capacity) {
strategy = new LockingLRUCacheStrategy<>(capacity);
}

/**
* Create a "locking-based" OR a "thread-based" LRUCache with the passed in capacity.
* <p>
* Note: There is a "shutdown" method on LRUCache to ensure that the default scheduler that was created for you
* is cleaned up, which is useful in a container environment.
* @param capacity int maximum number of entries in the cache.
* @param strategyType StrategyType.LOCKING or Strategy.THREADED indicating the underlying LRUCache implementation.
* @see com.cedarsoftware.util.cache.LockingLRUCacheStrategy
* @see com.cedarsoftware.util.cache.ThreadedLRUCacheStrategy
*/
public LRUCache(int capacity, StrategyType strategyType) {
this(capacity, strategyType, 10, null, null);
}

public LRUCache(int capacity, StrategyType strategyType, int cleanupDelayMillis, ScheduledExecutorService scheduler, ForkJoinPool cleanupPool) {
switch (strategyType) {
case THREADED:
this.strategy = new ThreadedLRUCacheStrategy<>(capacity, cleanupDelayMillis, scheduler, cleanupPool);
break;
case LOCKING:
this.strategy = new LockingLRUCacheStrategy<>(capacity);
break;
default:
throw new IllegalArgumentException("Unknown strategy type");
if (strategyType == StrategyType.THREADED) {
strategy = new ThreadedLRUCacheStrategy<>(capacity, 10, null, null);
} else if (strategyType == StrategyType.LOCKING) {
strategy = new LockingLRUCacheStrategy<>(capacity);
} else {
throw new IllegalArgumentException("Unsupported strategy type: " + strategyType);
}
}

/**
* Create a "thread-based" LRUCache with the passed in capacity.
* <p>
* Note: There is a "shutdown" method on LRUCache to ensure that the default scheduler that was created for you
* is cleaned up, which is useful in a container environment. If you supplied your own scheduler and cleanupPool,
* then it is up to you to manage there termination. The shutdown() method will not manipulate them in anyway.
* @param capacity int maximum number of entries in the cache.
* @param cleanupDelayMillis int number of milliseconds after a put() call when a scheduled task should run to
* trim the cache to no more than capacity. The default is 10ms.
* @param scheduler ScheduledExecutorService which can be null, in which case one will be created for you, or you
* can supply your own.
* @param cleanupPool ForkJoinPool can be null, in which case one will be created for you, you can supply your own.
* @see com.cedarsoftware.util.cache.ThreadedLRUCacheStrategy
*/
public LRUCache(int capacity, int cleanupDelayMillis, ScheduledExecutorService scheduler, ForkJoinPool cleanupPool) {
strategy = new ThreadedLRUCacheStrategy<>(capacity, cleanupDelayMillis, scheduler, cleanupPool);
}

@Override
public V get(Object key) {
return strategy.get(key);
Expand All @@ -51,7 +81,7 @@ public void putAll(Map<? extends K, ? extends V> m) {

@Override
public V remove(Object key) {
return strategy.remove((K)key);
return strategy.remove(key);
}

@Override
Expand All @@ -71,12 +101,12 @@ public boolean isEmpty() {

@Override
public boolean containsKey(Object key) {
return strategy.containsKey((K)key);
return strategy.containsKey(key);
}

@Override
public boolean containsValue(Object value) {
return strategy.containsValue((V)value);
return strategy.containsValue(value);
}

@Override
Expand Down Expand Up @@ -106,7 +136,14 @@ public int hashCode() {

@Override
public boolean equals(Object obj) {
return strategy.equals(obj);
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
LRUCache<?, ?> other = (LRUCache<?, ?>) obj;
return strategy.equals(other.strategy);
}

public void shutdown() {
Expand Down

0 comments on commit 2af75f8

Please sign in to comment.