brintos

brintos / linux-shallow public Read only

0
0
Text · 1.2 KiB · 6225cbc Raw
64 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Manage a cache of file names' existence */3#include <stdlib.h>4#include <unistd.h>5#include <string.h>6#include <linux/list.h>7#include "fncache.h"8 9struct fncache {10	struct hlist_node nd;11	bool res;12	char name[];13};14 15#define FNHSIZE 6116 17static struct hlist_head fncache_hash[FNHSIZE];18 19unsigned shash(const unsigned char *s)20{21	unsigned h = 0;22	while (*s)23		h = 65599 * h + *s++;24	return h ^ (h >> 16);25}26 27static bool lookup_fncache(const char *name, bool *res)28{29	int h = shash((const unsigned char *)name) % FNHSIZE;30	struct fncache *n;31 32	hlist_for_each_entry(n, &fncache_hash[h], nd) {33		if (!strcmp(n->name, name)) {34			*res = n->res;35			return true;36		}37	}38	return false;39}40 41static void update_fncache(const char *name, bool res)42{43	struct fncache *n = malloc(sizeof(struct fncache) + strlen(name) + 1);44	int h = shash((const unsigned char *)name) % FNHSIZE;45 46	if (!n)47		return;48	strcpy(n->name, name);49	n->res = res;50	hlist_add_head(&n->nd, &fncache_hash[h]);51}52 53/* No LRU, only use when bounded in some other way. */54bool file_available(const char *name)55{56	bool res;57 58	if (lookup_fncache(name, &res))59		return res;60	res = access(name, R_OK) == 0;61	update_fncache(name, res);62	return res;63}64