synchronized void checkEvict ( ) throws IOException { if ( cacheSize . get ( ) < cacheSizeMax ) { return ; // nothing to do, plenty of free space } // Only one thread should be doing the eviction. Do not block // current thread, it is ok to oversubscribe the cache size // temporarily. if ( evictionInProgress ) { return ; } // record the fact that eviction has started. evictionInProgress = true ; try { // if the cache has reached a threshold size, then free old entries. long curSize = cacheSize . get ( ) ; // how much to evict in one iteration long targetSize = cacheSizeMax - ( cacheSizeMax * cacheEvictPercent ) / 100 ; if ( LOG . isDebugEnabled ( ) ) { LOG . debug ( "Cache size " + curSize + " has exceeded the " + " maximum configured cacpacity " + cacheSizeMax + ". Eviction has to reduce cache size to " + targetSize ) ; } // sort all entries based on their accessTimes Collection < CacheEntry > values = cacheMap . values ( ) ; CacheEntry [ ] records = values . toArray ( new CacheEntry [ values . size ( ) ] ) ; Arrays . sort ( records , LRU_COMPARATOR ) ; for ( int i = 0 ; i < records . length ; i ++ ) { if ( cacheSize . get ( ) <= targetSize ) { break ; // we reclaimed everything we wanted to } CacheEntry c = records [ i ] ; evictCache ( c . hdfsPath ) ; } } finally { evictionInProgress = false ; // eviction done. } if ( LOG . isDebugEnabled ( ) ) { LOG . debug ( "Cache eviction complete. Current cache size is " + cacheSize . get ( ) ) ; } }
Eviction occurs if the cache is full we free up a specified percentage of the cache on every run . This method is synchronized so that only one thread is doing the eviction .