What is cache?

Cache is a pointer to cache_t in a class structure. As for metaclasses, the root metaclasses are similar. Everything is an object. The specific code structure is as follows:

    struct bucket_t *_buckets;
    mask_t _mask;
    mask_t _occupied;
Copy the code

_buckets

_buckets points to the pointer to the data entry of the cache block, which stores the bucket_t structure. Bucket_t structure is as follows:

MethodCacheIMP _imp; Cache_key_t _key; // Convert the method name to a numeric keyCopy the code

_mask

_mask, mask, salt. Value = Capacity () -1, total quantity -1. It is used to search the cache and perform ampersand on the key, and to obtain a hash array index using the hash function. View the source code left and right as follows:

cache_hash(k, m);

static inline mask_t cache_hash(cache_key_t key, mask_t mask) 
{
    return (mask_t)(key & mask);
}

Copy the code

_occupied

_occupied: Number of occupied memory blocks. This parameter indicates the size of the occupied memory block. This parameter is compared with capacity() to determine whether to expand the capacity. The process will be described below.

Cache method writing process

1. Call the fill method

Cache_fill (Class CLS, SEL SEL, IMP IMP, id receiver); Cache_fill_nolock (Class CLS, SEL SEL, IMP IMP, ID receiver)

A) whether the class has been initialized. If not, return if (! cls->isInitialized()) return;

If (cache_getImp(CLS, sel)) return if (cache_getImp(CLS, sel));

Cache_t *cache = getCache(CLS); cache_t = getCache(CLS); cache_key_t key = getKey(sel); mask_t newOccupied = cache->occupied() + 1; mask_t capacity = cache->capacity();

D) check whether the cache is read-only. If yes, restart the cache

if (cache->isConstantEmptyCache()) {
        // Cache is read-only. Replace it. cache->reallocate(capacity, capacity ? : INIT_CACHE_SIZE); }Copy the code

E) Check whether the occupied capacity exceeds 3/4 of the total capacity. If so, expand cache->expand(); Double the capacity, erase the previously cached data, reassign capacity (), mask

else if (newOccupied <= capacity / 4 * 3) {
        // Cache is less than 3/4 full. Use it as-is.
    }
    else {
        // Cache is too full. Expand it.
        cache->expand();
    }
Copy the code

If (key() == 0, the cache method has not been started yet. Bad_cache (receiver, (SEL)k, CLS) is a bad memory call if all buckets are searched and none are found; An error message is reported.

bucket_t *bucket = cache->find(key, receiver);
Copy the code

If (key() == 0);

if (bucket->key() == 0) cache->incrementOccupied();
Copy the code

Bucket ->set(key, imp);

bucket->set(key, imp);
Copy the code

At this point, the cache write and search processes are clear.

Interested in studying the bottom of the friends can add QQ communication

QQ:578200388

E-mail: 578200388 @qq.com