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 ;
2021-07-31 08:23:58 +00:00
using System.Threading ;
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 ;
2022-10-30 19:39:57 +00:00
public ConcurrentDictionary < ( string , bool ) , ImageUsage > Data { get ; } = new ( ) ;
2020-08-05 09:30:45 +00:00
private const int permissibleFactor = 2 ;
2021-07-31 08:23:58 +00:00
private SemaphoreSlim semaphore = new ( 1 , 1 ) ;
2021-05-23 14:54:52 +00:00
2022-10-30 19:39:57 +00:00
public void Initialization ( Dictionary < ( string , bool ) , int > usage )
2020-11-07 16:01:33 +00:00
{
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
}
}
2022-10-30 19:39:57 +00:00
public ImageSource this [ string path , bool isFullImage = false ]
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
{
2022-10-30 19:39:57 +00:00
if ( ! Data . TryGetValue ( ( path , isFullImage ) , out var value ) )
2020-11-07 16:01:33 +00:00
{
2022-10-30 19:39:57 +00:00
return null ;
2020-11-07 16:01:33 +00:00
}
2022-10-30 19:39:57 +00:00
value . usage + + ;
return value . imageSource ;
2020-11-15 12:45:00 +00:00
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 (
2022-10-30 19:39:57 +00:00
( path , isFullImage ) ,
new ImageUsage ( 0 , value ) ,
( k , v ) = >
{
v . imageSource = value ;
v . usage + + ;
return v ;
}
2020-11-12 02:34:23 +00:00
) ;
2020-08-05 09:30:45 +00:00
2021-07-31 08:23:58 +00:00
SliceExtra ( ) ;
async void SliceExtra ( )
2020-08-05 09:30:45 +00:00
{
2021-07-31 08:23:58 +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
if ( Data . Count > permissibleFactor * MaxCached )
{
2021-08-08 05:46:31 +00:00
await semaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
2021-07-31 08:23:58 +00:00
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary
// Double Check to avoid concurrent remove
if ( Data . Count > permissibleFactor * MaxCached )
2022-02-28 01:24:11 +00:00
foreach ( var key in Data . OrderBy ( x = > x . Value . usage ) . Take ( Data . Count - MaxCached ) . Select ( x = > x . Key ) )
2021-07-31 08:23:58 +00:00
Data . TryRemove ( key , out _ ) ;
semaphore . Release ( ) ;
}
2020-08-05 09:30:45 +00:00
}
}
2016-05-22 04:30:38 +00:00
}
2014-12-18 11:22:47 +00:00
2022-10-30 19:39:57 +00:00
public bool ContainsKey ( string key , bool isFullImage )
2017-01-13 15:40:32 +00:00
{
2022-10-30 19:39:57 +00:00
return key is not null & & Data . ContainsKey ( ( key , isFullImage ) ) & & Data [ ( key , isFullImage ) ] . 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
}
2022-10-30 19:39:57 +00:00
}