2020-03-30 10:49:23 +00:00
using System ;
2016-04-21 22:37:40 +00:00
using System.Collections.Concurrent ;
2017-01-13 15:40:32 +00:00
using System.Collections.Generic ;
2014-12-18 11:22:47 +00:00
using System.Linq ;
2020-08-05 09:30:45 +00:00
using System.Threading.Tasks ;
2017-01-13 15:40:32 +00:00
using System.Windows.Media ;
2014-12-18 11:22:47 +00:00
2020-08-05 09:57:23 +00:00
namespace Flow.Launcher.Infrastructure.Image
2014-12-18 11:22:47 +00:00
{
[Serializable]
2016-04-21 00:53:21 +00:00
public class ImageCache
2014-12-18 11:22:47 +00:00
{
2020-08-05 09:30:45 +00:00
private const int MaxCached = 50 ;
2017-01-13 15:40:32 +00:00
public ConcurrentDictionary < string , int > Usage = new ConcurrentDictionary < string , int > ( ) ;
private readonly ConcurrentDictionary < string , ImageSource > _data = new ConcurrentDictionary < string , ImageSource > ( ) ;
2020-08-05 09:30:45 +00:00
private const int permissibleFactor = 2 ;
2017-01-13 15:40:32 +00:00
public ImageSource this [ string path ]
2014-12-18 11:22:47 +00:00
{
2017-01-13 15:40:32 +00:00
get
2014-12-18 11:22:47 +00:00
{
2017-01-13 15:40:32 +00:00
Usage . AddOrUpdate ( path , 1 , ( k , v ) = > v + 1 ) ;
var i = _data [ path ] ;
return i ;
2014-12-18 11:22:47 +00:00
}
2020-08-05 09:30:45 +00:00
set
{
_data [ path ] = value ;
// To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size
// This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time
if ( _data . Count > permissibleFactor * MaxCached )
{
// This function resizes the Usage dictionary, taking the top 'maxCached' number of items and filtering the image icons that are not accessed frequently.
Cleanup ( ) ;
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary.
foreach ( var key in _data . Keys )
{
int dictValue ;
if ( ! Usage . TryGetValue ( key , out dictValue ) )
{
ImageSource imgSource ;
_data . TryRemove ( key , out imgSource ) ;
}
}
}
}
2016-05-22 04:30:38 +00:00
}
2014-12-18 11:22:47 +00:00
2020-08-05 09:30:45 +00:00
public void Cleanup ( )
{
var images = Usage
2017-01-13 15:40:32 +00:00
. OrderByDescending ( o = > o . Value )
. Take ( MaxCached )
. ToDictionary ( i = > i . Key , i = > i . Value ) ;
2020-08-05 09:30:45 +00:00
Usage = new ConcurrentDictionary < string , int > ( images ) ;
}
2017-01-13 15:40:32 +00:00
public bool ContainsKey ( string key )
{
var contains = _data . ContainsKey ( key ) ;
return contains ;
2014-12-18 11:22:47 +00:00
}
2020-01-03 19:16:17 +00:00
public int CacheSize ( )
{
return _data . Count ;
}
/// <summary>
/// return the number of unique images in the cache (by reference not by checking images content)
/// </summary>
public int UniqueImagesInCache ( )
{
return _data . Values . Distinct ( ) . Count ( ) ;
}
2014-12-18 11:22:47 +00:00
}
2017-01-13 15:40:32 +00:00
2020-08-05 09:30:45 +00:00
}