[stat_cache] separate symlink pol from data struct

separate symlink polily from internal data structures
no more dup entires in splaytree for allowing/disallowing symlinks

hash name to provided len
personal/stbuehler/ci-build
Glenn Strauss 4 years ago
parent 73bfee6308
commit 020a83c265

@ -86,20 +86,19 @@ typedef struct stat_cache {
/* the famous DJB hash function for strings */
static uint32_t hashme(const char *str, int z) {
uint32_t hash = 5381;
for (const unsigned char *s = (const unsigned char *)str; *s; ++s) {
hash = ((hash << 5) + hash) ^ *s;
}
/* customizations */
/* (differentiate hash values with and w/o con->conf.follow_symlink) */
hash = ((hash << 5) + hash) ^ (z ? '1' : '0');
static uint32_t djbhash(const char *str, const size_t len)
{
const unsigned char * const s = (const unsigned char *)str;
uint32_t hash = 5381;
for (size_t i = 0; i < len; ++i) hash = ((hash << 5) + hash) ^ s[i];
return hash;
}
hash &= ~(((uint32_t)1) << 31); /* strip the highest bit */
return hash;
static uint32_t hashme(const char *str, const size_t len)
{
/* strip highest bit of hash value for splaytree */
return djbhash(str,len) & ~(((uint32_t)1) << 31);
}
@ -164,7 +163,7 @@ static handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent)
FAMEvent fe;
fam_dir_entry *fam_dir;
splay_tree *node;
int ndx, j;
int ndx;
FAMNextEvent(&scf->fam, &fe);
@ -182,11 +181,7 @@ static handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent)
/* file/dir is still here */
if (fe.code == FAMChanged) break;
/* we have 2 versions, follow and no-follow-symlink */
for (j = 0; j < 2; j++) {
ndx = hashme(fe.filename, j);
ndx = hashme(fe.filename, strlen(fe.filename));
scf->dirs = splaytree_splay(scf->dirs, ndx);
node = scf->dirs;
@ -199,7 +194,6 @@ static handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent)
force_assert(osize - 1 == splaytree_size(scf->dirs));
}
}
break;
default:
break;
@ -287,14 +281,14 @@ static int buffer_copy_dirname(buffer *dst, const buffer *file) {
return -1;
}
static handler_t stat_cache_fam_dir_check(server *srv, stat_cache_fam *scf, stat_cache_entry *sce, const buffer *name, unsigned int follow_symlink) {
static handler_t stat_cache_fam_dir_check(server *srv, stat_cache_fam *scf, stat_cache_entry *sce, const buffer *name) {
if (0 != buffer_copy_dirname(scf->dir_name, name)) {
log_error_write(srv, __FILE__, __LINE__, "sb",
"no '/' found in filename:", name);
return HANDLER_ERROR;
}
scf->dir_ndx = hashme(scf->dir_name->ptr, follow_symlink);
scf->dir_ndx = hashme(CONST_BUF_LEN(scf->dir_name));
scf->dirs = splaytree_splay(scf->dirs, scf->dir_ndx);
@ -590,8 +584,8 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
stat_cache *sc;
struct stat st;
int fd;
const int follow_symlink = con->conf.follow_symlink;
int file_ndx;
UNUSED(con);
*ret_sce = NULL;
@ -601,7 +595,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
sc = srv->stat_cache;
file_ndx = hashme(name->ptr, follow_symlink);
file_ndx = hashme(CONST_BUF_LEN(name));
sc->files = splaytree_splay(sc->files, file_ndx);
if (sc->files && (sc->files->key == file_ndx)) {
@ -614,7 +608,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
if (buffer_is_equal(name, sce->name)) {
if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) {
if (sce->stat_ts == srv->cur_ts && follow_symlink) {
if (sce->stat_ts == srv->cur_ts) {
*ret_sce = sce;
return HANDLER_GO_ON;
}
@ -628,7 +622,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
#ifdef HAVE_FAM_H
/* dir-check */
if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
switch (stat_cache_fam_dir_check(srv, sc->scf, sce, name, follow_symlink)) {
switch (stat_cache_fam_dir_check(srv, sc->scf, sce, name)) {
case HANDLER_GO_ON:
break;
case HANDLER_FINISHED:

Loading…
Cancel
Save