com php-src: API cleanup: Zend/zend_hash.c Zend/zend_ha sh.h

[email protected] (Rasmus Lerdorf)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    fb2d079645829b12ed4e55a461034df6400bc430
Author:    Dmitry Stogov <[email protected]>         Fri, 30 Jan 2015 18:08:05 +0300
Parents:   08302c0d6d1cab279b9f2129df03a057baddf2ff
Branches:  dstogov-foreach

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=fb2d079645829b12ed4e55a461034df6400bc430

Log:
API cleanup

Changed paths:
  M  Zend/zend_hash.c
  M  Zend/zend_hash.h


Diff:
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 8a2f6a2..815444b 100644
--- a/Zend/zend_hash.c
+++ b/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,68 +289,41 @@ 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 && iter->pos == from) {
-			iter->pos = to;
+		if (iter->ht == ht) {
+			if (iter->pos >= start && iter->pos < res) {
+				res = iter->pos;
+			}
 		}
 		iter++;
 	}
+	return res;
 }
 
-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)
+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);
+	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++;
+	while (iter != end) {
+		if (iter->ht == ht && iter->pos == from) {
+			iter->pos = to;
 		}
+		iter++;
 	}
 }
 
@@ -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;
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index d244995..982c63b 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -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()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.