PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/opcache - zend_accelerator_hash.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 105 0.0 %
Date: 2014-04-16 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend OPcache                                                         |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Stanislav Malyshev <stas@zend.com>                          |
      18             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : #include "ZendAccelerator.h"
      23             : #include "zend_accelerator_hash.h"
      24             : #include "zend_hash.h"
      25             : #include "zend_shared_alloc.h"
      26             : 
      27             : /* Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
      28             : static uint prime_numbers[] =
      29             :         {5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 };
      30             : static uint num_prime_numbers = sizeof(prime_numbers) / sizeof(uint);
      31             : 
      32           0 : void zend_accel_hash_clean(zend_accel_hash *accel_hash)
      33             : {
      34           0 :         accel_hash->num_entries = 0;
      35           0 :         accel_hash->num_direct_entries = 0;
      36           0 :         memset(accel_hash->hash_table, 0, sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
      37           0 : }
      38             : 
      39           0 : void zend_accel_hash_init(zend_accel_hash *accel_hash, zend_uint hash_size)
      40             : {
      41             :         uint i;
      42             : 
      43           0 :         for (i=0; i<num_prime_numbers; i++) {
      44           0 :                 if (hash_size <= prime_numbers[i]) {
      45           0 :                         hash_size = prime_numbers[i];
      46           0 :                         break;
      47             :                 }
      48             :         }
      49             : 
      50           0 :         accel_hash->num_entries = 0;
      51           0 :         accel_hash->num_direct_entries = 0;
      52           0 :         accel_hash->max_num_entries = hash_size;
      53             : 
      54             :         /* set up hash pointers table */
      55           0 :         accel_hash->hash_table = zend_shared_alloc(sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
      56           0 :         if (!accel_hash->hash_table) {
      57           0 :                 zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
      58           0 :                 return;
      59             :         }
      60             : 
      61             :         /* set up hash values table */
      62           0 :         accel_hash->hash_entries = zend_shared_alloc(sizeof(zend_accel_hash_entry)*accel_hash->max_num_entries);
      63           0 :         if (!accel_hash->hash_entries) {
      64           0 :                 zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
      65           0 :                 return;
      66             :         }
      67           0 :         memset(accel_hash->hash_table, 0, sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
      68             : }
      69             : 
      70             : /* Returns NULL if hash is full
      71             :  * Returns pointer the actual hash entry on success
      72             :  * key needs to be already allocated as it is not copied
      73             :  */
      74           0 : zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, char *key, zend_uint key_length, zend_bool indirect, void *data)
      75             : {
      76             :         zend_ulong hash_value;
      77             :         zend_ulong index;
      78             :         zend_accel_hash_entry *entry;
      79           0 :         zend_accel_hash_entry *indirect_bucket = NULL;
      80             : 
      81           0 :         if (indirect) {
      82           0 :                 indirect_bucket = (zend_accel_hash_entry*)data;
      83           0 :                 while (indirect_bucket->indirect) {
      84           0 :                         indirect_bucket = (zend_accel_hash_entry*)indirect_bucket->data;
      85             :                 }
      86             :         }
      87             : 
      88           0 :         hash_value = zend_inline_hash_func(key, key_length);
      89           0 :         index = hash_value % accel_hash->max_num_entries;
      90             : 
      91             :         /* try to see if the element already exists in the hash */
      92           0 :         entry = accel_hash->hash_table[index];
      93           0 :         while (entry) {
      94           0 :                 if (entry->hash_value == hash_value
      95           0 :                         && entry->key_length == key_length
      96           0 :                         && !memcmp(entry->key, key, key_length)) {
      97             : 
      98           0 :                         if (entry->indirect) {
      99           0 :                                 if (indirect_bucket) {
     100           0 :                                         entry->data = indirect_bucket;
     101             :                                 } else {
     102           0 :                                         ((zend_accel_hash_entry*)entry->data)->data = data;
     103             :                                 }
     104             :                         } else {
     105           0 :                                 if (indirect_bucket) {
     106           0 :                                         accel_hash->num_direct_entries--;
     107           0 :                                         entry->data = indirect_bucket;
     108           0 :                                         entry->indirect = 1;
     109             :                                 } else {
     110           0 :                                         entry->data = data;
     111             :                                 }
     112             :                         }
     113           0 :                         return entry;
     114             :                 }
     115           0 :                 entry = entry->next;
     116             :         }
     117             : 
     118             :         /* Does not exist, add a new entry */
     119           0 :         if (accel_hash->num_entries == accel_hash->max_num_entries) {
     120           0 :                 return NULL;
     121             :         }
     122             : 
     123           0 :         entry = &accel_hash->hash_entries[accel_hash->num_entries++];
     124           0 :         if (indirect) {
     125           0 :                 entry->data = indirect_bucket;
     126           0 :                 entry->indirect = 1;
     127             :         } else {
     128           0 :                 accel_hash->num_direct_entries++;
     129           0 :                 entry->data = data;
     130           0 :                 entry->indirect = 0;
     131             :         }
     132           0 :         entry->hash_value = hash_value;
     133           0 :         entry->key = key;
     134           0 :         entry->key_length = key_length;
     135           0 :         entry->next = accel_hash->hash_table[index];
     136           0 :         accel_hash->hash_table[index] = entry;
     137           0 :         return entry;
     138             : }
     139             : 
     140             : /* Returns the data associated with key on success
     141             :  * Returns NULL if data doesn't exist
     142             :  */
     143           0 : void* zend_accel_hash_find(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
     144             : {
     145             :         zend_ulong hash_value;
     146             :         zend_ulong index;
     147             :         zend_accel_hash_entry *entry;
     148             : 
     149           0 :         hash_value = zend_inline_hash_func(key, key_length);
     150           0 :         index = hash_value % accel_hash->max_num_entries;
     151             : 
     152           0 :         entry = accel_hash->hash_table[index];
     153           0 :         while (entry) {
     154           0 :                 if (entry->hash_value == hash_value
     155           0 :                         && entry->key_length == key_length
     156           0 :                         && !memcmp(entry->key, key, key_length)) {
     157           0 :                         if (entry->indirect) {
     158           0 :                                 return ((zend_accel_hash_entry *) entry->data)->data;
     159             :                         } else {
     160           0 :                                 return entry->data;
     161             :                         }
     162             :                 }
     163           0 :                 entry = entry->next;
     164             :         }
     165           0 :         return NULL;
     166             : }
     167             : 
     168             : /* Returns the hash entry associated with key on success
     169             :  * Returns NULL if it doesn't exist
     170             :  */
     171           0 : zend_accel_hash_entry* zend_accel_hash_find_entry(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
     172             : {
     173             :         zend_ulong hash_value;
     174             :         zend_ulong index;
     175             :         zend_accel_hash_entry *entry;
     176             : 
     177           0 :         hash_value = zend_inline_hash_func(key, key_length);
     178           0 :         index = hash_value % accel_hash->max_num_entries;
     179             : 
     180           0 :         entry = accel_hash->hash_table[index];
     181           0 :         while (entry) {
     182           0 :                 if (entry->hash_value == hash_value
     183           0 :                         && entry->key_length == key_length
     184           0 :                         && !memcmp(entry->key, key, key_length)) {
     185           0 :                         if (entry->indirect) {
     186           0 :                                 return (zend_accel_hash_entry *) entry->data;
     187             :                         } else {
     188           0 :                                 return entry;
     189             :                         }
     190             :                 }
     191           0 :                 entry = entry->next;
     192             :         }
     193           0 :         return NULL;
     194             : }
     195             : 
     196           0 : int zend_accel_hash_unlink(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
     197             : {
     198             :         zend_ulong hash_value;
     199             :     zend_ulong index;
     200           0 :     zend_accel_hash_entry *entry, *last_entry=NULL;
     201             : 
     202           0 :         hash_value = zend_inline_hash_func(key, key_length);
     203           0 :         index = hash_value % accel_hash->max_num_entries;
     204             : 
     205           0 :         entry = accel_hash->hash_table[index];
     206           0 :         while (entry) {
     207           0 :                 if (entry->hash_value == hash_value
     208           0 :                         && entry->key_length == key_length
     209           0 :                         && !memcmp(entry->key, key, key_length)) {
     210           0 :                         if (!entry->indirect) {
     211           0 :                                 accel_hash->num_direct_entries--;
     212             :                         }
     213           0 :                         if (last_entry) {
     214           0 :                                 last_entry->next = entry->next;
     215             :                         } else {
     216           0 :                                 accel_hash->hash_table[index] = entry->next;
     217             :                         }
     218           0 :                         return SUCCESS;
     219             :                 }
     220           0 :                 last_entry = entry;
     221           0 :                 entry = entry->next;
     222             :         }
     223           0 :         return FAILURE;
     224             : }

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:52 +0000 (6 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.