summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-03-28 11:51:12 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-03-28 11:51:12 +0000
commit2d93495df2dd0c7c61fa73e07bb8fcae3d1ea5fd (patch)
tree38d90cb0894b238b84cfa88b3e4cc3658b8a7ced
parent6784e0333f3d8ee806a7eacbf2b709f45ffea0f5 (diff)
downloadrockbox-2d93495df2dd0c7c61fa73e07bb8fcae3d1ea5fd.zip
rockbox-2d93495df2dd0c7c61fa73e07bb8fcae3d1ea5fd.tar.gz
rockbox-2d93495df2dd0c7c61fa73e07bb8fcae3d1ea5fd.tar.bz2
rockbox-2d93495df2dd0c7c61fa73e07bb8fcae3d1ea5fd.tar.xz
Boost open() performance on platforms with dircache. Tagcache initial
scanning now over 50% faster than before. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9306 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/dircache.c20
-rw-r--r--firmware/common/file.c37
-rw-r--r--firmware/include/dircache.h4
3 files changed, 52 insertions, 9 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index f9fd63b..873e0f9 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -798,12 +798,20 @@ void dircache_bind(int fd, const char *path)
fd_bindings[fd] = entry;
}
-void dircache_update_filesize(int fd, long newsize)
+void dircache_update_filesize(int fd, long newsize, long startcluster)
{
if (!dircache_initialized || fd < 0)
return ;
+ if (fd_bindings[fd] == NULL)
+ {
+ logf("dircache fd access error");
+ dircache_initialized = false;
+ return ;
+ }
+
fd_bindings[fd]->size = newsize;
+ fd_bindings[fd]->startcluster = startcluster;
}
void dircache_mkdir(const char *path)
@@ -915,13 +923,19 @@ void dircache_rename(const char *oldpath, const char *newpath)
newentry->wrtdate = oldentry.wrtdate;
}
-void dircache_add_file(const char *path)
+void dircache_add_file(const char *path, long startcluster)
{
+ struct dircache_entry *entry;
+
if (!dircache_initialized)
return ;
logf("add file: %s", path);
- dircache_new_entry(path, 0);
+ entry = dircache_new_entry(path, 0);
+ if (entry == NULL)
+ return ;
+
+ entry->startcluster = startcluster;
}
DIRCACHED* opendir_cached(const char* name)
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 761caee..a0b4296 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -99,9 +99,35 @@ int open(const char* pathname, int flags)
}
file->busy = true;
+#ifdef HAVE_DIRCACHE
+ if (dircache_is_enabled() && !file->write)
+ {
+ const struct dircache_entry *ce;
+
+ ce = dircache_get_entry_ptr(pathname);
+ if (!ce)
+ {
+ errno = ENOENT;
+ file->busy = false;
+ return -7;
+ }
+
+ fat_open(IF_MV2(unsupported at the moment,)
+ ce->startcluster,
+ &(file->fatfile),
+ NULL);
+ file->size = ce->size;
+ file->attr = ce->attribute;
+ file->cacheoffset = -1;
+ file->fileoffset = 0;
+
+ return fd;
+ }
+#endif
+
strncpy(pathnamecopy,pathname,sizeof(pathnamecopy));
pathnamecopy[sizeof(pathnamecopy)-1] = 0;
-
+
/* locate filename */
name=strrchr(pathnamecopy+1,'/');
if ( name ) {
@@ -120,7 +146,7 @@ int open(const char* pathname, int flags)
file->busy = false;
return -4;
}
-
+
if(name[0] == 0) {
DEBUGF("Empty file name\n");
errno = EINVAL;
@@ -156,7 +182,7 @@ int open(const char* pathname, int flags)
return rc * 10 - 6;
}
#ifdef HAVE_DIRCACHE
- dircache_add_file(pathname);
+ dircache_add_file(pathname, file->fatfile.firstcluster);
#endif
file->size = 0;
file->attr = 0;
@@ -394,6 +420,9 @@ int ftruncate(int fd, off_t size)
}
file->size = size;
+#ifdef HAVE_DIRCACHE
+ dircache_update_filesize(fd, size, file->fatfile.firstcluster);
+#endif
return 0;
}
@@ -569,7 +598,7 @@ static int readwrite(int fd, void* buf, long count, bool write)
{
file->size = file->fileoffset;
#ifdef HAVE_DIRCACHE
- dircache_update_filesize(fd, file->size);
+ dircache_update_filesize(fd, file->size, file->fatfile.firstcluster);
#endif
}
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 93bc413..48f2980 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -82,12 +82,12 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size);
void dircache_bind(int fd, const char *path);
-void dircache_update_filesize(int fd, long newsize);
+void dircache_update_filesize(int fd, long newsize, long startcluster);
void dircache_mkdir(const char *path);
void dircache_rmdir(const char *path);
void dircache_remove(const char *name);
void dircache_rename(const char *oldpath, const char *newpath);
-void dircache_add_file(const char *path);
+void dircache_add_file(const char *path, long startcluster);
DIRCACHED* opendir_cached(const char* name);
struct dircache_entry* readdir_cached(DIRCACHED* dir);