數據類型 - 字符串

字符串的數據結構比較簡單,牽扯到的東西比較少,我簡單展示下源碼中的數據結構的定義。

zend_string數據結構

typedef struct _zend_string      zend_string;


struct _zend_string {
   zend_refcounted_h gc;
   zend_ulong        h;                /* hash value */
   size_t            len;
   char              val[1];
};

這個結構有4個成員。

  • gc : zend_refcounted_h 結構體,主要用來變量的引用計數,用於內存管理,在後續的內存管理將會使用到
  • h: 字符串的Hash Code(使用time 33 Hash算法得到的Hash值)
  • len: 字符串長度
  • val: 一個可變數組,用來存儲字符串內容

快速充電樁~:

  • 這裏先劃重點,敲黑板啦!咱們後續的數組等複雜類型的講解,都是比較依賴HashTable來實現,使用HashTable比較重要的就是選取一個Hash函數,儘量減少Hash衝突,PHP選取實現方式Time 33算法。
  • 關於Time 33算法: 目前是對於字符串Hash最好的哈希算法之一了,原因在於該算法的速度非常快,而且分類非常好(衝突小,分佈均勻).
  • 由於我看的PHP源碼的版本和鳥哥不一樣,Time 33算法實現的位置也有點區別,對於有興趣的同學,我貼出對應的源碼位置

    //file : zend_string.h
    
    
    static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
    {
       register zend_ulong hash = Z_UL(5381);
    
       /* variant with the hash unrolled eight times */
       for (; len >= 8; len -= 8) {
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
          hash = ((hash << 5) + hash) + *str++;
       }
       switch (len) {
          case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
          case 1: hash = ((hash << 5) + hash) + *str++; break;
          case 0: break;
    	EMPTY_SWITCH_DEFAULT_CASE()
       }
        /* Hash value can't be zero, so we always set the high bit */
    	#if SIZEOF_ZEND_LONG == 8
       	return hash | Z_UL(0x8000000000000000);
    	#elif SIZEOF_ZEND_LONG == 4
        return hash | Z_UL(0x80000000);
    	#else
    	# error "Unknown SIZEOF_ZEND_LONG"
    	#endif
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章