1212#import " FICImageTableChunk.h"
1313#import " FICImageTableEntry.h"
1414#import " FICUtilities.h"
15- #import " FICWeakReference.h"
1615
1716#import " FICImageCache+FICErrorLogging.h"
1817
@@ -51,7 +50,8 @@ @interface FICImageTable () {
5150 NSInteger _chunkCount;
5251
5352 NSMutableDictionary *_chunkDictionary;
54- NSMutableArray *_recentChunks;
53+ NSCountedSet *_chunkSet;
54+
5555 NSRecursiveLock *_lock;
5656
5757 // Image table metadata
@@ -140,6 +140,7 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
140140 _imageLength = _imageRowLength * (NSInteger )pixelSize.height ;
141141
142142 _chunkDictionary = [[NSMutableDictionary alloc ] init ];
143+ _chunkSet = [[NSCountedSet alloc ] init ];
143144
144145 _indexMap = [[NSMutableDictionary alloc ] init ];
145146 _occupiedIndexes = [[NSMutableIndexSet alloc ] init ];
@@ -149,8 +150,6 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
149150
150151 _sourceImageMap = [[NSMutableDictionary alloc ] init ];
151152
152- _recentChunks = [[NSMutableArray alloc ] init ];
153-
154153 _filePath = [[self tableFilePath ] copy ];
155154
156155 [self _loadMetadata ];
@@ -206,24 +205,13 @@ - (void)dealloc {
206205#pragma mark - Working with Chunks
207206
208207- (FICImageTableChunk *)_cachedChunkAtIndex : (NSInteger )index {
209- FICImageTableChunk *cachedChunk = nil ;
210- NSNumber *indexNumber = @(index);
211- FICWeakReference *chunkReference = [_chunkDictionary objectForKey: indexNumber];
212-
213- if (chunkReference) {
214- cachedChunk = [chunkReference object ];
215- if (!cachedChunk) {
216- [_chunkDictionary removeObjectForKey: indexNumber];
217- }
218- }
219-
220- return cachedChunk;
208+ return [_chunkDictionary objectForKey: @(index)];
221209}
222210
223211- (void )_setChunk : (FICImageTableChunk *)chunk index : (NSInteger )index {
224212 NSNumber *indexNumber = @(index);
225213 if (chunk != nil ) {
226- [_chunkDictionary setObject: [[FICWeakReference alloc ] initWithObject: chunk] forKey: indexNumber];
214+ [_chunkDictionary setObject: chunk forKey: indexNumber];
227215 } else {
228216 [_chunkDictionary removeObjectForKey: indexNumber];
229217 }
@@ -245,15 +233,6 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
245233 chunk = [[FICImageTableChunk alloc ] initWithFileDescriptor: _fileDescriptor index: index length: chunkLength];
246234 [self _setChunk: chunk index: index];
247235 }
248-
249- if (chunk != nil ) {
250- static const NSInteger __recentChunksToKeepMapped = 2 ;
251- [_recentChunks insertObject: chunk atIndex: 0 ];
252-
253- if ([_recentChunks count ] > __recentChunksToKeepMapped) {
254- [_recentChunks removeLastObject ];
255- }
256- }
257236 }
258237
259238 return chunk;
@@ -467,6 +446,13 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
467446 void *mappedChunkAddress = [chunk bytes ];
468447 void *mappedEntryAddress = mappedChunkAddress + entryOffsetInChunk;
469448 entryData = [[FICImageTableEntry alloc ] initWithImageTableChunk: chunk bytes: mappedEntryAddress length: _entryLength];
449+
450+ [_chunkSet addObject: chunk];
451+
452+ __weak FICImageTable *weakSelf = self;
453+ [entryData executeBlockOnDealloc: ^{
454+ [weakSelf _entryWasDeallocatedFromChunk: chunk];
455+ }];
470456 }
471457 }
472458
@@ -475,6 +461,15 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
475461 return entryData;
476462}
477463
464+ - (void )_entryWasDeallocatedFromChunk : (FICImageTableChunk *)chunk {
465+ [_lock lock ];
466+ [_chunkSet removeObject: chunk];
467+ if ([_chunkSet countForObject: chunk] == 0 ) {
468+ [self _setChunk: nil index: [chunk index ]];
469+ }
470+ [_lock unlock ];
471+ }
472+
478473- (NSInteger )_nextEntryIndex {
479474 NSMutableIndexSet *unoccupiedIndexes = [[NSMutableIndexSet alloc ] initWithIndexesInRange: NSMakeRange (0 , _entryCount)];
480475 [unoccupiedIndexes removeIndexes: _occupiedIndexes];
0 commit comments