diff options
| author | Dmitry Stogov <dmitry@php.net> | 2010-04-20 11:05:54 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2010-04-20 11:05:54 +0000 |
| commit | dd5c478be61a0ef94b54837cfa875c964356e14f (patch) | |
| tree | afdce3c072b3c27f7721c6f24895a147a9f825b4 /Zend/zend_hash.c | |
| parent | 94dd83722b57c4613ccf8371a3c4f50ffc274584 (diff) | |
| download | php-git-dd5c478be61a0ef94b54837cfa875c964356e14f.tar.gz | |
Added concept of interned strings. All strings constants known at compile time are allocated in a single copy and never changed.
Diffstat (limited to 'Zend/zend_hash.c')
| -rw-r--r-- | Zend/zend_hash.c | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 69b6bdc169..530afa7d34 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -20,6 +20,7 @@ /* $Id$ */ #include "zend.h" +#include "zend_globals.h" #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ (element)->pNext = (list_head); \ @@ -210,8 +211,8 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { if (flag & HASH_ADD) { return FAILURE; } @@ -232,16 +233,24 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe } HANDLE_UNBLOCK_INTERRUPTIONS(); return SUCCESS; - } } p = p->pNext; } - p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent); - if (!p) { - return FAILURE; + if (IS_INTERNED(arKey)) { + p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); + if (!p) { + return FAILURE; + } + p->arKey = (char*)arKey; + } else { + p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); + if (!p) { + return FAILURE; + } + p->arKey = (char*)(p + 1); + memcpy(p->arKey, arKey, nKeyLength); } - memcpy(p->arKey, arKey, nKeyLength); p->nKeyLength = nKeyLength; INIT_DATA(ht, p, pData, nDataSize); p->h = h; @@ -276,8 +285,8 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { if (flag & HASH_ADD) { return FAILURE; } @@ -298,17 +307,25 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui } HANDLE_UNBLOCK_INTERRUPTIONS(); return SUCCESS; - } } p = p->pNext; } - p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent); - if (!p) { - return FAILURE; + if (IS_INTERNED(arKey)) { + p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); + if (!p) { + return FAILURE; + } + p->arKey = (char*)arKey; + } else { + p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); + if (!p) { + return FAILURE; + } + p->arKey = (char*)(p + 1); + memcpy(p->arKey, arKey, nKeyLength); } - memcpy(p->arKey, arKey, nKeyLength); p->nKeyLength = nKeyLength; INIT_DATA(ht, p, pData, nDataSize); p->h = h; @@ -380,10 +397,11 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void } p = p->pNext; } - p = (Bucket *) pemalloc_rel(sizeof(Bucket) - 1, ht->persistent); + p = (Bucket *) pemalloc_rel(sizeof(Bucket), ht->persistent); if (!p) { return FAILURE; } + p->arKey = NULL; p->nKeyLength = 0; /* Numeric indices are marked by making the nKeyLength == 0 */ p->h = h; INIT_DATA(ht, p, pData, nDataSize); @@ -885,11 +903,10 @@ ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLen p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { *pData = p->pData; return SUCCESS; - } } p = p->pNext; } @@ -912,11 +929,10 @@ ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint n p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { *pData = p->pData; return SUCCESS; - } } p = p->pNext; } @@ -937,10 +953,9 @@ ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyL p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { return 1; - } } p = p->pNext; } @@ -963,10 +978,9 @@ ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint p = ht->arBuckets[nIndex]; while (p != NULL) { - if ((p->h == h) && (p->nKeyLength == nKeyLength)) { - if (!memcmp(p->arKey, arKey, nKeyLength)) { + if (p->arKey == arKey || + ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { return 1; - } } p = p->pNext; } @@ -1290,7 +1304,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const } if (p->nKeyLength != str_length) { - Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) - 1 + str_length, ht->persistent); + Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) + str_length, ht->persistent); q->nKeyLength = str_length; if (p->pData == &p->pDataPtr) { @@ -1324,6 +1338,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const if (key_type == HASH_KEY_IS_LONG) { p->h = num_index; } else { + p->arKey = (char*)(p+1); memcpy(p->arKey, str_index, str_length); p->h = zend_inline_hash_func(str_index, str_length); } |
