bb.util
Class DateUtil.DateInfoBin

java.lang.Object
  extended by bb.util.DateUtil.DateInfoBin
Enclosing class:
DateUtil

private static final class DateUtil.DateInfoBin
extends Object

Stores all the DateUtil.DateInfo instances which have a common day number key (as calculated by getDateInfo).


Field Summary
private  DateUtil.DateInfo[] dateInfos
          Forms the second level of the DateInfo cache, namely, an array of DateUtil.DateInfo instances.
private static boolean executing_onCacheMiss
          Recursion detection flag used inside onCacheMiss.
 
Constructor Summary
private DateUtil.DateInfoBin()
           
 
Method Summary
private  DateUtil.DateInfo findDateInfo(long time, DateUtil.DateInfoBin[] bins)
          Performs a linear search thru all the currently stored DateInfos, looking for one which is for time; such an instance is returned if found, else the result of calling onCacheMiss is returned.
private  DateUtil.DateInfo onCacheMiss(long time, DateUtil.DateInfoBin[] bins, DateUtil.DateInfo[] infos)
          Handles a cache miss.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

executing_onCacheMiss

private static boolean executing_onCacheMiss
Recursion detection flag used inside onCacheMiss.

This field is static, instead of being instance based, merely to save memory, since there is no point in having it be instance based because the onCacheMiss method must use the static lock_DateInfo field so no instance-level concurrency is possible anyways.

Contract: this field must only be used inside a synchronized (lock_DateInfo) { ... } block. Because of this, it need not be declared as volatile.


dateInfos

private volatile DateUtil.DateInfo[] dateInfos
Forms the second level of the DateInfo cache, namely, an array of DateUtil.DateInfo instances. This array stores the DateInfos in the order in which they were created, which for an arbitrary program is essentially random order.

Contract: this field may be null, but if non-null then is a reference to a fully valid array (i.e. it never has null elements, nor is zero-length). It must be declared as volatile because it is designed to be accessed outside of synchronized blocks for high performance.

Constructor Detail

DateUtil.DateInfoBin

private DateUtil.DateInfoBin()
Method Detail

findDateInfo

private DateUtil.DateInfo findDateInfo(long time,
                                       DateUtil.DateInfoBin[] bins)
Performs a linear search thru all the currently stored DateInfos, looking for one which is for time; such an instance is returned if found, else the result of calling onCacheMiss is returned.


onCacheMiss

private DateUtil.DateInfo onCacheMiss(long time,
                                      DateUtil.DateInfoBin[] bins,
                                      DateUtil.DateInfo[] infos)
Handles a cache miss.

Immediately returns null if:

  1. the bins parameter is != the dateInfoBins field of the DateUtil class. This only happens if another thread calling setDateInfoCacheSizeMax grabbed lock_DateInfo just before the thread(s) calling onCacheMiss, which will now block until they get lock_DateInfo. In this case, immediate return is required to avoid side effects (e.g. incrementing the dateInfoCacheSize field) which would now be incorrect to do.
  2. the infos parameter is != the dateInfos field of this class. This only happens if one or more other threads concurrently calling onCacheMiss grabbed lock_DateInfo just before the current thread and modified the dateInfos field. In this case, immediate return is required to avoid putting redundant DateInfos into the dateInfos field (since one of the previous threads may have already stored a DateInfo suitable for time, and the code in this method does not check for this condition).
  3. the cache size limit (dateInfoCacheSizeMax) has been reached. In this case, the DateUtil.countDateInfoCacheMisses field is incremented before return.
  4. the call is recursive. This is necessary because the first call to onCacheMiss will call methods like getDayStart as part of creating the new DateInfo instance, and these methods will in turn call getDateInfo/findDateInfo/onCacheMiss recursively, which has to be detected to avoid an infinite recursion.
  5. a problem creating a DateInfo suitable for time is encountered

Otherwise, this method creates a new DateInfo[] of length 1 greater then the previous length of the dateInfos field, copies all the previous elements of dateInfos to its beginning elements, adds a new DateInfo instance for time as this array's final element, assigns this array as the new value of dateInfos, increments DateUtil.dateInfoCacheSize, and returns the DateInfo instance that was created for time.