Skip to content

Commit 75dc4c2

Browse files
committed
Tile Cache Fix.
1 parent b60f463 commit 75dc4c2

2 files changed

Lines changed: 50 additions & 35 deletions

File tree

BioCore/BioCore.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>net8.0-windows</TargetFramework>
55
<Nullable>enable</Nullable>
6-
<Version>4.0.0</Version>
6+
<Version>4.0.1</Version>
77
<UseWindowsForms>true</UseWindowsForms>
88
<ImplicitUsings>enable</ImplicitUsings>
99
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
@@ -23,9 +23,9 @@
2323
<PackageId>BioCore</PackageId>
2424
<Platforms>AnyCPU;x86;x64</Platforms>
2525
<Description>A .NET library &amp; program for annotating, &amp; editing various microscopy imaging formats using Bioformats supported images. including whole slide, pyramidal &amp; series.</Description>
26-
<AssemblyVersion>4.0.0</AssemblyVersion>
27-
<FileVersion>4.0.0</FileVersion>
28-
<PackageReleaseNotes>.NET8 update.</PackageReleaseNotes>
26+
<AssemblyVersion>4.0.1</AssemblyVersion>
27+
<FileVersion>4.0.1</FileVersion>
28+
<PackageReleaseNotes>Tile Cache Fix.</PackageReleaseNotes>
2929
</PropertyGroup>
3030

3131
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

BioCore/Source/Bio/ISlideSource.cs

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,38 @@
1010
using AForge;
1111
namespace 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

Comments
 (0)