Make VOP_LOOKUP's O(1) instead of O(n log(n)) giving a speedup of 7500% on

a 1400 file directory.
This commit is contained in:
reinoud 2006-09-19 23:59:16 +00:00
parent b62d9f714a
commit ce2c68fd18
2 changed files with 16 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf.h,v 1.6 2006/08/22 16:52:41 reinoud Exp $ */
/* $NetBSD: udf.h,v 1.7 2006/09/19 23:59:16 reinoud Exp $ */
/*
* Copyright (c) 2006 Reinoud Zandijk
@ -230,6 +230,7 @@ struct udf_node {
struct long_ad loc; /* FID/hash loc. */
struct long_ad next_loc; /* strat 4096 loc */
int needs_indirect; /* has missing indr. */
uint64_t last_diroffset; /* speeding up lookup*/
/* TODO support for allocation extents? */

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_subr.c,v 1.17 2006/09/19 22:00:38 reinoud Exp $ */
/* $NetBSD: udf_subr.c,v 1.18 2006/09/19 23:59:16 reinoud Exp $ */
/*
* Copyright (c) 2006 Reinoud Zandijk
@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: udf_subr.c,v 1.17 2006/09/19 22:00:38 reinoud Exp $");
__RCSID("$NetBSD: udf_subr.c,v 1.18 2006/09/19 23:59:16 reinoud Exp $");
#endif /* not lint */
@ -2336,13 +2336,22 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
fid = malloc(lb_size, M_TEMP, M_WAITOK);
found = 0;
diroffset = 0;
while (!found && (diroffset < file_size)) {
diroffset = dir_node->last_diroffset;
while (!found) {
/* if not found in this track, turn trough zero */
if (diroffset >= file_size)
diroffset = 0;
/* transfer a new fid/dirent */
error = udf_read_fid_stream(vp, &diroffset, fid, &dirent);
if (error)
break;
if (diroffset == dir_node->last_diroffset) {
/* we have cycled */
break;
}
/* skip deleted entries */
if (fid->file_char & UDF_FILE_CHAR_DEL)
continue;
@ -2354,6 +2363,7 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
}
}
free(fid, M_TEMP);
dir_node->last_diroffset = diroffset;
return found;
}