Changeset 385

Show
Ignore:
Timestamp:
02/01/10 16:59:16 (6 months ago)
Author:
bart
Message:

* A retab on eaccelerator.c
* Remove caching based on inodes
* Reimplement eaccelerator_stat to speed it up: the new ea_stat is

almost twice as fast as the old version with inodes. The tests were
done on a file that includes 10k empty files.

* Increment version to 1.0-dev

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ChangeLog

    r381 r385  
     12010-02-01  Bart Vanbrabant <bart at vanbrabant.eu> 
     2 
     3                * A retab on eaccelerator.c 
     4                * Remove caching based on inodes 
     5                * Reimplement eaccelerator_stat to speed it up: the new ea_stat is 
     6                almost twice as fast as the old version with inodes. The tests were 
     7                done on a file that includes 10k empty files. 
     8                * Increment version to 1.0-dev 
     9 
    1102010-01-22      Bart Vanbrabant <bart at vanbrabant.eu> 
    211 
  • eaccelerator/trunk/config.m4

    r362 r385  
    4747]) 
    4848 
    49 AC_ARG_WITH(eaccelerator-use-inode, 
    50 [  --without-eaccelerator-use-inode         Don't use inodes to determine hash keys (never used on win32)],[ 
    51   eaccelerator_inode=$withval 
    52 ],[ 
    53   eaccelerator_inode=yes 
    54 ]) 
    55  
    5649AC_ARG_WITH(eaccelerator-debug, 
    5750[  --with-eaccelerator-debug                Enable the debug code so eaccelerator logs verbose.],[ 
     
    9588  if test "$eaccelerator_disassembler" = "yes"; then 
    9689    AC_DEFINE(WITH_EACCELERATOR_DISASSEMBLER, 1, [Define if you like to explore Zend bytecode]) 
    97   fi 
    98   if test "$eaccelerator_inode" = "yes"; then 
    99     AC_DEFINE(WITH_EACCELERATOR_USE_INODE, 1, [Undef if you don't wan't to use inodes to determine hash keys]) 
    10090  fi 
    10191  if test "$eaccelerator_debug" = "yes"; then 
  • eaccelerator/trunk/eaccelerator.c

    r375 r385  
    124124  ea_cache_entry *p, *q; 
    125125 
    126 #ifdef EACCELERATOR_USE_INODE 
    127   hv = buf->st_dev + buf->st_ino; 
    128 #else 
    129126  hv = zend_get_hash_value((char *)key, strlen(key)); 
    130 #endif 
    131127  slot = hv & EA_HASH_MAX; 
    132128 
     
    135131  p = ea_mm_instance->hash[slot]; 
    136132  while (p != NULL) { 
    137 #ifdef EACCELERATOR_USE_INODE 
    138     if (p->st_dev == buf->st_dev && p->st_ino == buf->st_ino) { 
    139       struct stat buf2; 
    140       if ((EAG(check_mtime_enabled) && ea_mm_instance->check_mtime_enabled && 
    141           (buf->st_mtime != p->mtime || buf->st_size != p->filesize)) || 
    142           (strcmp(p->realfilename, key) != 0 && 
    143            (stat(p->realfilename,&buf2) != 0 || 
    144            buf2.st_dev != buf->st_dev || 
    145            buf2.st_ino != buf->st_ino))) { 
    146 #else 
    147133    if ((p->hv == hv) && (strcmp(p->realfilename, key) == 0)) { 
    148134      if (EAG(check_mtime_enabled) && ea_mm_instance->check_mtime_enabled && 
    149135          (buf->st_mtime != p->mtime || buf->st_size != p->filesize)) { 
    150 #endif 
    151136        /* key is invalid. Remove it. */ 
    152137        *nreloads = p->nreloads+1; 
     
    191176  ea_cache_entry *p,*q; 
    192177  unsigned int slot; 
    193 #ifdef EACCELERATOR_USE_INODE 
    194   slot = (x->st_dev + x->st_ino) & EA_HASH_MAX; 
    195 #else 
    196178  x->hv = zend_get_hash_value(x->realfilename, strlen(x->realfilename)); 
    197179  slot = x->hv & EA_HASH_MAX; 
    198 #endif 
    199180 
    200181  EACCELERATOR_LOCK_RW(); 
     
    205186  p = x->next; 
    206187  while (p != NULL) { 
    207 #ifdef EACCELERATOR_USE_INODE 
    208     if ((p->st_dev == x->st_dev) && (p->st_ino == x->st_ino)) { 
    209 #else 
    210188    if ((p->hv == x->hv) && 
    211189        (strcmp(p->realfilename, x->realfilename) == 0)) { 
    212 #endif 
    213190      q->next = p->next; 
    214191      ea_mm_instance->hash_cnt--; 
     
    404381static char num2hex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; 
    405382 
    406 #ifdef EACCELERATOR_USE_INODE 
    407 static int eaccelerator_inode_key(char* s, dev_t dev, ino_t ino TSRMLS_DC) { 
    408   int n, i; 
    409   snprintf(s, MAXPATHLEN-1, "%s/", EAG(cache_dir)); 
    410   n = strlen(s); 
    411   for (i = 1; i <= EACCELERATOR_HASH_LEVEL && n < MAXPATHLEN - 1; i++) { 
    412     s[n++] = num2hex[(ino >> (i << 2)) & 0xf]; // (ino / (i * 4)) 
    413     s[n++] = '/'; 
    414   } 
    415   s[n] = 0; 
    416   strlcat(s, "eaccelerator-", MAXPATHLEN-1); 
    417   n += sizeof("eaccelerator-") - 1; 
    418   while (dev > 0) { 
    419     if (n >= MAXPATHLEN) return 0; 
    420     s[n++] = (dev % 10) +'0'; 
    421     dev /= 10; 
    422   } 
    423   if (n >= MAXPATHLEN) return 0; 
    424   s[n++] = '.'; 
    425   while (ino > 0) { 
    426     if (n >= MAXPATHLEN) return 0; 
    427     s[n++] = (ino % 10) +'0'; 
    428     ino /= 10; 
    429   } 
    430   if (n >= MAXPATHLEN) return 0; 
    431   s[n++] = '\000'; 
    432   return 1; 
    433 } 
    434 #endif 
    435  
    436383/* Function to create a hash key when filenames are used */ 
    437384int eaccelerator_md5(char* s, const char* prefix, const char* key TSRMLS_DC) { 
     
    470417      if (((*p)->ttl != 0 && (*p)->ttl < t && (*p)->use_cnt <= 0) || 
    471418          stat((*p)->realfilename,&buf) != 0 || 
    472 #ifdef EACCELERATOR_USE_INODE 
    473           (*p)->st_dev != buf.st_dev || 
    474           (*p)->st_ino != buf.st_ino || 
    475 #endif 
    476419          (*p)->mtime != buf.st_mtime || 
    477420          (*p)->filesize != buf.st_size) { 
     
    644587  char s[MAXPATHLEN]; 
    645588  ea_file_header hdr; 
    646   ea_cache_entry *p
     589  ea_cache_entry *p = NULL
    647590  int use_shm = 1; 
    648591 
    649 #ifdef EACCELERATOR_USE_INODE 
    650   struct stat buf2; 
    651  
    652   if (!eaccelerator_inode_key(s, buf->st_dev, buf->st_ino TSRMLS_CC)) { 
    653     return NULL; 
    654   } 
    655 #else 
    656592  if (!eaccelerator_md5(s, "/eaccelerator-", key TSRMLS_CC)) { 
    657593    return NULL; 
    658594  } 
    659 #endif 
    660595 
    661596  if ((f = open(s, O_RDONLY | O_BINARY)) > 0) { 
     
    697632    EACCELERATOR_FLOCK(f, LOCK_UN); 
    698633    close(f); 
    699 #ifdef EACCELERATOR_USE_INODE 
    700     if (p->st_dev != buf->st_dev || p->st_ino != buf->st_ino) { 
    701 #else 
    702634    if (strcmp(key,p->realfilename) != 0) { 
    703 #endif 
    704635      if (use_shm) eaccelerator_free(p); else efree(p); 
    705636      return NULL; 
     
    707638    if ((EAG(check_mtime_enabled) && ea_mm_instance->check_mtime_enabled && 
    708639        (buf->st_mtime != p->mtime || buf->st_size != p->filesize)) 
    709 #ifdef EACCELERATOR_USE_INODE 
    710         || 
    711         (strcmp(p->realfilename, key) != 0 && 
    712          (stat(p->realfilename,&buf2) != 0 || 
    713          buf2.st_dev != buf->st_dev || 
    714          buf2.st_ino != buf->st_ino)) 
    715 #endif 
    716640       ) { 
    717641      /* key is invalid. Remove it. */ 
     
    750674  ea_file_header hdr; 
    751675 
    752 #ifdef EACCELERATOR_USE_INODE 
    753   if (!eaccelerator_inode_key(s, p->st_dev, p->st_ino TSRMLS_CC)) { 
    754     return 0; 
    755   } 
    756 #else 
    757676  if (!eaccelerator_md5(s, "/eaccelerator-", p->realfilename TSRMLS_CC)) { 
    758677    return 0; 
    759678  } 
    760 #endif 
    761679 
    762680  unlink(s); 
     
    824742    p->size     = size; 
    825743    p->nreloads = nreloads; 
    826 #ifdef EACCELERATOR_USE_INODE 
    827     p->st_dev   = buf->st_dev; 
    828     p->st_ino   = buf->st_ino; 
    829 #endif 
    830744    if (use_shm) { 
    831745      if (ea_shm_ttl > 0) { 
     
    894808} 
    895809 
    896  
     810/** 
     811 * Get the real filename of the file represented by the given file_handle. 
     812 * If unable to determine the realfilename this function returns 0, otherwise 
     813 * it returns 1. 
     814 * 
     815 * realfilename should be MAXPATHLEN long. 
     816 */ 
     817static int ea_get_realname(zend_file_handle *file_handle, char* realname TSRMLS_DC) { 
     818  if (file_handle->opened_path == NULL && file_handle->filename == NULL) { 
     819                return 0; 
     820        } 
     821 
     822        if (file_handle->opened_path != NULL) { 
     823                strcpy(realname, file_handle->opened_path); 
     824                return 1; 
     825        } 
     826 
     827        if (PG(include_path) == NULL ||  
     828                        file_handle->filename[0] == '.' || 
     829      IS_SLASH(file_handle->filename[0]) || 
     830      IS_ABSOLUTE_PATH(file_handle->filename, strlen(file_handle->filename))) { 
     831     
     832                return VCWD_REALPATH(file_handle->filename, realname); 
     833        } else { 
     834    int filename_len = strlen(file_handle->filename); 
     835                char* temp_name = php_resolve_path_for_zend(file_handle->filename, filename_len TSRMLS_CC); 
     836 
     837                if (temp_name == NULL) { 
     838                        return 0; 
     839                } 
     840 
     841                strcpy(realname, temp_name); 
     842                efree(temp_name); 
     843                return 1; 
     844        } 
     845 
     846        return 0; 
     847
     848 
     849/*  
     850 * Stat the file that belongs to file_handle. It puts result of the stat call 
     851 * in buf and the real filename in realname. 
     852 * 
     853 * Returns 0 when the stat failed or if unable to perform a stat call. If successful 
     854 * it returns 1 
     855 */ 
    897856static int eaccelerator_stat(zend_file_handle *file_handle, 
    898857                        char* realname, struct stat* buf TSRMLS_DC) { 
    899 #ifdef EACCELERATOR_USE_INODE 
    900 #  ifndef ZEND_WIN32 
    901   if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp != NULL) { 
    902     if (fstat(fileno(file_handle->handle.fp), buf) == 0 && S_ISREG(buf->st_mode)) { 
    903       if (file_handle->opened_path != NULL) { 
    904         strcpy(realname, file_handle->opened_path); 
    905       } 
    906       return 0; 
    907     } 
    908   } else 
    909 #  endif 
    910   if (file_handle->opened_path != NULL) { 
    911     if (stat(file_handle->opened_path, buf) == 0 && S_ISREG(buf->st_mode)) { 
    912        strcpy(realname,file_handle->opened_path); 
    913        return 0; 
    914     } 
    915   } else if (PG(include_path) == NULL ||  
    916                                  file_handle->filename[0] == '.' || 
    917              IS_SLASH(file_handle->filename[0]) || 
    918              IS_ABSOLUTE_PATH(file_handle->filename,strlen(file_handle->filename))) { 
    919     if (stat(file_handle->filename, buf) == 0 && S_ISREG(buf->st_mode)) { 
    920        return 0; 
    921     } 
    922   } else { 
    923     char* ptr = PG(include_path); 
    924     char* end; 
    925     int   len; 
    926     char  tryname[MAXPATHLEN]; 
    927     int   filename_len = strlen(file_handle->filename); 
    928  
    929     while (ptr && *ptr) { 
    930       end = strchr(ptr, DEFAULT_DIR_SEPARATOR); 
    931       if (end != NULL) { 
    932         len = end - ptr; 
    933         end++; 
    934       } else { 
    935         len = strlen(ptr); 
    936         end = ptr + len; 
    937       } 
    938       if (len + filename_len + 2 < MAXPATHLEN) { 
    939         memcpy(tryname, ptr, len); 
    940         tryname[len] = '/'; 
    941         memcpy(tryname + len + 1, file_handle->filename, filename_len); 
    942         tryname[len + filename_len + 1] = '\0'; 
    943         if (stat(tryname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    944           return 0; 
    945         } 
    946       } 
    947       ptr = end; 
    948     } 
    949  
    950         if (zend_is_executing(TSRMLS_C)) { 
    951         int tryname_length; 
    952                 strncpy(tryname, zend_get_executed_filename(TSRMLS_C), MAXPATHLEN); 
    953                 tryname[MAXPATHLEN - 1] = 0; 
    954                 tryname_length = strlen(tryname); 
    955  
    956                 while (tryname_length >= 0 && !IS_SLASH(tryname[tryname_length])) { 
    957                         tryname_length--; 
    958                 } 
    959                 if (tryname_length > 0 && tryname[0] != '[' // [no active file] 
    960                         && tryname_length + filename_len + 1 < MAXPATHLEN) 
    961                 { 
    962                         strncpy(tryname + tryname_length + 1, file_handle->filename, filename_len + 1); 
    963                         if (stat(tryname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    964                                 return 0; 
    965                         } 
    966                 } 
     858        if (!ea_get_realname(file_handle, realname)) { 
     859                return 0; 
    967860        } 
    968   } 
    969   return -1; 
    970 #else 
    971   if (file_handle->opened_path != NULL) { 
    972     strcpy(realname,file_handle->opened_path); 
    973 #  ifndef ZEND_WIN32 
    974     if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp != NULL) { 
    975       if (!EAG(check_mtime_enabled) && !ea_mm_instance->check_mtime_enabled) { 
    976         return 0; 
    977       } else if (fstat(fileno(file_handle->handle.fp), buf) == 0 && S_ISREG(buf->st_mode)) { 
    978         return 0; 
    979       } else { 
    980         return -1; 
    981       } 
    982     } else { 
    983       if (!EAG(check_mtime_enabled) && !ea_mm_instance->check_mtime_enabled) { 
    984         return 0; 
    985       } else if (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    986         return 0; 
    987       } else { 
    988         return -1; 
    989       } 
    990     } 
    991 #  else 
    992     if (!EAG(check_mtime_enabled) && !ea_mm_instance->check_mtime_enabled) { 
    993       return 0; 
    994     } else if (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    995       return 0; 
    996     } else { 
    997       return -1; 
    998     } 
    999 #  endif 
    1000   } else if (file_handle->filename == NULL) { 
    1001     return -1; 
    1002   } else if (PG(include_path) == NULL ||  
    1003              file_handle->filename[0] == '.' || 
    1004              IS_SLASH(file_handle->filename[0]) || 
    1005              IS_ABSOLUTE_PATH(file_handle->filename,strlen(file_handle->filename))) { 
    1006     if (VCWD_REALPATH(file_handle->filename, realname)) { 
    1007       if (!EAG(check_mtime_enabled) && !ea_mm_instance->check_mtime_enabled) { 
    1008         return 0; 
    1009       } else if (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    1010         return 0; 
    1011       } else { 
    1012         return -1; 
    1013       } 
    1014     } 
    1015   } else { 
    1016     char* ptr = PG(include_path); 
    1017     char* end; 
    1018     int   len; 
    1019     char  tryname[MAXPATHLEN]; 
    1020     int   filename_len = strlen(file_handle->filename); 
    1021  
    1022     while (ptr && *ptr) { 
    1023       end = strchr(ptr, DEFAULT_DIR_SEPARATOR); 
    1024       if (end != NULL) { 
    1025         len = end - ptr; 
    1026         end++; 
    1027       } else { 
    1028         len = strlen(ptr); 
    1029         end = ptr + len; 
    1030       } 
    1031       if (len+filename_len+2 < MAXPATHLEN) { 
    1032         memcpy(tryname, ptr, len); 
    1033         tryname[len] = '/'; 
    1034         memcpy(tryname + len + 1, file_handle->filename, filename_len); 
    1035         tryname[len + filename_len + 1] = '\0'; 
    1036         if (VCWD_REALPATH(tryname, realname)) { 
    1037 #  ifdef ZEND_WIN32 
    1038           if (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    1039             return 0; 
    1040           } 
    1041 #  else 
    1042           if (!EAG(check_mtime_enabled) && !ea_mm_instance->check_mtime_enabled) { 
    1043             return 0; 
    1044           } else if (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)) { 
    1045             return 0; 
    1046           } else { 
    1047             return -1; 
    1048           } 
    1049 #  endif 
    1050         } 
    1051       } 
    1052       ptr = end; 
    1053     } 
    1054   } 
    1055   return -1; 
    1056 #endif 
     861 
     862        return (stat(realname, buf) == 0 && S_ISREG(buf->st_mode)); 
    1057863} 
    1058864 
     
    1079885        while (p != NULL) { 
    1080886                if (p->pattern[0] == '!') { 
    1081                   if ((fnmatch((const char *)(p->pattern + 1), path, 0) == 0)) { 
     887                       if ((fnmatch((const char *)(p->pattern + 1), path, 0) == 0)) { 
    1082888                                // a negative pattern matches, accept 
    1083889                                return 0; 
     
    1099905void ea_class_add_ref(zend_class_entry **ce) 
    1100906{ 
    1101             (*ce)->refcount++; 
     907        (*ce)->refcount++; 
    1102908} 
    1103909 
     
    1123929#endif 
    1124930 
    1125 #ifdef EACCELERATOR_USE_INODE 
    1126   realname[0] = '\000'; 
    1127 #endif 
    1128  
    1129931  DBG(ea_debug_start_time, (&tv_start)); 
    1130932  DBG(ea_debug_printf, (EA_DEBUG, "[%d] Enter COMPILE\n",getpid())); 
     
    1141943  if (!EAG(enabled) || (ea_mm_instance == NULL) ||  
    1142944      !ea_mm_instance->enabled || file_handle == NULL || 
    1143       file_handle->filename == NULL || stat_result != 0 || !ok_to_cache) { 
     945      file_handle->filename == NULL || stat_result == 0 || !ok_to_cache) { 
    1144946    DBG(ea_debug_printf, (EA_DEBUG, "\t[%d] compile_file: compiling\n", getpid())); 
    1145947    t = ea_saved_zend_compile_file(file_handle, type TSRMLS_CC); 
     
    1159961 
    1160962  if (buf.st_mtime >= EAG(req_start) && ea_debug > 0) { 
    1161         ea_debug_log("EACCELERATOR: Warning: \"%s\" is cached but it's mtime is in the future.\n", file_handle->filename); 
     963               ea_debug_log("EACCELERATOR: Warning: \"%s\" is cached but it's mtime is in the future.\n", file_handle->filename); 
    1162964  } 
    1163965 
     
    12401042     
    12411043                if (EAG(optimizer_enabled) && ea_mm_instance->optimizer_enabled) { 
    1242                   EAG(compiler) = 1; 
     1044                       EAG(compiler) = 1; 
    12431045                } 
    12441046 
     
    14191221              ea_mm_instance->enabled)?"true":"false"); 
    14201222  php_info_print_table_row(2, "Optimizer Enabled", (EAG(optimizer_enabled) &&  
    1421                                                   (ea_mm_instance != NULL) && ea_mm_instance->optimizer_enabled)?"true":"false"); 
     1223                                                       (ea_mm_instance != NULL) && ea_mm_instance->optimizer_enabled)?"true":"false"); 
    14221224  php_info_print_table_row(2, "Check mtime Enabled", (EAG(check_mtime_enabled) &&  
    1423                                                   (ea_mm_instance != NULL) && ea_mm_instance->check_mtime_enabled)?"true":"false"); 
     1225                                                       (ea_mm_instance != NULL) && ea_mm_instance->check_mtime_enabled)?"true":"false"); 
    14241226  if (ea_mm_instance != NULL) { 
    14251227    size_t available; 
     
    22652067 * c-basic-offset: 2 
    22662068 * End: 
    2267  * vim600: noet sw=2 ts=2 fdm=marker 
    2268  * vim<600: noet sw=2 ts=2 
     2069 * vim: noet sw=2 ts=2 fdm=marker 
    22692070 */ 
  • eaccelerator/trunk/eaccelerator.h

    r375 r385  
    5757#ifdef STR_EMPTY_ALLOC 
    5858#       define empty_string STR_EMPTY_ALLOC() 
    59 #endif 
    60  
    61 #if !defined(ZEND_WIN32) && defined(WITH_EACCELERATOR_USE_INODE) 
    62 /* UnDefine if your filesystem doesn't support inodes */ 
    63 #  define EACCELERATOR_USE_INODE 
    6459#endif 
    6560 
     
    289284typedef struct _ea_cache_entry { 
    290285        struct _ea_cache_entry *next; 
    291 #ifdef EACCELERATOR_USE_INODE 
    292         dev_t st_dev;                           /* file's device                         */ 
    293         ino_t st_ino;                           /* file's inode                          */ 
    294 #else 
    295286        unsigned int hv;                        /* hash value                            */ 
    296 #endif 
    297287        off_t filesize;                         /* file size */ 
    298288        time_t mtime;                           /* file last modification time           */ 
  • eaccelerator/trunk/eaccelerator_version.h

    r381 r385  
    11#ifndef EACCELERATOR_VERSION 
    2 #define EACCELERATOR_VERSION "0.9.6-rc2
     2#define EACCELERATOR_VERSION "1.0-dev
    33#endif