iOS开发之runtime(24):maptable之hash算法

logo

本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看 runtime 的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime

背景

上一篇文章笔者带大家浏览了一下文件 maptable.h ,了解了文件的大概构成,但每个字段的含义可能读者还不是特别清楚,笔者将在这篇文章中和大家一起分析源码。

NXMapTablePrototype

其定义如下:

typedef struct _NXMapTablePrototype {
    unsigned    (*hash)(NXMapTable *, const void *key);
    int     (*isEqual)(NXMapTable *, const void *key1, const void *key2);
    void    (*free)(NXMapTable *, void *key, void *value);
    int     style; /* reserved for future expansion; currently 0 */
} NXMapTablePrototype

Prototype 英文意思为:“原型”。看结构体中各个属性的声明,大概能了解前三个属性为函数,第一个函数应该定义了 table 获取 key 的方式,第二个函数定义两个 table 是否相同;第三个函数是定义table的释放。

结构体中指向函数的指针
C 语言中的 struct 是最接近类的概念,但是在 C 语言的 struct 中只有成员,不能有函数,但是可以有指向函数的指针,这也就方便了我们使用函数了。

后面我们有看到几个 prototype 的定义:

NXMapTablePrototype NXPtrValueMapPrototype;
NXMapTablePrototype NXStrValueMapPrototype;
NXMapTablePrototype NXObjectMapPrototype ;

其实现分别为:

const NXMapTablePrototype NXPtrValueMapPrototype = {
    _mapPtrHash, _mapPtrIsEqual, _mapNoFree, 0
};

const NXMapTablePrototype NXStrValueMapPrototype = {
    _mapStrHash, _mapStrIsEqual, _mapNoFree, 0
};

这两个,而 NXObjectMapPrototype 没有对应的实现了。

OBJC_EXPORT const NXMapTablePrototype NXObjectMapPrototype  OBJC2_UNAVAILABLE;

这从 OBJC2_UNAVAILABLE 这个宏可以看出。因此我们只需要分析 NXPtrValueMapPrototype 和 NXStrValueMapPrototype 即可。
而根据我们上面的代码,可以找到对应的函数:

static unsigned _mapPtrHash(NXMapTable *table, const void *key) {
#ifdef __LP64__
    return (unsigned)(((uintptr_t)key) >> 3);
#else
    return ((uintptr_t)key) >> 2;
#endif
}

static unsigned _mapStrHash(NXMapTable *table, const void *key) {
    unsigned        hash = 0;
    unsigned char   *s = (unsigned char *)key;
    /* unsigned to avoid a sign-extend */
    /* unroll the loop */
    if (s) for (; ; ) { 
    if (*s == '\0') break;
    hash ^= *s++;
    if (*s == '\0') break;
    hash ^= *s++ << 8;
    if (*s == '\0') break;
    hash ^= *s++ << 16;
    if (*s == '\0') break;
    hash ^= *s++ << 24;
    }
    return xorHash(hash);
}
    
static int _mapPtrIsEqual(NXMapTable *table, const void *key1, const void *key2) {
    return key1 == key2;
}

static int _mapStrIsEqual(NXMapTable *table, const void *key1, const void *key2) {
    if (key1 == key2) return YES;
    if (! key1) return ! strlen ((char *) key2);
    if (! key2) return ! strlen ((char *) key1);
    if (((char *) key1)[0] != ((char *) key2)[0]) return NO;
    return (strcmp((char *) key1, (char *) key2)) ? NO : YES;
}
    
static void _mapNoFree(NXMapTable *table, void *key, void *value) {}

可以看出 NXMapTablePrototype 的作用应该就是指定 maptable 的 hash 算法。那么我们今天就研究一下 hash 算法。先抛出几个问题:

  • 什么是 hash

分析

本文详细版请见:
https://xiaozhuanlan.com/topic/8239514706

广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

壁纸宝贝

你可能感兴趣的:(iOS开发之runtime(24):maptable之hash算法)