TumblrArchive / TMCache

Fast parallel object cache for iOS and OS X.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Define a limit to TMMemoryCache memory consumption

mackoj opened this issue · comments

It will be nice if we can be able to define the maximum memory usable by in-memory cache mechanism.

I agree, but I don't think it's possible. There's no reliable way to know how much memory an arbitrary object consumes, especially if it's mutable and has the potential to change over time without notice.

Instead, TMMemoryCache has a setObject:forKey:withCost: method and a costLimit property. The cost is an integer that you define, and if you know the size of your objects this can effectively be a byte limit.

For instance, if you know that you only need to store NSData in the cache and want to limit the size to 1 megabyte:

[[TMMemoryCache sharedCache] setCostLimit:0x100000];
[[TMMemoryCache sharedCache] setObject:data forKey@"someData" withCost:[data length]];

Ok, thanks I understand it better now.

What is the rule when the cost limit has been reached ? Does it remove everything or just the first things added ? How does it select what to remove ?

Maybe you can make a ring buffer with a size limit. This a naive example with strings but it should work perfectly with a few modification with anything that respond to NSCopying protocol.

@interface NSMutableArray (PseudoRingBuffer)
- (NSUInteger)sizeInOctet;
- (void)addString:(NSString*)s;
@end

@implementation NSMutableArray (PseudoRingBuffer)

- (NSUInteger)sizeInOctet {
    NSUInteger acc = 0;
    for (NSString *s in self) {
        acc += [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    }
    return acc;
}

- (void)addString:(NSString*)s {
    [self addObject:s];
    while ([self sizeInOctet] > RINGBUFFERSIZE) {
        [self removeObjectAtIndex:0];
    }
}
@end

Really interesting idea! I hadn't thought of using NSCopying like that, I'll have to think about it some more. Thank you.

Everything is documented in the header for TMMemoryCache, check out costLimit and trimToCostByDate:

https://github.com/tumblr/TMCache/blob/master/TMCache/TMMemoryCache.h

Since lengthOfBytesUsingEncoding: is specific to NSString (and not NSCopying) it's not going to be much help in the general case, unfortunately. I'd still love a way to know the byte size in memory of any arbitrary object, but I don't think it exists.