Cleanup tree.c cache handling a bit.

* Rename stuff to not re-use the term dircache
 * Move cache to own struct
 * Encapsulate retrieving entries a bit

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30242 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Thomas Martitz 2011-08-03 09:49:25 +00:00
parent fa5cf8edea
commit 98096970e0
9 changed files with 74 additions and 69 deletions

View file

@ -60,13 +60,13 @@ int ft_build_playlist(struct tree_context* c, int start_index)
int i; int i;
int start=start_index; int start=start_index;
struct entry *dircache = c->dircache; struct entry *entries = c->cache.entries;
for(i = 0;i < c->filesindir;i++) for(i = 0;i < c->filesindir;i++)
{ {
if((dircache[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
{ {
if (playlist_add(dircache[i].name) < 0) if (playlist_add(entries[i].name) < 0)
break; break;
} }
else else
@ -122,12 +122,12 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename)
return false; return false;
} }
/* walk a directory and check all dircache entries if a .talk file exists */ /* walk a directory and check all entries if a .talk file exists */
static void check_file_thumbnails(struct tree_context* c) static void check_file_thumbnails(struct tree_context* c)
{ {
int i; int i;
struct dirent *entry; struct dirent *entry;
struct entry* dircache = c->dircache; struct entry* entries = c->cache.entries;
DIR *dir; DIR *dir;
dir = opendir(c->currdir); dir = opendir(c->currdir);
@ -136,18 +136,18 @@ static void check_file_thumbnails(struct tree_context* c)
/* mark all files as non talking, except the .talk ones */ /* mark all files as non talking, except the .talk ones */
for (i=0; i < c->filesindir; i++) for (i=0; i < c->filesindir; i++)
{ {
if (dircache[i].attr & ATTR_DIRECTORY) if (entries[i].attr & ATTR_DIRECTORY)
continue; /* we're not touching directories */ continue; /* we're not touching directories */
if (strcasecmp(file_thumbnail_ext, if (strcasecmp(file_thumbnail_ext,
&dircache[i].name[strlen(dircache[i].name) &entries[i].name[strlen(entries[i].name)
- strlen(file_thumbnail_ext)])) - strlen(file_thumbnail_ext)]))
{ /* no .talk file */ { /* no .talk file */
dircache[i].attr &= ~FILE_ATTR_THUMBNAIL; /* clear */ entries[i].attr &= ~FILE_ATTR_THUMBNAIL; /* clear */
} }
else else
{ /* .talk file, we later let them speak themselves */ { /* .talk file, we later let them speak themselves */
dircache[i].attr |= FILE_ATTR_THUMBNAIL; /* set */ entries[i].attr |= FILE_ATTR_THUMBNAIL; /* set */
} }
} }
@ -170,9 +170,9 @@ static void check_file_thumbnails(struct tree_context* c)
/* search corresponding file in dir cache */ /* search corresponding file in dir cache */
for (i=0; i < c->filesindir; i++) for (i=0; i < c->filesindir; i++)
{ {
if (!strcasecmp(dircache[i].name, (char *)entry->d_name)) if (!strcasecmp(entries[i].name, (char *)entry->d_name))
{ /* match */ { /* match */
dircache[i].attr |= FILE_ATTR_THUMBNAIL; /* set the flag */ entries[i].attr |= FILE_ATTR_THUMBNAIL; /* set the flag */
break; /* exit search loop, because we found it */ break; /* exit search loop, because we found it */
} }
} }
@ -265,7 +265,7 @@ static int compare(const void* p1, const void* p2)
return 0; /* never reached */ return 0; /* never reached */
} }
/* load and sort directory into dircache. returns NULL on failure. */ /* load and sort directory into the tree's cache. returns NULL on failure. */
int ft_load(struct tree_context* c, const char* tempdir) int ft_load(struct tree_context* c, const char* tempdir)
{ {
int files_in_dir = 0; int files_in_dir = 0;
@ -290,8 +290,8 @@ int ft_load(struct tree_context* c, const char* tempdir)
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
int len; int len;
struct dirinfo info; struct dirinfo info;
struct entry* dptr = struct entry* table = c->cache.entries;
(struct entry*)(c->dircache + files_in_dir * sizeof(struct entry)); struct entry* dptr = &table[files_in_dir];
if (!entry) if (!entry)
break; break;
@ -360,8 +360,8 @@ int ft_load(struct tree_context* c, const char* tempdir)
continue; continue;
} }
if ((len > c->name_buffer_size - name_buffer_used - 1) || if ((len > c->cache.name_buffer_size - name_buffer_used - 1) ||
(files_in_dir >= c->dircache_count)) { (files_in_dir >= c->cache.max_entries)) {
/* Tell the world that we ran out of buffer space */ /* Tell the world that we ran out of buffer space */
c->dirfull = true; c->dirfull = true;
break; break;
@ -369,7 +369,7 @@ int ft_load(struct tree_context* c, const char* tempdir)
++files_in_dir; ++files_in_dir;
dptr->name = &c->name_buffer[name_buffer_used]; dptr->name = &c->cache.name_buffer[name_buffer_used];
dptr->time_write = dptr->time_write =
(long)info.wrtdate<<16 | (long)info.wrtdate<<16 |
(long)info.wrttime; /* in one # */ (long)info.wrttime; /* in one # */
@ -384,7 +384,7 @@ int ft_load(struct tree_context* c, const char* tempdir)
closedir(dir); closedir(dir);
compare_sort_dir = c->sort_dir; compare_sort_dir = c->sort_dir;
qsort(c->dircache, files_in_dir, sizeof(struct entry), compare); qsort(c->cache.entries, files_in_dir, sizeof(struct entry), compare);
/* If thumbnail talking is enabled, make an extra run to mark files with /* If thumbnail talking is enabled, make an extra run to mark files with
associated thumbnails, so we don't do unsuccessful spinups later. */ associated thumbnails, so we don't do unsuccessful spinups later. */
@ -424,8 +424,8 @@ int ft_enter(struct tree_context* c)
{ {
int rc = GO_TO_PREVIOUS; int rc = GO_TO_PREVIOUS;
char buf[MAX_PATH]; char buf[MAX_PATH];
struct entry *dircache = c->dircache; struct entry* table = c->cache.entries;
struct entry* file = &dircache[c->selected_item]; struct entry *file = &table[c->selected_item];
if (c->currdir[1]) if (c->currdir[1])
snprintf(buf,sizeof(buf),"%s/%s",c->currdir, file->name); snprintf(buf,sizeof(buf),"%s/%s",c->currdir, file->name);

View file

@ -1537,7 +1537,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
break; break;
} }
files = (struct entry*) tc->dircache; files = tc->cache.entries;
num_files = tc->filesindir; num_files = tc->filesindir;
for (i=0; i<num_files; i++) for (i=0; i<num_files; i++)
@ -1615,7 +1615,7 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
return -2; return -2;
} }
files = (struct entry*) tc->dircache; files = tc->cache.entries;
num_files = tc->filesindir; num_files = tc->filesindir;
for (i=0; i<num_files; i++) for (i=0; i<num_files; i++)
@ -3568,7 +3568,7 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
return -1; return -1;
} }
files = (struct entry*) tc->dircache; files = tc->cache.entries;
num_files = tc->filesindir; num_files = tc->filesindir;
/* we've overwritten the dircache so tree browser will need to be /* we've overwritten the dircache so tree browser will need to be
@ -3603,7 +3603,7 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
break; break;
} }
files = (struct entry*) tc->dircache; files = tc->cache.entries;
num_files = tc->filesindir; num_files = tc->filesindir;
if (!num_files) if (!num_files)
{ {

View file

@ -136,7 +136,7 @@ static enum image_type image_type = IMAGE_UNKNOWN;
static void get_pic_list(void) static void get_pic_list(void)
{ {
struct tree_context *tree = rb->tree_get_context(); struct tree_context *tree = rb->tree_get_context();
struct entry *dircache = tree->dircache; struct entry *dircache = tree->cache.entries;
int i; int i;
char *pname; char *pname;

View file

@ -185,7 +185,7 @@ bool mod_ext(const char ext[])
void get_mod_list(void) void get_mod_list(void)
{ {
struct tree_context *tree = rb->tree_get_context(); struct tree_context *tree = rb->tree_get_context();
struct entry *dircache = tree->dircache; struct entry *dircache = tree->cache.entries;
int i; int i;
char *pname; char *pname;

View file

@ -1876,7 +1876,7 @@ static bool is_videofile(const char* file)
static bool get_videofile(int direction, char* videofile, size_t bufsize) static bool get_videofile(int direction, char* videofile, size_t bufsize)
{ {
struct tree_context *tree = rb->tree_get_context(); struct tree_context *tree = rb->tree_get_context();
struct entry *dircache = tree->dircache; struct entry *dircache = tree->cache.entries;
int i, step, end, found = 0; int i, step, end, found = 0;
char *videoname = rb->strrchr(videofile, '/') + 1; char *videoname = rb->strrchr(videofile, '/') + 1;
size_t rest = bufsize - (videoname - videofile) - 1; size_t rest = bufsize - (videoname - videofile) - 1;

View file

@ -948,7 +948,7 @@ static bool browse_fonts( char *dst, int dst_size )
tree = rb->tree_get_context(); tree = rb->tree_get_context();
backup = *tree; backup = *tree;
dc = tree->dircache; dc = tree->cache.entries;
a = backup.currdir+rb->strlen(backup.currdir)-1; a = backup.currdir+rb->strlen(backup.currdir)-1;
if( *a != '/' ) if( *a != '/' )
{ {

View file

@ -1175,7 +1175,7 @@ static int format_str(struct tagcache_search *tcs, struct display_format *fmt,
static int retrieve_entries(struct tree_context *c, int offset, bool init) static int retrieve_entries(struct tree_context *c, int offset, bool init)
{ {
struct tagcache_search tcs; struct tagcache_search tcs;
struct tagentry *dptr = (struct tagentry *)c->dircache; struct tagentry *dptr = c->cache.entries;
struct display_format *fmt; struct display_format *fmt;
int i; int i;
int namebufused = 0; int namebufused = 0;
@ -1339,13 +1339,13 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
} }
} }
dptr->name = &c->name_buffer[namebufused]; dptr->name = &c->cache.name_buffer[namebufused];
if (fmt) if (fmt)
namebufused += strlen(buf)+1; namebufused += strlen(buf)+1;
else else
namebufused += tcs.result_len; namebufused += tcs.result_len;
if (namebufused >= c->name_buffer_size) if (namebufused >= c->cache.name_buffer_size)
{ {
logf("chunk mode #2: %d", current_entry_count); logf("chunk mode #2: %d", current_entry_count);
c->dirfull = true; c->dirfull = true;
@ -1363,7 +1363,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
dptr++; dptr++;
current_entry_count++; current_entry_count++;
if (current_entry_count >= c->dircache_count) if (current_entry_count >= c->cache.max_entries)
{ {
logf("chunk mode #3: %d", current_entry_count); logf("chunk mode #3: %d", current_entry_count);
c->dirfull = true; c->dirfull = true;
@ -1382,9 +1382,12 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
} }
if (sort) if (sort)
qsort(c->dircache + special_entry_count * c->dentry_size, {
int entry_size = sizeof(struct tagentry);
qsort(c->cache.entries + special_entry_count * entry_size,
current_entry_count - special_entry_count, current_entry_count - special_entry_count,
c->dentry_size, compare); entry_size, compare);
}
if (!init) if (!init)
{ {
@ -1416,7 +1419,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
if (strip) if (strip)
{ {
dptr = c->dircache; dptr = c->cache.entries;
for (i = 0; i < total_count; i++, dptr++) for (i = 0; i < total_count; i++, dptr++)
{ {
int len = strlen(dptr->name); int len = strlen(dptr->name);
@ -1434,7 +1437,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
static int load_root(struct tree_context *c) static int load_root(struct tree_context *c)
{ {
struct tagentry *dptr = (struct tagentry *)c->dircache; struct tagentry *dptr = c->cache.entries;
int i; int i;
tc = c; tc = c;
@ -1476,7 +1479,6 @@ int tagtree_load(struct tree_context* c)
int count; int count;
int table = c->currtable; int table = c->currtable;
c->dentry_size = sizeof(struct tagentry);
c->dirsindir = 0; c->dirsindir = 0;
if (!table) if (!table)
@ -1870,7 +1872,7 @@ static int tagtree_play_folder(struct tree_context* c)
struct tagentry* tagtree_get_entry(struct tree_context *c, int id) struct tagentry* tagtree_get_entry(struct tree_context *c, int id)
{ {
struct tagentry *entry = (struct tagentry *)c->dircache; struct tagentry *entry = (struct tagentry *)c->cache.entries;
int realid = id - current_offset; int realid = id - current_offset;
/* Load the next chunk if necessary. */ /* Load the next chunk if necessary. */

