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
网友评论