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]
2020-11-11 02:56:53 +00:00
public class ImageUsage
{
public int usage ;
public ImageSource imageSource ;
public ImageUsage ( int usage , ImageSource image )
{
this . usage = usage ;
imageSource = image ;
}
}
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 ;
2020-11-11 02:56:53 +00:00
public ConcurrentDictionary < string , ImageUsage > Data { get ; private set ; } = new ConcurrentDictionary < string , ImageUsage > ( ) ;
2020-08-05 09:30:45 +00:00
private const int permissibleFactor = 2 ;
2020-11-15 12:45:00 +00:00
2020-11-07 16:01:33 +00:00
public void Initialization ( Dictionary < string , int > usage )
{
foreach ( var key in usage . Keys )
{
2020-11-11 02:56:53 +00:00
Data [ key ] = new ImageUsage ( usage [ key ] , null ) ;
2020-11-07 16:01:33 +00:00
}
}
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
{
2020-11-07 16:01:33 +00:00
if ( Data . TryGetValue ( path , out var value ) )
{
value . usage + + ;
return value . imageSource ;
}
2020-11-15 12:45:00 +00:00
2020-11-12 02:34:23 +00:00
return null ;
2014-12-18 11:22:47 +00:00
}
2020-08-05 09:30:45 +00:00
set
{
2020-11-12 02:34:23 +00:00
Data . AddOrUpdate (
2020-11-15 12:45:00 +00:00
path ,
new ImageUsage ( 0 , value ) ,
2020-11-12 02:34:23 +00:00
( k , v ) = >
{
v . imageSource = value ;
v . usage + + ;
return v ;
}
) ;
2020-08-05 09:30:45 +00:00
// 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
2020-11-07 16:01:33 +00:00
if ( Data . Count > permissibleFactor * MaxCached )
2020-08-05 09:30:45 +00:00
{
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary.
2020-11-26 20:04:39 +00:00
foreach ( var key in Data . OrderBy ( x = > x . Value . usage ) . Take ( Data . Count - MaxCached ) . Select ( x = > x . Key ) )
2020-11-15 13:03:39 +00:00
Data . TryRemove ( key , out _ ) ;
2020-08-05 09:30:45 +00:00
}
}
2016-05-22 04:30:38 +00:00
}
2014-12-18 11:22:47 +00:00
2017-01-13 15:40:32 +00:00
public bool ContainsKey ( string key )
{
2020-11-16 05:04:16 +00:00
return Data . ContainsKey ( key ) & & Data [ key ] . imageSource ! = null ;
2014-12-18 11:22:47 +00:00
}
2020-01-03 19:16:17 +00:00
public int CacheSize ( )
{
2020-11-07 16:01:33 +00:00
return Data . Count ;
2020-01-03 19:16:17 +00:00
}
/// <summary>
/// return the number of unique images in the cache (by reference not by checking images content)
/// </summary>
public int UniqueImagesInCache ( )
{
2020-11-07 16:01:33 +00:00
return Data . Values . Select ( x = > x . imageSource ) . Distinct ( ) . Count ( ) ;
2020-01-03 19:16:17 +00:00
}
2014-12-18 11:22:47 +00:00
}
2020-08-05 09:30:45 +00:00
}