View file

@ -104,6 +104,12 @@ static int ft_play_dirname(char* name);
static void ft_play_filename(char *dir, char *file); static void ft_play_filename(char *dir, char *file);
static void say_filetype(int attr); static void say_filetype(int attr);
static struct entry* get_entry_at(struct tree_context *t, int index)
{
struct entry* entries = t->cache.entries;
return &entries[index];
}
static const char* tree_get_filename(int selected_item, void *data, static const char* tree_get_filename(int selected_item, void *data,
char *buffer, size_t buffer_len) char *buffer, size_t buffer_len)
{ {
@ -121,8 +127,7 @@ static const char* tree_get_filename(int selected_item, void *data,
else else
#endif #endif
{ {
struct entry* dc = local_tc->dircache; struct entry* e = get_entry_at(local_tc, selected_item);
struct entry* e = &dc[selected_item];
name = e->name; name = e->name;
attr = e->attr; attr = e->attr;
} }
@ -164,8 +169,7 @@ static int tree_get_filecolor(int selected_item, void * data)
if (*tc.dirfilter == SHOW_ID3DB) if (*tc.dirfilter == SHOW_ID3DB)
return -1; return -1;
struct tree_context * local_tc=(struct tree_context *)data; struct tree_context * local_tc=(struct tree_context *)data;
struct entry* dc = local_tc->dircache; struct entry* e = get_entry_at(local_tc, selected_item);
struct entry* e = &dc[selected_item];
return filetype_get_color(e->name, e->attr); return filetype_get_color(e->name, e->attr);
} }
#endif #endif
@ -180,9 +184,8 @@ static enum themable_icons tree_get_fileicon(int selected_item, void * data)
} }
else else
#endif #endif
{ {
struct entry* dc = local_tc->dircache; struct entry* e = get_entry_at(local_tc, selected_item);
struct entry* e = &dc[selected_item];
return filetype_get_icon(e->attr); return filetype_get_icon(e->attr);
} }
} }
@ -203,8 +206,7 @@ static int tree_voice_cb(int selected_item, void * data)
else else
#endif #endif
{ {
struct entry* dc = local_tc->dircache; struct entry* e = get_entry_at(local_tc, selected_item);
struct entry* e = &dc[selected_item];
name = e->name; name = e->name;
attr = e->attr; attr = e->attr;
} }
@ -322,12 +324,12 @@ struct tree_context* tree_get_context(void)
static int tree_get_file_position(char * filename) static int tree_get_file_position(char * filename)
{ {
int i; int i;
struct entry* e;
/* use lastfile to determine the selected item (default=0) */ /* use lastfile to determine the selected item (default=0) */
for (i=0; i < tc.filesindir; i++) for (i=0; i < tc.filesindir; i++)
{ {
struct entry* dc = tc.dircache; e = get_entry_at(&tc, i);
struct entry* e = &dc[i];
if (!strcasecmp(e->name, filename)) if (!strcasecmp(e->name, filename))
return(i); return(i);
} }
@ -529,8 +531,7 @@ char* get_current_file(char* buffer, size_t buffer_len)
return NULL; return NULL;
#endif #endif
struct entry* dc = tc.dircache; struct entry* e = get_entry_at(&tc, tc.selected_item);
struct entry* e = &dc[tc.selected_item];
if (getcwd(buffer, buffer_len)) if (getcwd(buffer, buffer_len))
{ {
if (tc.dirlength) if (tc.dirlength)
@ -649,7 +650,7 @@ static int dirbrowse(void)
gui_synclist_draw(&tree_lists); gui_synclist_draw(&tree_lists);
while(1) { while(1) {
struct entry *dircache = tc.dircache; struct entry *entries = tc.cache.entries;
bool restore = false; bool restore = false;
if (tc.dirlevel < 0) if (tc.dirlevel < 0)
tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
@ -666,7 +667,7 @@ static int dirbrowse(void)
break; break;
if ((tc.browse->flags & BROWSE_SELECTONLY) && if ((tc.browse->flags & BROWSE_SELECTONLY) &&
!(dircache[tc.selected_item].attr & ATTR_DIRECTORY)) !(entries[tc.selected_item].attr & ATTR_DIRECTORY))
{ {
tc.browse->flags |= BROWSE_SELECTED; tc.browse->flags |= BROWSE_SELECTED;
get_current_file(tc.browse->buf, tc.browse->bufsize); get_current_file(tc.browse->buf, tc.browse->bufsize);
@ -791,15 +792,15 @@ static int dirbrowse(void)
else else
#endif #endif
{ {
attr = dircache[tc.selected_item].attr; attr = entries[tc.selected_item].attr;
if (currdir[1]) /* Not in / */ if (currdir[1]) /* Not in / */
snprintf(buf, sizeof buf, "%s/%s", snprintf(buf, sizeof buf, "%s/%s",
currdir, currdir,
dircache[tc.selected_item].name); entries[tc.selected_item].name);
else /* In / */ else /* In / */
snprintf(buf, sizeof buf, "/%s", snprintf(buf, sizeof buf, "/%s",
dircache[tc.selected_item].name); entries[tc.selected_item].name);
} }
onplay_result = onplay(buf, attr, curr_context, hotkey); onplay_result = onplay(buf, attr, curr_context, hotkey);
} }
@ -1001,17 +1002,17 @@ int rockbox_browse(struct browse_context *browse)
void tree_mem_init(void) void tree_mem_init(void)
{ {
/* initialize tree context struct */ /* initialize tree context struct */
struct tree_cache* cache = &tc.cache;
memset(&tc, 0, sizeof(tc)); memset(&tc, 0, sizeof(tc));
tc.dirfilter = &global_settings.dirfilter; tc.dirfilter = &global_settings.dirfilter;
tc.sort_dir = global_settings.sort_dir; tc.sort_dir = global_settings.sort_dir;
tc.name_buffer_size = AVERAGE_FILENAME_LENGTH * cache->name_buffer_size = AVERAGE_FILENAME_LENGTH *
global_settings.max_files_in_dir; global_settings.max_files_in_dir;
tc.name_buffer = buffer_alloc(tc.name_buffer_size); cache->name_buffer = buffer_alloc(cache->name_buffer_size);
tc.dircache_count = global_settings.max_files_in_dir; cache->max_entries = global_settings.max_files_in_dir;
tc.dircache = buffer_alloc(global_settings.max_files_in_dir * cache->entries = buffer_alloc(cache->max_entries*(sizeof(cache->entries)));
sizeof(struct entry));
tree_get_filetypes(&filetypes, &filetypes_count); tree_get_filetypes(&filetypes, &filetypes_count);
} }

View file

@ -38,6 +38,15 @@ struct entry {
#define BROWSE_SELECTED 0x0100 /* this bit is set if user selected item */ #define BROWSE_SELECTED 0x0100 /* this bit is set if user selected item */
struct tree_context; struct tree_context;
struct tree_cache {
/* A big buffer with plenty of entry structs,
* contains all files and dirs in the current
* dir (with filters applied) */
void* entries;
char* name_buffer;
int max_entries; /* Max entries in the cache */
int name_buffer_size; /* in bytes */
};
struct browse_context { struct browse_context {
int dirfilter; int dirfilter;
@ -80,14 +89,7 @@ struct tree_context {
int currtable; /* db use */ int currtable; /* db use */
int currextra; /* db use */ int currextra; /* db use */
#endif #endif
/* A big buffer with plenty of entry structs, struct tree_cache cache;
* contains all files and dirs in the current
* dir (with filters applied) */
void* dircache;
int dircache_count; /* Number of entries in dircache */
char* name_buffer;
int name_buffer_size;
int dentry_size;
bool dirfull; bool dirfull;
int sort_dir; /* directory sort order */ int sort_dir; /* directory sort order */
struct browse_context *browse; struct browse_context *browse;