Skip to content

Commit 9298278

Browse files
add javadoc comments, and minor fixed and refactors.
1 parent 07b5ad5 commit 9298278

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

src/main/java/com/athingforcode/TTLHashMap.java

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,60 @@ public class TTLHashMap<K, V> {
1111
private final ConcurrentHashMap<K, Entry<K, V>> map;
1212
private final ScheduledExecutorService scheduler;
1313

14+
15+
/**
16+
* Creates a new instance of TTLHashMap.
17+
* This constructor initializes a new ConcurrentHashMap to store entries and a single-threaded ScheduledExecutorService to manage time-to-live (TTL) expiration.
18+
*/
1419
public TTLHashMap() {
1520
this.map = new ConcurrentHashMap<>();
1621
this.scheduler = Executors.newSingleThreadScheduledExecutor();
1722
}
1823

24+
/**
25+
* Shuts down the ScheduledExecutorService used by this TTLHashMap, terminating any pending TTL expiration tasks.
26+
* This method should be called when the TTLHashMap is no longer needed to prevent memory leaks and ensure proper cleanup.
27+
*/
1928
public void shutdown() {
2029
scheduler.shutdownNow();
2130
}
2231

32+
/**
33+
* Puts a key-value pair into the map with an optional expiration time.
34+
*
35+
* @param key the key with which the specified value is to be associated
36+
* @param value the value to be associated with the specified key
37+
* @param ttl the time to live for the entry
38+
* @param unit the time unit of the ttl argument
39+
* @param actionWhenExpired the action to be performed when the entry expires
40+
* @throws NullPointerException if the key or unit is null
41+
*
42+
* @implNote If ttl is negative, the entry is considered non-expiring.
43+
* If ttl is zero or positive, a removal schedule is set for the entry.
44+
*/
2345
public void put(K key, V value, long ttl, TimeUnit unit, BiConsumer<K, V> actionWhenExpired) {
2446
Objects.requireNonNull(key);
47+
Objects.requireNonNull(unit);
2548
Entry<K, V> entry = new Entry<>(key, value, ttl, unit);
2649
map.put(key, entry);
27-
//if ttl is negative then entry is cosidered non expiring
50+
/*
51+
if ttl is negative then entry is cosidered non expiring
52+
* */
2853
if(ttl >= 0) {
2954
setRemovalSchedule(entry,actionWhenExpired);
3055
}
3156
}
3257

58+
/**
59+
* Retrieves the value associated with the specified key.
60+
*
61+
* @param key the key whose associated value is to be returned
62+
* @return the value associated with the specified key, or null if the key is not found
63+
* or the entry has expired
64+
*
65+
* @implNote If the entry associated with the key has expired, it is removed from the map
66+
* before returning null.
67+
*/
3368
public V get(K key) {
3469
Entry<K, V> entry = map.get(key);
3570
if (entry == null || entry.isExpired()) {
@@ -39,10 +74,25 @@ public V get(K key) {
3974
return entry.getValue();
4075
}
4176

77+
/**
78+
* Removes the mapping for the specified key from this map if present.
79+
*
80+
* @param key the key whose mapping is to be removed from the map
81+
*/
4282
public void remove(K key) {
4383
map.remove(key);
4484
}
4585

86+
/**
87+
* Sets up a schedule for removing an entry after its time-to-live has elapsed.
88+
*
89+
* @param entry the entry to be scheduled for removal
90+
* @param actionWhenExpired the action to be performed when the entry expires
91+
*
92+
* @implNote This method uses a scheduler to remove the entry from the map after its TTL.
93+
* If an action is provided, it will be executed with the entry's key and value
94+
* after removal.
95+
*/
4696
private void setRemovalSchedule(Entry<K, V> entry, BiConsumer<K, V> actionWhenExpired) {
4797
scheduler.schedule(() -> {
4898
map.remove(entry.getKey());
@@ -59,11 +109,20 @@ private static class Entry<K, V> {
59109
private final TimeUnit ttlUnit;
60110
private final long creationTime;
61111

62-
public Entry(K key, V value, long ttl, TimeUnit unit) {
112+
/**
113+
* Creates a new Entry with the specified key, value, time-to-live (TTL), and TTL unit.
114+
* The creation time of the entry is set to the current system time.
115+
*
116+
* @param key the key of the entry
117+
* @param value the value of the entry
118+
* @param ttl the time-to-live value of the entry
119+
* @param ttlUnit the unit of the TTL value (e.g., seconds, minutes, hours)
120+
*/
121+
public Entry(K key, V value, long ttl, TimeUnit ttlUnit) {
63122
this.key = key;
64123
this.value = value;
65124
this.ttl = ttl;
66-
this.ttlUnit = unit;
125+
this.ttlUnit = ttlUnit;
67126
this.creationTime = System.currentTimeMillis();
68127
}
69128

@@ -83,7 +142,17 @@ public TimeUnit getTtlUnit() {
83142
return ttlUnit;
84143
}
85144

145+
/**
146+
* Checks if this entry has expired based on its time-to-live (TTL) value.
147+
* An entry is considered expired if the current time is greater than or equal to the entry's creation time plus its TTL.
148+
* An entry with negative ttl is never expired
149+
*
150+
* @return true if this entry has expired, false otherwise
151+
*/
86152
public boolean isExpired() {
153+
if(ttl < 0) {
154+
return false;
155+
}
87156
long now = System.currentTimeMillis();
88157
long expirationTime = creationTime + ttlUnit.toMillis(ttl);
89158
return now >= expirationTime;

0 commit comments

Comments
 (0)