@@ -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