4
4
using System . Linq ;
5
5
using System . Threading ;
6
6
using System . Windows . Media ;
7
+ using FastCache ;
8
+ using FastCache . Services ;
7
9
8
10
namespace Flow . Launcher . Infrastructure . Image
9
11
{
10
- [ Serializable ]
11
12
public class ImageUsage
12
13
{
13
-
14
14
public int usage ;
15
15
public ImageSource imageSource ;
16
16
@@ -23,95 +23,77 @@ public ImageUsage(int usage, ImageSource image)
23
23
24
24
public class ImageCache
25
25
{
26
- private const int MaxCached = 50 ;
27
- public ConcurrentDictionary < ( string , bool ) , ImageUsage > Data { get ; } = new ( ) ;
28
- private const int permissibleFactor = 2 ;
29
- private SemaphoreSlim semaphore = new ( 1 , 1 ) ;
26
+ private const int MaxCached = 150 ;
30
27
31
28
public void Initialize ( Dictionary < ( string , bool ) , int > usage )
32
29
{
33
30
foreach ( var key in usage . Keys )
34
31
{
35
- Data [ key ] = new ImageUsage ( usage [ key ] , null ) ;
32
+ Cached < ImageUsage > . Save ( key , new ImageUsage ( usage [ key ] , null ) , TimeSpan . MaxValue , MaxCached ) ;
36
33
}
37
34
}
38
35
39
36
public ImageSource this [ string path , bool isFullImage = false ]
40
37
{
41
38
get
42
39
{
43
- if ( ! Data . TryGetValue ( ( path , isFullImage ) , out var value ) )
40
+ if ( ! Cached < ImageUsage > . TryGet ( ( path , isFullImage ) , out var value ) )
44
41
{
45
42
return null ;
46
43
}
47
- value . usage ++ ;
48
- return value . imageSource ;
49
44
45
+ value . Value . usage ++ ;
46
+ return value . Value . imageSource ;
50
47
}
51
48
set
52
49
{
53
- Data . AddOrUpdate (
54
- ( path , isFullImage ) ,
55
- new ImageUsage ( 0 , value ) ,
56
- ( k , v ) =>
57
- {
58
- v . imageSource = value ;
59
- v . usage ++ ;
60
- return v ;
61
- }
62
- ) ;
63
-
64
- SliceExtra ( ) ;
65
-
66
- async void SliceExtra ( )
50
+ if ( Cached < ImageUsage > . TryGet ( ( path , isFullImage ) , out var cached ) )
67
51
{
68
- // 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
69
- // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time
70
- if ( Data . Count > permissibleFactor * MaxCached )
71
- {
72
- await semaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
73
- // To delete the images from the data dictionary based on the resizing of the Usage Dictionary
74
- // Double Check to avoid concurrent remove
75
- if ( Data . Count > permissibleFactor * MaxCached )
76
- foreach ( var key in Data . OrderBy ( x => x . Value . usage ) . Take ( Data . Count - MaxCached ) . Select ( x => x . Key ) )
77
- Data . TryRemove ( key , out _ ) ;
78
- semaphore . Release ( ) ;
79
- }
52
+ cached . Value . imageSource = value ;
53
+ cached . Value . usage ++ ;
80
54
}
55
+
56
+ Cached < ImageUsage > . Save ( ( path , isFullImage ) , new ImageUsage ( 0 , value ) , TimeSpan . MaxValue ,
57
+ MaxCached ) ;
81
58
}
82
59
}
83
60
84
61
public bool ContainsKey ( string key , bool isFullImage )
85
62
{
86
- return key is not null && Data . ContainsKey ( ( key , isFullImage ) ) && Data [ ( key , isFullImage ) ] . imageSource != null ;
63
+ return Cached < ImageUsage > . TryGet ( ( key , isFullImage ) , out _ ) ;
87
64
}
88
65
89
66
public bool TryGetValue ( string key , bool isFullImage , out ImageSource image )
90
67
{
91
- if ( key is not null )
92
- {
93
- bool hasKey = Data . TryGetValue ( ( key , isFullImage ) , out var imageUsage ) ;
94
- image = hasKey ? imageUsage . imageSource : null ;
95
- return hasKey ;
96
- }
97
- else
68
+ if ( Cached < ImageUsage > . TryGet ( ( key , isFullImage ) , out var value ) )
98
69
{
99
- image = null ;
100
- return false ;
70
+ image = value . Value . imageSource ;
71
+ value . Value . usage ++ ;
72
+ return image != null ;
101
73
}
74
+
75
+ image = null ;
76
+ return false ;
102
77
}
103
78
104
79
public int CacheSize ( )
105
80
{
106
- return Data . Count ;
81
+ return CacheManager . TotalCount < ( string , bool ) , ImageUsage > ( ) ;
107
82
}
108
83
109
84
/// <summary>
110
85
/// return the number of unique images in the cache (by reference not by checking images content)
111
86
/// </summary>
112
87
public int UniqueImagesInCache ( )
113
88
{
114
- return Data . Values . Select ( x => x . imageSource ) . Distinct ( ) . Count ( ) ;
89
+ return CacheManager . EnumerateEntries < ( string , bool ) , ImageUsage > ( ) . Select ( x => x . Value . imageSource )
90
+ . Distinct ( )
91
+ . Count ( ) ;
92
+ }
93
+
94
+ public IEnumerable < Cached < ( string , bool ) , ImageUsage > > EnumerateEntries ( )
95
+ {
96
+ return CacheManager . EnumerateEntries < ( string , bool ) , ImageUsage > ( ) ;
115
97
}
116
98
}
117
99
}
0 commit comments