5656 * amortized {@code O(1)} expiration.
5757 * <p>
5858 * This implementation does not support providing an {@link EvictionPolicy} or
59- * {@link EvictionApprover}, and always uses TinyLFU policy. The maximum size is
60- * set by {@link #setHighUnits(int)} and the low watermark, {@link
59+ * {@link EvictionApprover}, and always uses the TinyLFU policy. The maximum
60+ * size is set by {@link #setHighUnits(int)} and the low watermark, {@link
6161 * #setLowUnits(int)}, has no effect. Cache entries do not support {@code
6262 * touch()}, {@code getTouchCount()}, {@code getLastTouchMillis()}, or {@code
6363 * setUnits(c)}. By default, the cache is unbounded and will not be limited by
@@ -196,21 +196,21 @@ else if (cMillis == EXPIRY_DEFAULT)
196196 @ SuppressWarnings ("OptionalGetWithoutIsPresent" )
197197 public int getUnits ()
198198 {
199- return ( int ) Math . min ( f_eviction .weightedSize ().getAsLong (), Integer . MAX_VALUE );
199+ return toExternalUnits ( f_eviction .weightedSize ().getAsLong (), getUnitFactor () );
200200 }
201201
202202 // ---- ConfigurableCacheMap interface ----------------------------------
203203
204204 @ Override
205205 public int getHighUnits ()
206206 {
207- return ( int ) Math . min ( f_eviction .getMaximum (), Integer . MAX_VALUE );
207+ return toExternalUnits ( f_eviction .getMaximum (), getUnitFactor () );
208208 }
209209
210210 @ Override
211211 public synchronized void setHighUnits (int units )
212212 {
213- f_eviction .setMaximum (units );
213+ f_eviction .setMaximum (toInternalUnits ( units , getUnitFactor ()) );
214214 }
215215
216216 @ Override
@@ -243,7 +243,19 @@ else if (!isEmpty())
243243 throw new IllegalStateException (
244244 "The unit factor cannot be set after the cache has been populated" );
245245 }
246- this .m_nUnitFactor = nUnitFactor ;
246+
247+ // only adjust the max units if there was no unit factor set previously
248+ if (m_nUnitFactor == 1 )
249+ {
250+ long cCurrentMaxUnits = f_eviction .getMaximum ();
251+ if (cCurrentMaxUnits < (Long .MAX_VALUE - Integer .MAX_VALUE ))
252+ {
253+ long cMaxUnits = (cCurrentMaxUnits * nUnitFactor );
254+ f_eviction .setMaximum ((cMaxUnits < 0 ) ? Long .MAX_VALUE : cMaxUnits );
255+ }
256+ }
257+
258+ m_nUnitFactor = nUnitFactor ;
247259 }
248260
249261 @ Override
@@ -266,6 +278,41 @@ public void setUnitCalculator(UnitCalculator calculator)
266278 }
267279 }
268280
281+ /**
282+ * Convert from an external 32-bit unit value to an internal 64-bit unit
283+ * value using the configured units factor.
284+ *
285+ * @param cUnits an external 32-bit units value
286+ * @param nFactor the unit factor
287+ *
288+ * @return an internal 64-bit units value
289+ */
290+ protected static long toInternalUnits (int cUnits , int nFactor )
291+ {
292+ return (cUnits <= 0 ) || (cUnits == Integer .MAX_VALUE )
293+ ? Long .MAX_VALUE
294+ : ((long ) cUnits ) * nFactor ;
295+ }
296+
297+ /**
298+ * Convert from an internal 64-bit unit value to an external 32-bit unit
299+ * value using the configured units factor.
300+ *
301+ * @param cUnits an internal 64-bit units value
302+ * @param nFactor the unit factor
303+ *
304+ * @return an external 32-bit units value
305+ */
306+ protected static int toExternalUnits (long cUnits , int nFactor )
307+ {
308+ if (nFactor > 1 )
309+ {
310+ cUnits = (cUnits + nFactor - 1 ) / nFactor ;
311+ }
312+
313+ return (cUnits > Integer .MAX_VALUE ) ? Integer .MAX_VALUE : (int ) cUnits ;
314+ }
315+
269316 @ Override
270317 public void evict (Object oKey )
271318 {
@@ -705,13 +752,7 @@ public String toString()
705752 */
706753 private int weigh (Object oKey , Object oValue )
707754 {
708- int cUnits = m_unitCalculator .calculateUnits (oKey , oValue );
709- if (cUnits < 0 )
710- {
711- throw new IllegalStateException (String .format (
712- "Negative unit (%s) for %s=%s" , cUnits , oKey , oValue ));
713- }
714- return (cUnits / m_nUnitFactor );
755+ return m_unitCalculator .calculateUnits (oKey , oValue );
715756 }
716757
717758 /**
@@ -722,8 +763,12 @@ private int weigh(Object oKey, Object oValue)
722763 */
723764 private void notifyCreate (Object oKey , Object oValueNew )
724765 {
725- fireEvent (new CacheEvent (this , MapEvent .ENTRY_INSERTED ,
726- oKey , null , oValueNew , false ));
766+ if (!f_listeners .isEmpty ())
767+ {
768+ CacheEvent event = new CacheEvent (this , MapEvent .ENTRY_INSERTED ,
769+ oKey , null , oValueNew , false );
770+ f_listeners .fireEvent (event , false );
771+ }
727772 }
728773
729774 /**
@@ -735,8 +780,12 @@ private void notifyCreate(Object oKey, Object oValueNew)
735780 */
736781 private void notifyUpdate (Object oKey , Object oValueOld , Object oValueNew )
737782 {
738- fireEvent (new CacheEvent (this , MapEvent .ENTRY_UPDATED ,
739- oKey , oValueOld , oValueNew , false ));
783+ if (!f_listeners .isEmpty ())
784+ {
785+ CacheEvent event = new CacheEvent (this , MapEvent .ENTRY_UPDATED ,
786+ oKey , oValueOld , oValueNew , false );
787+ f_listeners .fireEvent (event , false );
788+ }
740789 }
741790
742791 /**
@@ -748,8 +797,12 @@ private void notifyUpdate(Object oKey, Object oValueOld, Object oValueNew)
748797 */
749798 private void notifyDelete (Object oKey , Object oValueOld )
750799 {
751- fireEvent (new CacheEvent (this , MapEvent .ENTRY_DELETED ,
752- oKey , oValueOld , null , false ));
800+ if (!f_listeners .isEmpty ())
801+ {
802+ CacheEvent event = new CacheEvent (this , MapEvent .ENTRY_DELETED ,
803+ oKey , oValueOld , null , false );
804+ f_listeners .fireEvent (event , false );
805+ }
753806 }
754807
755808 /**
@@ -761,22 +814,13 @@ private void notifyDelete(Object oKey, Object oValueOld)
761814 * @param removalCause the eviction type (size, expired)
762815 */
763816 private void notifyEvicted (Object oKey , Object oValueOld , RemovalCause removalCause )
764- {
765- boolean fExpired = removalCause == RemovalCause .EXPIRED ;
766- fireEvent (new CacheEvent (this , MapEvent .ENTRY_DELETED ,
767- oKey , oValueOld , null , true ,
768- TransformationState .TRANSFORMABLE , false , fExpired ));
769- }
770-
771- /**
772- * Fire the specified cache event.
773- *
774- * @param event the cache event to fire
775- */
776- private void fireEvent (CacheEvent event )
777817 {
778818 if (!f_listeners .isEmpty ())
779819 {
820+ boolean fExpired = removalCause == RemovalCause .EXPIRED ;
821+ CacheEvent event = new CacheEvent (this , MapEvent .ENTRY_DELETED , oKey , oValueOld ,
822+ null , true , TransformationState .TRANSFORMABLE ,
823+ false , fExpired );
780824 f_listeners .fireEvent (event , false );
781825 }
782826 }
@@ -1247,7 +1291,7 @@ public void setExpiryMillis(long cMillis)
12471291 @ Override
12481292 public int getUnits ()
12491293 {
1250- return f_nWeight * m_nUnitFactor ;
1294+ return f_nWeight ;
12511295 }
12521296
12531297 @ Override
0 commit comments