$arr = array( $val1, $val2, ..., $valn );
This array can be looped through in two ways. foreach($arr as $k => $v ) {...}
and $n = count( $arr ); for($k = 0; $k < $n; $k++ ) {...}
C
and C++
, where the array index is a simple pointer offset.Bucket
structure describes a “pointer” to the current position of the array. typedef struct bucket { ulong h; // // ( ) uint nKeyLength; // ( ) void *pData; // // [ : (zval **)pos->pData ] void *pDataPtr; struct bucket *pListNext; // struct bucket *pListLast; // struct bucket *pNext; // arBuckets struct bucket *pLast; // arBuckets const char *arKey; // , } Bucket; typedef Bucket* HashPosition;
HashTable
structure is the array itself in the internal representation: typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; // ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; // Bucket *pListTail; // Bucket **arBuckets; // , . // // dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection; } HashTable;
// . int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos) { HashPosition *current = pos ? pos : &ht->pInternalPointer; if (*current) { *current = (*current)->pListNext; return SUCCESS; } else return FAILURE; } // . // php , Zend // . int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos) { HashPosition *current = pos ? pos : &ht->pInternalPointer; if (*current) { *current = (*current)->pListLast; return SUCCESS; } else return FAILURE; }
int zend_hash_index_find(const HashTable *ht, ulong h, void **pData) { uint nIndex; Bucket *p; nIndex = h & ht->nTableMask; p = ht->arBuckets[nIndex]; while (p != NULL) { if ((p->h == h) && (p->nKeyLength == 0)) { *pData = p->pData; return SUCCESS; } p = p->pNext; } return FAILURE; }
arBuckets
array is arBuckets
( C
array from HashPosition
- pointers to Bucket
).arBuckets
before searching for the desired value. foreach($arr as $i => $v ){...}
Quite quickly enumerates all the elements of the array, getting them one by one. The complexity of this operation is O (n). for($i = 0; $i < $n; $i++ ){...}
At each iteration, it searches for an index in the internal hash table.Source: https://habr.com/ru/post/216103/
All Articles