RKCache Class Reference

Inherits fromNSObject
RegexKit0.6.0 Release Notes
PCRE7.6
AvailabilityAvailable in Mac OS X v10.4 or later.
Declared in
  • RegexKit/RKCache.h
Overview
Important:
The RKCache class is not intended for general usage. This documentation is provided for completeness and to aid in debugging issues.

The RKCache class declares the programmatic interface for the RKRegex framework caching feature.

Some of the features provided by the RKCache class are:

Restrictions

While a RKCache will permit any type of object to be added, as a pragmatic limitation only immutable objects should be added to a cache. In essence, a RKCache is a multithreading safe NSMutableSet. The cache can only ensure that an object retrieved from the cache will not be deallocated before the retrieving thread has finished with the object and released it properly. Once an object has been retrieved, the retrieved object must provide any concurrent modification safety mechanisms. Since immutable objects can not be modified by definition, this greatly simplifies concurrent access to objects and is the reason why only immutable objects should be added in general.

A RKCache is best applied to situations in which a result can take an appreciable amount of time to prepare, but once computed, the result can be used again and again. For example, the RegexKit.framework must compile a regular expression to an internal format before it can perform any matches with it. The compiled regular expression does not change, and can be reused again and again. While compiling a regular expression is relatively quick, it can still be an order of magnitude slower than a cache lookup.

Ownership and deallocation of cached objects

When an object is added to the cache, it is sent a retain message just as if it were being added to any other type of collection. Similarly, when an object is removed from the cache, it is sent a release message. Adding or removing objects from the cache requires the thread to obtain the exclusive use write lock on the cache. There can be any number of simultaneous threads with a read lock, but the write lock guarantees that the write lock owner is the only thread accessing the cache.

The cache takes certain steps to ensure that objects are not deallocated while in use even if another thread immediately clears the cache after the requesting thread has retrieved an object. To do this, the cache obtains a read lock on the NSMapTable and performs a lookup. If there is a match, the cache sends a retain message to the retrieved object while it still has the cache read locked and then releases its read lock. A different thread might immediately obtain a write lock on the cache and clear it, causing the cache to release ownership of the just retrieved object. Since the cache sent a retain message to the just retrieved object, it is not immediately deallocated. If the caller requests it, the cache sends an autorelease to the object before returning it.

Each thread is required to have at least one NSAutoreleasePool. Since the autorelease is registered with the retrieving threads NSAutoreleasePool, this ensures that the object will not be deallocated until the requesting threads NSAutoreleasePool is released. A caller might request that an autorelease not be sent automatically after the object was retrieved because it will be returning the result as part of an init... method and would have to counter the autorelease with another retain message immediately, wasting effort.

Tasks

Creating Caches
Adding, Retrieving, and Removing Objects from the Cache
Cache Information
Cache Maintenance

Instance Methods

Add an object to the cache.
- (BOOL)addObjectToCache:(id)object;
Discussion
Invokes addObjectToCache:withHash: with object and the result of [object hash] for the hash value.
Return Value
Returns YES if object was successfully added to the cache, NO otherwise.
Add an object to the cache using the supplied objectHash value.
- (BOOL)addObjectToCache:(id)object withHash:(const RKUInteger)objectHash;
Parameters
  • object
    The object to add to the cache.
  • objectHash
    The hash that represents the value of object.
Discussion

This method may be used in place of addObjectToCache: when either the hash value is already computed and available, or to override the default value that would be returned by [object hash].

Reasons for returning NO and not adding an object to the cache include:

  • An object in the cache with a hash of objectHash is already in the cache.
  • Caching was not enabled when the add was attempted. See setCacheEnabled:.
  • An error occurred while attempting to add object to the cache.
Return Value
Returns YES if object was successfully added to the cache, NO otherwise.
The number of objects currently in the cache.
- (RKUInteger)cacheCount;
A NSSet of the objects cached.
- (NSSet *)cacheSet;
Discussion

Creates a new, autoreleased NSSet by adding all of the objects currently in the cache to a new NSSet. This is done while the cache is locked, and once all the current objects are added, the cache is unlocked. Therefore it is possible that the objects in the returned NSSet and the objects in the cache are no longer the same as another thread may have added, removed, or cleared the cache by the time the caller receives the NSSet result. It is, in essence, a snapshot of contents of the cache at the instant in time it was created.

