1010using AForge ;
1111namespace BioCore
1212{
13- public class LruCache < TKey , TValue >
13+ public class LruCache < TileInformation , TValue >
1414 {
15+ public class Info
16+ {
17+ public ZCT Coordinate { get ; set ; }
18+ public TileIndex Index { get ; set ; }
19+ }
1520 private readonly int capacity ;
16- private Dictionary < TKey , LinkedListNode < ( TKey key , TValue value ) > > cacheMap = new Dictionary < TKey , LinkedListNode < ( TKey key , TValue value ) > > ( ) ;
17- private LinkedList < ( TKey key , TValue value ) > lruList = new LinkedList < ( TKey key , TValue value ) > ( ) ;
21+ private Dictionary < Info , LinkedListNode < ( Info key , TValue value ) > > cacheMap = new Dictionary < Info , LinkedListNode < ( Info key , TValue value ) > > ( ) ;
22+ private LinkedList < ( Info key , TValue value ) > lruList = new LinkedList < ( Info key , TValue value ) > ( ) ;
1823
1924 public LruCache ( int capacity )
2025 {
2126 this . capacity = capacity ;
2227 }
2328
24- public TValue Get ( TKey key )
29+ public TValue Get ( Info key )
2530 {
26- if ( cacheMap . TryGetValue ( key , out var node ) )
31+ foreach ( LinkedListNode < ( Info key , TValue value ) > item in cacheMap . Values )
2732 {
28- lruList . Remove ( node ) ;
29- lruList . AddLast ( node ) ;
30- return node . Value . value ;
33+ Info k = item . Value . key ;
34+ if ( k . Coordinate == key . Coordinate && k . Index == key . Index )
35+ {
36+ lruList . Remove ( item ) ;
37+ lruList . AddLast ( item ) ;
38+ return item . Value . value ;
39+ }
3140 }
32-
3341 return default ( TValue ) ;
3442 }
3543
36- public void Add ( TKey key , TValue value )
44+ public void Add ( Info key , TValue value )
3745 {
3846 if ( cacheMap . Count >= capacity )
3947 {
@@ -50,41 +58,48 @@ public void Add(TKey key, TValue value)
5058 lruList . Remove ( cacheMap [ key ] ) ;
5159 }
5260
53- var newNode = new LinkedListNode < ( TKey key , TValue value ) > ( ( key , value ) ) ;
61+ var newNode = new LinkedListNode < ( Info key , TValue value ) > ( ( key , value ) ) ;
5462 lruList . AddLast ( newNode ) ;
5563 cacheMap [ key ] = newNode ;
5664 }
5765 }
5866 public class TileCache
5967 {
60- private LruCache < TileInfo , byte [ ] > cache ;
68+ private LruCache < TileInformation , byte [ ] > cache ;
6169 private int capacity ;
6270 SlideSourceBase source = null ;
63- public TileCache ( SlideSourceBase source , int capacity = 10000 )
71+ public TileCache ( SlideSourceBase source , int capacity = 1000 )
6472 {
6573 this . source = source ;
6674 this . capacity = capacity ;
67- this . cache = new LruCache < TileInfo , byte [ ] > ( capacity ) ;
75+ this . cache = new LruCache < TileInformation , byte [ ] > ( capacity ) ;
6876 }
6977
70- public async Task < byte [ ] > GetTile ( TileInfo info )
78+ public async Task < byte [ ] > GetTile ( TileInformation info )
7179 {
72- byte [ ] data = cache . Get ( info ) ;
80+ LruCache < TileInformation , byte [ ] > . Info inf = new LruCache < TileInformation , byte [ ] > . Info ( ) ;
81+ inf . Coordinate = info . Coordinate ;
82+ inf . Index = info . Index ;
83+ byte [ ] data = cache . Get ( inf ) ;
7384 if ( data != null )
7485 {
7586 return data ;
7687 }
7788 byte [ ] tile = await LoadTile ( info ) ;
89+ if ( tile != null )
7890 AddTile ( info , tile ) ;
7991 return tile ;
8092 }
8193
82- private void AddTile ( TileInfo tileId , byte [ ] tile )
94+ private void AddTile ( TileInformation tileId , byte [ ] tile )
8395 {
84- cache . Add ( tileId , tile ) ;
96+ LruCache < TileInformation , byte [ ] > . Info inf = new LruCache < TileInformation , byte [ ] > . Info ( ) ;
97+ inf . Coordinate = tileId . Coordinate ;
98+ inf . Index = tileId . Index ;
99+ cache . Add ( inf , tile ) ;
85100 }
86101
87- private async Task < byte [ ] > LoadTile ( TileInfo tileId )
102+ private async Task < byte [ ] > LoadTile ( TileInformation tileId )
88103 {
89104 try
90105 {
@@ -97,7 +112,7 @@ private async Task<byte[]> LoadTile(TileInfo tileId)
97112 }
98113 }
99114
100- public class TileInfo
115+ public class TileInformation
101116 {
102117 public TileIndex Index { get ; set ; }
103118 public Extent Extent { get ; set ; }
@@ -124,7 +139,7 @@ public static void Resister(string extensionUpper, Func<string, bool, ISlideSour
124139
125140 public static ISlideSource Create ( BioImage source , SlideImage im , bool enableCache = true )
126141 {
127-
142+
128143 var ext = Path . GetExtension ( source . file ) . ToUpper ( ) ;
129144 try
130145 {
@@ -134,12 +149,12 @@ public static ISlideSource Create(BioImage source, SlideImage im, bool enableCac
134149 if ( ! string . IsNullOrEmpty ( SlideBase . DetectVendor ( source . file ) ) )
135150 {
136151 SlideBase b = new SlideBase ( source , im , enableCache ) ;
137-
152+
138153 }
139154 }
140- catch ( Exception e )
141- {
142- Console . WriteLine ( e . Message ) ;
155+ catch ( Exception e )
156+ {
157+ Console . WriteLine ( e . Message ) ;
143158 }
144159 return null ;
145160 }
@@ -161,13 +176,13 @@ public async Task<byte[]> GetSlice(SliceInfo sliceInfo)
161176 List < Tuple < Extent , byte [ ] > > tiles = new List < Tuple < Extent , byte [ ] > > ( ) ;
162177 foreach ( BruTile . TileInfo t in tileInfos )
163178 {
164- TileInfo tf = new TileInfo ( ) ;
179+ TileInformation tf = new TileInformation ( ) ;
165180 tf . Extent = t . Extent ;
166181 tf . Coordinate = App . viewer . GetCoordinate ( ) ;
167182 tf . Index = t . Index ;
168183 byte [ ] c = await cache . GetTile ( tf ) ;
169- if ( c != null )
170- tiles . Add ( Tuple . Create ( t . Extent . WorldToPixelInvertedY ( curUnitsPerPixel ) , c ) ) ;
184+ if ( c != null )
185+ tiles . Add ( Tuple . Create ( t . Extent . WorldToPixelInvertedY ( curUnitsPerPixel ) , c ) ) ;
171186 }
172187 var srcPixelExtent = sliceInfo . Extent . WorldToPixelInvertedY ( curUnitsPerPixel ) ;
173188 var dstPixelExtent = sliceInfo . Extent . WorldToPixelInvertedY ( sliceInfo . Resolution ) ;
@@ -264,7 +279,7 @@ public void Dispose()
264279 GC . SuppressFinalize ( this ) ;
265280 }
266281
267- public async Task < byte [ ] > GetTileAsync ( TileInfo tileInfo )
282+ public async Task < byte [ ] > GetTileAsync ( TileInformation tileInfo )
268283 {
269284 if ( tileInfo == null )
270285 return null ;
@@ -275,7 +290,7 @@ public async Task<byte[]> GetTileAsync(TileInfo tileInfo)
275290 var curLevelOffsetYPixel = - tileInfo . Extent . MaxY / Schema . Resolutions [ tileInfo . Index . Level ] . UnitsPerPixel ;
276291 var curTileWidth = ( int ) ( tileInfo . Extent . MaxX > Schema . Extent . Width ? tileWidth - ( tileInfo . Extent . MaxX - Schema . Extent . Width ) / r : tileWidth ) ;
277292 var curTileHeight = ( int ) ( - tileInfo . Extent . MinY > Schema . Extent . Height ? tileHeight - ( - tileInfo . Extent . MinY - Schema . Extent . Height ) / r : tileHeight ) ;
278- var bgraData = await Image . ReadRegionAsync ( tileInfo . Index . Level , ( long ) curLevelOffsetXPixel , ( long ) curLevelOffsetYPixel , curTileWidth , curTileHeight , tileInfo . Coordinate ) ;
293+ var bgraData = await Image . ReadRegionAsync ( tileInfo . Index . Level , ( long ) curLevelOffsetXPixel , ( long ) curLevelOffsetYPixel , curTileWidth , curTileHeight , tileInfo . Coordinate ) ;
279294 //We check to see if the data is valid.
280295 if ( bgraData . Length != curTileWidth * curTileHeight * 4 )
281296 return null ;
@@ -381,7 +396,7 @@ public SliceInfo() { }
381396 /// <param name="unitsPerPixel">um/pixel</param>
382397 public SliceInfo ( double xPixel , double yPixel , double widthPixel , double heightPixel , double unitsPerPixel , ZCT coord )
383398 {
384- Extent = new Extent ( xPixel , yPixel , xPixel + widthPixel , yPixel + heightPixel ) . PixelToWorldInvertedY ( unitsPerPixel ) ;
399+ Extent = new Extent ( xPixel , yPixel , xPixel + widthPixel , yPixel + heightPixel ) . PixelToWorldInvertedY ( unitsPerPixel ) ;
385400 Resolution = unitsPerPixel ;
386401 }
387402
0 commit comments