13期_iOS_cache_t探究

2023-08-15  本文已影响0人  萧修

cach_t的结构

struct cache_t {
    struct bucket_t *buckets() const;
    mask_t mask() const;
    mask_t _occupied;
}

buckets:装方法的桶子,里面存放方法的实现imp,根据方法编号sel生成key
mask:扩容因子,同时和key共同计算得出寻找bucket_t的哈希索引
_occupied:是当前占用的容量

x/4gx:按16进制打印4个8字节地址

static void cache_fill_nolock(Class cls, SEL sel, IMP imp, id receiver)
{
    cacheUpdateLock.assertLocked(); ①

    if (!cls->isInitialized()) return; ②
    
    if (cache_getImp(cls, sel)) return; ③

    cache_t *cache = getCache(cls); ④
    cache_key_t key = getKey(sel); ⑤

    mask_t newOccupied = cache->occupied() + 1; ⑥
    mask_t capacity = cache->capacity(); ⑦
    if (cache->isConstantEmptyCache()) { ⑧
        cache->reallocate(capacity, capacity ?: INIT_CACHE_SIZE); ⑨
    } 
    else if (newOccupied <= capacity / 4 * 3) { ⑩
    
    }
    else {
        cache->expand(); ⑪
    }
    bucket_t *bucket = cache->find(key, receiver); ⑫
    if (bucket->key() == 0) cache->incrementOccupied(); ⑬
    bucket->set(key, imp); ⑭
}

缓存锁
判断类是否被初始化,如果未初始化,直接返回
判断sel是否被cls缓存,如果已经被缓存就没必要再走下面的流程,直接返回
通过cls获取cache_t内存地址
通过sel强制生成key
获取cache中当前占有量occupied + 1的值,给下面进行容量判断
取出cache中的容量capacity
⑧ 判断当前占有量是否为0并且桶子的容量是否为空的
⑨占有量为0并且桶子容量为空时,进行reallocate重新分配Buckets和Mask
⑩新的占有量小于等于总容量的3/4时,无另外操作
⑪新的占有量大于总容量的3/4时,进行expand扩容
⑫ 通过key当作哈希下标寻找对应bucket
⑬ 如果key等于0,说明没找到,需要缓存,则cache中的当前占有量 occupied + 1
⑭ 把key和imp装进桶子bucket

上一篇 下一篇

猜你喜欢

热点阅读