The objects in the returned NSSet have their retain count incremented by being included in the NSSet. Therefore, even if the cache is cleared by another thread, it is still safe to use the objects contained in the returned NSSet.

Removes all objects from the cache.
- (BOOL)clearCache;
The receivers description together with the information from status.
- (NSString *)description;
Discussion

Example:

NSString *cacheDescription = [cacheObject description]; // Example cacheDescription: // <RKCache: 0x512750> "RKRegex Cache" Enabled = Yes, Cleared count = 0, Cache count = 27, Hit rate = 96.27%, Hits = 697, Misses = 27, Total = 724

Example usage with %@ format specifier:

NSLog(@"cache info:\n%@\n", [RKRegex regexCache]); // NSLog output: // 2007-08-06 14:07:05.738 cli_test[19615] cache info: // <RKCache: 0x512750> "RKRegex Cache" Enabled = Yes, Cleared count = 0, Cache count = 27, Hit rate = 96.27%, Hits = 697, Misses = 27, Total = 724
Initializes a new RKCache with the caller supplied description of the cache.
- (id)initWithDescription:(NSString * const)descriptionString;
Returns whether or not the cache is currently enabled.
- (BOOL)isCacheEnabled;
Return the cached object for the supplied hash, if it exists.
- (id)objectForHash:(const RKUInteger)objectHash description:(NSString * const)descriptionString;
Parameters
  • objectHash
    The hash that represents the value of an object.
  • descriptionString
    A description of the object.
Discussion

Invokes objectForHash:description:autorelease: with objectHash, descriptionString, and YES for autorelease.

Important:
The returned object will be released when the current NSAutoreleasePool is released. Therefore, the caller must send the returned object a retain message if the object will be used past the current NSAutoreleasePool context.
Return Value
Returns the object that matches objectHash if it currently exists in the cache, nil otherwise.
Return the cached object for the supplied hash, if it exists.
- (id)objectForHash:(const RKUInteger)objectHash description:(NSString * const)descriptionString autorelease:(const BOOL)shouldAutorelease;
Parameters
  • objectHash
    The hash that represents the value of an object.
  • descriptionString
    A description of the object.
  • shouldAutorelease
    While the cache is locked, the object matching objectHash is sent a retain to ensure the object is not deallocated once the cache lock is released. If YES, the object is also sent an autorelease to keep the retain count balanced. If NO, the caller takes responsibility for releasing the returned cached object when finished with it.
Discussion

This method is used in cases such as returning a cached object from an init... method to avoid adding the object unnecessarily to the current NSAutoreleasePool which would result in wasted work because init... would require sending a retain to counter the autorelease.

Return Value
Returns the object that matches objectHash if it currently exists in the cache, nil otherwise.
Removes the specified object from the cache.
- (id)removeObjectFromCache:(id)object;
Discussion

Invokes removeObjectWithHash: with the value of [object hash].

The returned object may not be the same object as object. The returned object is the instantiated object that was originally added to the cache, but will have the same hash value as object and [object isEqual:theRemovedObject] == YES.

Return Value
Removes and returns the object in the cache that has a hash value of object. Returns nil if no such object was in the cache.
Removes the specified object from the cache.
- (id)removeObjectWithHash:(const RKUInteger)objectHash;
Parameters
  • objectHash
    The hash that represents the value of an object.
Discussion

The object to be removed, if any, is sent both a retain and autorelease while the cache is locked. This ensures that the object returned remains live in the callers thread for the duration of the callers current NSAutoreleasePool pool. If you wish to use the object past that point, you must take ownership of it by sending a retain message. This is similar to various convenience functions, such as [NSString stringWithFormat:@"Hello"].

Return Value
Returns the object in the cache that has the hash value of objectHash. Returns nil if there is was no object in the cache matching objectHash.
Enables or disables the cache.
- (BOOL)setCacheEnabled:(const BOOL)enableCache;
Return Value
Returns YES if the cache was successfully enabled, NO otherwise.
Sets the description of the cache to descriptionString
- (void)setDescription:(NSString * const)descriptionString;
A string containing the cache status, including some statistics.
- (NSString *)status;
Discussion

Includes information about the cache, such as the number of objects currently cached and cache effectiveness.

Example:

NSString *cacheStatus = [[RKRegex cache] status]; // Example cacheStatus: // @"Enabled = Yes, Cleared count = 0, Cache count = 27, Hit rate = 96.27%, Hits = 697, Misses = 27, Total = 724";
See Also
 
RegexKit project hosted by: