php-5.6.26源代码 - hash存储结构 - 添加

 

添加
    if (zend_hash_add(&module_registry, lcname, name_len+1, (void *)module, sizeof(zend_module_entry), (void**)&module_ptr){
        // zend_hash_add 定义在文件“php-5.6.26\Zend\zend_hash.h”
        #define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
            _zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
        {
            // _zend_hash_add_or_update 实现在文件“php-5.6.26\Zend\zend_hash.c”
            ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
            {
                // arKey==键名,nKeyLength键名的长度,pData==键值,nDataSize==键值的长度,pDest==被存入的数据
                
                ulong h;
                uint nIndex;
                Bucket *p;
            #ifdef ZEND_SIGNALS
                TSRMLS_FETCH();
            #endif
            
                IS_CONSISTENT(ht);
            
                ZEND_ASSERT(nKeyLength != 0);
            
                CHECK_INIT(ht);
            
                h = zend_inline_hash_func(arKey, nKeyLength); 
                nIndex = h & ht->nTableMask;
            
                p = ht->arBuckets[nIndex];
                while (p != NULL) {
                    if (p->arKey == arKey ||
                        ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { // 更新操作
                            if (flag & HASH_ADD) {
                                return FAILURE;
                            }
                            ZEND_ASSERT(p->pData != pData);
                            HANDLE_BLOCK_INTERRUPTIONS();
                            if (ht->pDestructor) {
                                ht->pDestructor(p->pData); // 销毁数据
                            }
                            UPDATE_DATA(ht, p, pData, nDataSize);
                            if (pDest) {
                                *pDest = p->pData;
                            }
                            HANDLE_UNBLOCK_INTERRUPTIONS();
                            return SUCCESS;
                    }
                    p = p->pNext; // 走到hash链的末尾
                }
                
                if (IS_INTERNED(arKey)) {
                    p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); // 创建一个Bucket
                    p->arKey = arKey;
                } else {
                    p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent);
                    p->arKey = (const char*)(p + 1);
                    memcpy((char*)p->arKey, arKey, nKeyLength);
                }
                p->nKeyLength = nKeyLength; // 设置键名长度
                INIT_DATA(ht, p, pData, nDataSize); // 设置数据 
                p->h = h; // 设置对HashTable的指针
                CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]); // p->pNext = ht->arBuckets[nIndex]; ht->arBuckets[nIndex]->pLast = p;
                if (pDest) {
                    *pDest = p->pData;
                }
            
                HANDLE_BLOCK_INTERRUPTIONS();
                CONNECT_TO_GLOBAL_DLLIST(p, ht);
                ht->arBuckets[nIndex] = p;
                HANDLE_UNBLOCK_INTERRUPTIONS();
            
                ht->nNumOfElements++;
                ZEND_HASH_IF_FULL_DO_RESIZE(ht);        /* If the Hash table is full, resize it */
                return SUCCESS;
            }
                        
        }
        
    }==FAILURE) { // 添加模块信息到“模块注册表module_registry”
        ...
    }

 

posted on 2018-03-23 18:10  周~~  阅读(231)  评论(0)    收藏  举报

导航