/* HashTable容量满了的时候重新分配大小 */ static int zend_hash_do_resize(HashTable *ht) { Bucket **t; #ifdef ZEND_SIGNALS TSRMLS_FETCH(); #endif IS_CONSISTENT(ht); if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ /* 重新分配大小 */ t = (Bucket **)perealloc_recoverable( ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); if (t) { HANDLE_BLOCK_INTERRUPTIONS(); ht->arBuckets = t; /* 设置nTableSize */ ht->nTableSize = (ht->nTableSize << 1); /* nTableMask随着nTableSize改变,永远是nTableSize-1 */ ht->nTableMask = ht->nTableSize - 1; /* 修改HashTable大小之后需要重新哈希 */ zend_hash_rehash(ht); HANDLE_UNBLOCK_INTERRUPTIONS(); return SUCCESS; } return FAILURE; } return SUCCESS; }
static int zend_hash_do_resize(HashTable *ht) { Bucket **t; IS_CONSISTENT(ht); if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); if (t) { HANDLE_BLOCK_INTERRUPTIONS(); ht->arBuckets = t; ht->nTableSize = (ht->nTableSize << 1); ht->nTableMask = ht->nTableSize - 1; zend_hash_rehash(ht); HANDLE_UNBLOCK_INTERRUPTIONS(); #if DEBUG_RESIZE asm("int3"); printf("#%d resized %d\n", ++resizes, ht->nTableSize); #endif return SUCCESS; } return FAILURE; } return SUCCESS; }
static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC) { #ifndef ZTS ulong h; uint nIndex; Bucket *p; if (IS_INTERNED(arKey)) { return arKey; } h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & CG(interned_strings).nTableMask; p = CG(interned_strings).arBuckets[nIndex]; while (p != NULL) { if ((p->h == h) && (p->nKeyLength == nKeyLength)) { if (!memcmp(p->arKey, arKey, nKeyLength)) { if (free_src) { efree((void *)arKey); } return p->arKey; } } p = p->pNext; } if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >= CG(interned_strings_end)) { /* no memory */ return arKey; } p = (Bucket *) CG(interned_strings_top); CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength); #if ZEND_DEBUG_INTERNED_STRINGS mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE); #endif p->arKey = (char*)(p+1); memcpy((char*)p->arKey, arKey, nKeyLength); if (free_src) { efree((void *)arKey); } p->nKeyLength = nKeyLength; p->h = h; p->pData = &p->pDataPtr; p->pDataPtr = p; p->pNext = CG(interned_strings).arBuckets[nIndex]; p->pLast = NULL; if (p->pNext) { p->pNext->pLast = p; } HANDLE_BLOCK_INTERRUPTIONS(); p->pListLast = CG(interned_strings).pListTail; CG(interned_strings).pListTail = p; p->pListNext = NULL; if (p->pListLast != NULL) { p->pListLast->pListNext = p; } if (!CG(interned_strings).pListHead) { CG(interned_strings).pListHead = p; } CG(interned_strings).arBuckets[nIndex] = p; HANDLE_UNBLOCK_INTERRUPTIONS(); CG(interned_strings).nNumOfElements++; if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) { if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */ Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent); if (t) { HANDLE_BLOCK_INTERRUPTIONS(); CG(interned_strings).arBuckets = t; CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1); CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1; zend_hash_rehash(&CG(interned_strings)); HANDLE_UNBLOCK_INTERRUPTIONS(); } } } #if ZEND_DEBUG_INTERNED_STRINGS mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ); #endif return p->arKey; #else return arKey; #endif }