Skip to content

Commit d09b710

Browse files
committed
Change realpath cache hash algorithm to the regular string hash algorithm
Right now the FNV-1 algorithm is used for determine the realpath cache key. For applications that are light-weight, but have lots of files (e.g. WordPress), the realpath cache key computation shows up in the Callgrind profile. The reason is that we do a simple byte-by-byte loop. Furthermore, we always use the 32-bit prime and offset values, even in a 64-bit environment which reduces the diffusion property of the hash. This hinders the distribution of keys a bit (although probably not a lot since we have only limited entries in the cache). I propose to switch to our regular string hashing algorithm, which is better optimised than a byte-per-byte loop, and has better diffusion on 64-bit systems. I don't know why FNV-1 was chosen over the DJB33X algorithm we use in the normal string hashing. Also, I don't know why FNV-1A wasn't chosen instead of FNV-1, which would be a simple modification and would distribute the hashes better than FNV-1. The only thing I can think of is that typically FNV-1A has a better distribution than DJB33X algorithms like what we use for string hashing [1]. But I doubt that makes a difference here, and if it does then we should perhaps look into changing the string hash algorithm from DJB33X to FNV-1A. [1] https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
1 parent 976d7ed commit d09b710

File tree

1 file changed

+5
-20
lines changed

1 file changed

+5
-20
lines changed

Zend/zend_virtual_cwd.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -317,39 +317,24 @@ CWD_API char *virtual_getcwd(char *buf, size_t size) /* {{{ */
317317
#ifdef ZEND_WIN32
318318
static inline zend_ulong realpath_cache_key(const char *path, size_t path_len) /* {{{ */
319319
{
320-
zend_ulong h;
321320
size_t bucket_key_len;
322-
const char *bucket_key_start = tsrm_win32_get_path_sid_key(path, path_len, &bucket_key_len);
323-
const char *bucket_key = bucket_key_start;
324-
const char *e;
321+
const char *bucket_key = tsrm_win32_get_path_sid_key(path, path_len, &bucket_key_len);
325322

326323
if (!bucket_key) {
327324
return 0;
328325
}
329326

330-
e = bucket_key + bucket_key_len;
331-
for (h = Z_UL(2166136261); bucket_key < e;) {
332-
h *= Z_UL(16777619);
333-
h ^= *bucket_key++;
334-
}
335-
if (bucket_key_start != path) {
336-
HeapFree(GetProcessHeap(), 0, (LPVOID)bucket_key_start);
327+
zend_ulong h = zend_hash_func(bucket_key, bucket_key_len);
328+
if (bucket_key != path) {
329+
HeapFree(GetProcessHeap(), 0, (LPVOID)bucket_key);
337330
}
338331
return h;
339332
}
340333
/* }}} */
341334
#else
342335
static inline zend_ulong realpath_cache_key(const char *path, size_t path_len) /* {{{ */
343336
{
344-
zend_ulong h;
345-
const char *e = path + path_len;
346-
347-
for (h = Z_UL(2166136261); path < e;) {
348-
h *= Z_UL(16777619);
349-
h ^= *path++;
350-
}
351-
352-
return h;
337+
return zend_hash_func(path, path_len);
353338
}
354339
/* }}} */
355340
#endif /* defined(ZEND_WIN32) */

0 commit comments

Comments
 (0)