mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
API cleanup
This commit is contained in:
parent
08302c0d6d
commit
fb2d079645
2 changed files with 81 additions and 74 deletions
145
Zend/zend_hash.c
145
Zend/zend_hash.c
|
@ -269,7 +269,7 @@ ZEND_API void zend_hash_iterator_del(uint32_t idx)
|
|||
}
|
||||
}
|
||||
|
||||
static zend_never_inline void _iterators_del(HashTable *ht)
|
||||
static zend_never_inline void _zend_hash_iterators_remove(HashTable *ht)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
|
@ -289,14 +289,32 @@ static zend_never_inline void _iterators_del(HashTable *ht)
|
|||
EG(ht_iterators_used) = idx;
|
||||
}
|
||||
|
||||
static zend_always_inline void iterators_del(HashTable *ht)
|
||||
static zend_always_inline void zend_hash_iterators_remove(HashTable *ht)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_iterators_del(ht);
|
||||
_zend_hash_iterators_remove(ht);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_never_inline void _iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
HashPosition res = INVALID_IDX;
|
||||
uint32_t idx;
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->ht == ht) {
|
||||
if (iter->pos >= start && iter->pos < res) {
|
||||
res = iter->pos;
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
|
@ -309,51 +327,6 @@ static zend_never_inline void _iterators_update(HashTable *ht, HashPosition from
|
|||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_iterators_update(ht, from, to);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_never_inline void _iterators_update_to_next(HashTable *ht, HashPosition from)
|
||||
{
|
||||
uint32_t to = from;
|
||||
|
||||
while (1) {
|
||||
to++;
|
||||
if (to >= ht->nNumUsed) {
|
||||
to = INVALID_IDX;
|
||||
break;
|
||||
} else if (Z_TYPE(ht->arData[to].val) != IS_UNDEF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_iterators_update(ht, from, to);
|
||||
}
|
||||
|
||||
static zend_always_inline void iterators_update_to_next(HashTable *ht, HashPosition from)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_iterators_update_to_next(ht, from);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->ht == ht && iter->pos == from) {
|
||||
iter->pos = to;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong h;
|
||||
|
@ -466,7 +439,7 @@ add_to_hash:
|
|||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = idx;
|
||||
}
|
||||
iterators_update(ht, INVALID_IDX, idx);
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, idx);
|
||||
p = ht->arData + idx;
|
||||
p->h = h = zend_string_hash_val(key);
|
||||
p->key = key;
|
||||
|
@ -634,7 +607,7 @@ add_to_packed:
|
|||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = h;
|
||||
}
|
||||
iterators_update(ht, INVALID_IDX, h);
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, h);
|
||||
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
|
||||
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
|
||||
}
|
||||
|
@ -677,7 +650,7 @@ add_to_hash:
|
|||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = idx;
|
||||
}
|
||||
iterators_update(ht, INVALID_IDX, idx);
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, idx);
|
||||
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
|
||||
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
|
||||
}
|
||||
|
@ -758,20 +731,42 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
|
|||
}
|
||||
|
||||
memset(ht->arHash, INVALID_IDX, ht->nTableSize * sizeof(uint32_t));
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
if (EXPECTED(ht->u.v.nIteratorsCount == 0)) {
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
}
|
||||
}
|
||||
iterators_update(ht, i, j);
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
uint32_t iter_pos = zend_hash_iterators_lower_pos(ht, 0);
|
||||
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
}
|
||||
if (i == iter_pos) {
|
||||
zend_hash_iterators_update(ht, i, j);
|
||||
iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1);
|
||||
}
|
||||
}
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
ht->nNumUsed = j;
|
||||
return SUCCESS;
|
||||
|
@ -793,18 +788,22 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
|
|||
} while (ht->nNumUsed > 0 && (Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF));
|
||||
}
|
||||
ht->nNumOfElements--;
|
||||
iterators_update_to_next(ht, idx);
|
||||
if (ht->nInternalPointer == idx) {
|
||||
if (ht->nInternalPointer == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
uint32_t new_idx = idx;
|
||||
|
||||
while (1) {
|
||||
idx++;
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ht->nInternalPointer = INVALID_IDX;
|
||||
new_idx++;
|
||||
if (new_idx >= ht->nNumUsed) {
|
||||
new_idx = INVALID_IDX;
|
||||
break;
|
||||
} else if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
|
||||
ht->nInternalPointer = idx;
|
||||
} else if (Z_TYPE(ht->arData[new_idx].val) != IS_UNDEF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ht->nInternalPointer == idx) {
|
||||
ht->nInternalPointer = new_idx;
|
||||
}
|
||||
zend_hash_iterators_update(ht, idx, new_idx);
|
||||
}
|
||||
if (p->key) {
|
||||
zend_string_release(p->key);
|
||||
|
@ -1059,7 +1058,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
|
|||
} while (++p != end);
|
||||
}
|
||||
}
|
||||
iterators_del(ht);
|
||||
zend_hash_iterators_remove(ht);
|
||||
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
return;
|
||||
}
|
||||
|
@ -1100,7 +1099,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
|||
}
|
||||
} while (++p != end);
|
||||
}
|
||||
iterators_del(ht);
|
||||
zend_hash_iterators_remove(ht);
|
||||
SET_INCONSISTENT(HT_DESTROYED);
|
||||
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
return;
|
||||
|
|
|
@ -229,7 +229,15 @@ ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ul
|
|||
ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht);
|
||||
ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht);
|
||||
ZEND_API void zend_hash_iterator_del(uint32_t idx);
|
||||
ZEND_API void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
|
||||
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start);
|
||||
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
|
||||
|
||||
static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_zend_hash_iterators_update(ht, from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_EXTERN_C()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue