Dircache: Don't expose struct dircache_entry and pointers into the cache, use IDs instead.
Only integer IDs are exposed from dircache with this. This way the cache is isolated from other modules. This is needed for my buflib gsoc project. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30038 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0b9c57d33e
commit
af7aaae478
8 changed files with 104 additions and 95 deletions
|
@ -575,7 +575,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
|
|||
playlist->indices[ playlist->amount ] = i+count;
|
||||
#ifdef HAVE_DIRCACHE
|
||||
if (playlist->filenames)
|
||||
playlist->filenames[ playlist->amount ] = NULL;
|
||||
playlist->filenames[ playlist->amount ] = -1;
|
||||
#endif
|
||||
playlist->amount++;
|
||||
}
|
||||
|
@ -816,7 +816,7 @@ static int add_track_to_playlist(struct playlist_info* playlist,
|
|||
|
||||
#ifdef HAVE_DIRCACHE
|
||||
if (playlist->filenames)
|
||||
playlist->filenames[insert_position] = NULL;
|
||||
playlist->filenames[insert_position] = -1;
|
||||
#endif
|
||||
|
||||
playlist->amount++;
|
||||
|
@ -958,9 +958,9 @@ static int randomise_playlist(struct playlist_info* playlist,
|
|||
#ifdef HAVE_DIRCACHE
|
||||
if (playlist->filenames)
|
||||
{
|
||||
store = (long)playlist->filenames[candidate];
|
||||
store = playlist->filenames[candidate];
|
||||
playlist->filenames[candidate] = playlist->filenames[count];
|
||||
playlist->filenames[count] = (struct dircache_entry *)store;
|
||||
playlist->filenames[count] = store;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1298,7 +1298,7 @@ static void playlist_thread(void)
|
|||
&& queue_empty(&playlist_queue); index++)
|
||||
{
|
||||
/* Process only pointers that are not already loaded. */
|
||||
if (playlist->filenames[index])
|
||||
if (playlist->filenames[index] >= 0)
|
||||
continue ;
|
||||
|
||||
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
|
||||
|
@ -1310,7 +1310,7 @@ static void playlist_thread(void)
|
|||
break ;
|
||||
|
||||
/* Set the dircache entry pointer. */
|
||||
playlist->filenames[index] = dircache_get_entry_ptr(tmp);
|
||||
playlist->filenames[index] = dircache_get_entry_id(tmp);
|
||||
|
||||
/* And be on background so user doesn't notice any delays. */
|
||||
yield();
|
||||
|
@ -1351,7 +1351,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
|
|||
#ifdef HAVE_DIRCACHE
|
||||
if (dircache_is_enabled() && playlist->filenames)
|
||||
{
|
||||
if (playlist->filenames[index] != NULL)
|
||||
if (playlist->filenames[index] >= 0)
|
||||
{
|
||||
max = dircache_copy_path(playlist->filenames[index],
|
||||
tmp_buf, sizeof(tmp_buf)-1);
|
||||
|
@ -2389,7 +2389,7 @@ int playlist_add(const char *filename)
|
|||
|
||||
playlist->indices[playlist->amount] = playlist->buffer_end_pos;
|
||||
#ifdef HAVE_DIRCACHE
|
||||
playlist->filenames[playlist->amount] = NULL;
|
||||
playlist->filenames[playlist->amount] = -1;
|
||||
#endif
|
||||
playlist->amount++;
|
||||
|
||||
|
@ -2713,8 +2713,7 @@ int playlist_create_ex(struct playlist_info* playlist,
|
|||
playlist->max_playlist_size = num_indices;
|
||||
playlist->indices = index_buffer;
|
||||
#ifdef HAVE_DIRCACHE
|
||||
playlist->filenames = (const struct dircache_entry **)
|
||||
&playlist->indices[num_indices];
|
||||
playlist->filenames = (int*)&playlist->indices[num_indices];
|
||||
#endif
|
||||
|
||||
playlist->buffer_size = 0;
|
||||
|
|
|
@ -81,7 +81,7 @@ struct playlist_info
|
|||
bool control_created; /* has control file been created? */
|
||||
int dirlen; /* Length of the path to the playlist file */
|
||||
unsigned long *indices; /* array of indices */
|
||||
const struct dircache_entry **filenames; /* Entries from dircache */
|
||||
int *filenames; /* Array of dircache indices */
|
||||
int max_playlist_size; /* Max number of files in playlist. Mirror of
|
||||
global_settings.max_files_in_playlist */
|
||||
bool in_ram; /* playlist stored in ram (dirplay) */
|
||||
|
|
|
@ -383,8 +383,9 @@ static bool do_timed_yield(void)
|
|||
#endif
|
||||
|
||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||
static long find_entry_ram(const char *filename,
|
||||
const struct dircache_entry *dc)
|
||||
/* find the ramcache entry corresponding to the file indicated by
|
||||
* filename and dc (it's corresponding dircache id). */
|
||||
static long find_entry_ram(const char *filename, int dc)
|
||||
{
|
||||
static long last_pos = 0;
|
||||
int i;
|
||||
|
@ -393,10 +394,10 @@ static long find_entry_ram(const char *filename,
|
|||
if (!tc_stat.ramcache)
|
||||
return -1;
|
||||
|
||||
if (dc == NULL)
|
||||
dc = dircache_get_entry_ptr(filename);
|
||||
if (dc < 0)
|
||||
dc = dircache_get_entry_id(filename);
|
||||
|
||||
if (dc == NULL)
|
||||
if (dc < 0)
|
||||
{
|
||||
logf("tagcache: file not found.");
|
||||
return -1;
|
||||
|
@ -411,7 +412,7 @@ static long find_entry_ram(const char *filename,
|
|||
|
||||
for (; i < current_tcmh.tch.entry_count; i++)
|
||||
{
|
||||
if (hdr->indices[i].tag_seek[tag_filename] == (long)dc)
|
||||
if (hdr->indices[i].tag_seek[tag_filename] == dc)
|
||||
{
|
||||
last_pos = MAX(0, i - 3);
|
||||
return i;
|
||||
|
@ -539,7 +540,7 @@ static int find_index(const char *filename)
|
|||
|
||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||
if (tc_stat.ramcache && is_dircache_intact())
|
||||
idx_id = find_entry_ram(filename, NULL);
|
||||
idx_id = find_entry_ram(filename, -1);
|
||||
#endif
|
||||
|
||||
if (idx_id < 0)
|
||||
|
@ -723,8 +724,8 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
|
|||
if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)
|
||||
&& is_dircache_intact())
|
||||
{
|
||||
dircache_copy_path((struct dircache_entry *)seek,
|
||||
buf, size);
|
||||
/* for tag_filename, seek is a dircache index */
|
||||
dircache_copy_path(seek, buf, size);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -1481,8 +1482,7 @@ static bool get_next(struct tagcache_search *tcs)
|
|||
if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE)
|
||||
&& is_dircache_intact())
|
||||
{
|
||||
size_t len = dircache_copy_path((struct dircache_entry *)tcs->position,
|
||||
buf, sizeof buf);
|
||||
size_t len = dircache_copy_path(tcs->position, buf, sizeof buf);
|
||||
tcs->result_len = len + 1;
|
||||
tcs->result = buf;
|
||||
tcs->ramresult = false;
|
||||
|
@ -1599,29 +1599,6 @@ static bool update_master_header(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void tagcache_modify(struct tagcache_search *tcs, int type, const char *text)
|
||||
{
|
||||
struct tagentry *entry;
|
||||
|
||||
if (tcs->type != tag_title)
|
||||
return ;
|
||||
|
||||
/* We will need reserve buffer for this. */
|
||||
if (tcs->ramcache)
|
||||
{
|
||||
struct tagfile_entry *ep;
|
||||
|
||||
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->result_seek];
|
||||
tcs->seek_list[tcs->seek_list_count];
|
||||
}
|
||||
|
||||
entry = find_entry_ram();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void tagcache_search_finish(struct tagcache_search *tcs)
|
||||
{
|
||||
int i;
|
||||
|
@ -1677,7 +1654,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
|
|||
return false;
|
||||
|
||||
/* Find the corresponding entry in tagcache. */
|
||||
idx_id = find_entry_ram(filename, NULL);
|
||||
idx_id = find_entry_ram(filename, -1);
|
||||
if (idx_id < 0)
|
||||
return false;
|
||||
|
||||
|
@ -1761,7 +1738,7 @@ static int check_if_empty(char **tag)
|
|||
static void __attribute__ ((noinline)) add_tagcache(char *path,
|
||||
unsigned long mtime
|
||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||
,const struct dircache_entry *dc
|
||||
,int dc
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
@ -4017,7 +3994,7 @@ static bool load_tagcache(void)
|
|||
if (tag == tag_filename)
|
||||
{
|
||||
# ifdef HAVE_DIRCACHE
|
||||
const struct dircache_entry *dc;
|
||||
int dc;
|
||||
# endif
|
||||
|
||||
// FIXME: This is wrong!
|
||||
|
@ -4064,8 +4041,8 @@ static bool load_tagcache(void)
|
|||
# ifdef HAVE_DIRCACHE
|
||||
if (dircache_is_enabled())
|
||||
{
|
||||
dc = dircache_get_entry_ptr(buf);
|
||||
if (dc == NULL)
|
||||
dc = dircache_get_entry_id(buf);
|
||||
if (dc < 0)
|
||||
{
|
||||
logf("Entry no longer valid.");
|
||||
logf("-> %s", buf);
|
||||
|
@ -4075,7 +4052,7 @@ static bool load_tagcache(void)
|
|||
}
|
||||
|
||||
idx->flag |= FLAG_DIRCACHE;
|
||||
idx->tag_seek[tag_filename] = (long)dc;
|
||||
idx->tag_seek[tag_filename] = dc;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
|
|
|
@ -57,7 +57,23 @@
|
|||
#else
|
||||
#define MAX_OPEN_DIRS 8
|
||||
#endif
|
||||
static DIR_CACHED opendirs[MAX_OPEN_DIRS];
|
||||
|
||||
#define MAX_PENDING_BINDINGS 2
|
||||
struct fdbind_queue {
|
||||
char path[MAX_PATH];
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* Exported structures. */
|
||||
struct dircache_entry {
|
||||
struct dirinfo info;
|
||||
struct dircache_entry *next;
|
||||
struct dircache_entry *up;
|
||||
struct dircache_entry *down;
|
||||
long startcluster;
|
||||
char *d_name;
|
||||
};
|
||||
|
||||
/* Cache Layout:
|
||||
*
|
||||
* x - array of struct dircache_entry
|
||||
|
@ -75,7 +91,6 @@ static DIR_CACHED opendirs[MAX_OPEN_DIRS];
|
|||
* total allocation size grows
|
||||
* |xxxxxxxx|rrrrrrrrr|dddddddd|
|
||||
*/
|
||||
static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
|
||||
/* this points to the beginnging of the buffer and the first entry */
|
||||
static struct dircache_entry *dircache_root;
|
||||
/* these point to the start and end of the name buffer (d above) */
|
||||
|
@ -86,6 +101,9 @@ static char *dot, *dotdot;
|
|||
static struct dircache_entry *append_position;
|
||||
#endif
|
||||
|
||||
static DIR_CACHED opendirs[MAX_OPEN_DIRS];
|
||||
static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
|
||||
|
||||
static bool dircache_initialized = false;
|
||||
static bool dircache_initializing = false;
|
||||
static bool thread_enabled = false;
|
||||
|
@ -105,6 +123,11 @@ static int fdbind_idx = 0;
|
|||
|
||||
/* --- Internal cache structure control functions --- */
|
||||
|
||||
static inline struct dircache_entry* get_entry(int id)
|
||||
{
|
||||
return &dircache_root[id];
|
||||
}
|
||||
|
||||
#ifdef HAVE_EEPROM_SETTINGS
|
||||
/**
|
||||
* Open the dircache file to save a snapshot on disk
|
||||
|
@ -1012,14 +1035,36 @@ void dircache_disable(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* Usermode function to return dircache_entry pointer to the given path.
|
||||
* Usermode function to return dircache_entry index to the given path.
|
||||
*/
|
||||
const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
|
||||
static int dircache_get_entry_id_ex(const char *filename, bool go_down)
|
||||
{
|
||||
if (!dircache_initialized || filename == NULL)
|
||||
return NULL;
|
||||
return -1;
|
||||
|
||||
return dircache_get_entry(filename, false);
|
||||
struct dircache_entry* res = dircache_get_entry(filename, go_down);
|
||||
return res ? res - dircache_root : -1;
|
||||
}
|
||||
|
||||
int dircache_get_entry_id(const char* filename)
|
||||
{
|
||||
return dircache_get_entry_id_ex(filename, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal: Get the startcluster for the index
|
||||
*/
|
||||
long _dircache_get_entry_startcluster(int id)
|
||||
{
|
||||
return get_entry(id)->startcluster;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal: Get the struct dirinfo for the index
|
||||
*/
|
||||
struct dirinfo* _dircache_get_entry_dirinfo(int id)
|
||||
{
|
||||
return &get_entry(id)->info;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1050,13 +1095,13 @@ static size_t copy_path_helper(const struct dircache_entry *entry, char *buf, si
|
|||
*
|
||||
* Returns the size of the resulting string, or 0 if an error occured
|
||||
*/
|
||||
size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size)
|
||||
size_t dircache_copy_path(int index, char *buf, size_t size)
|
||||
{
|
||||
if (!size || !buf)
|
||||
if (!size || !buf || index < 0)
|
||||
return 0;
|
||||
|
||||
buf[0] = '/';
|
||||
size_t res = copy_path_helper(entry, buf, size);
|
||||
size_t res = copy_path_helper(&dircache_root[index], buf, size);
|
||||
/* fixup trailing '/' */
|
||||
buf[res] = '\0';
|
||||
return res;
|
||||
|
@ -1373,17 +1418,17 @@ DIR_CACHED* opendir_cached(const char* name)
|
|||
|
||||
if (!dircache_initialized || is_disable_msg_pending())
|
||||
{
|
||||
pdir->internal_entry = NULL;
|
||||
pdir->internal_entry = -1;
|
||||
pdir->regulardir = opendir_uncached(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdir->regulardir = NULL;
|
||||
pdir->internal_entry = dircache_get_entry(name, true);
|
||||
pdir->internal_entry = dircache_get_entry_id_ex(name, true);
|
||||
pdir->theent.info.attribute = -1; /* used to make readdir_cached aware of the first call */
|
||||
}
|
||||
|
||||
if (pdir->internal_entry == NULL && pdir->regulardir == NULL)
|
||||
if (pdir->internal_entry == -1 && pdir->regulardir == NULL)
|
||||
{
|
||||
pdir->busy = false;
|
||||
return NULL;
|
||||
|
@ -1394,7 +1439,7 @@ DIR_CACHED* opendir_cached(const char* name)
|
|||
|
||||
struct dirent_cached* readdir_cached(DIR_CACHED* dir)
|
||||
{
|
||||
struct dircache_entry *ce = dir->internal_entry;
|
||||
struct dircache_entry *ce = get_entry(dir->internal_entry);
|
||||
struct dirent_uncached *regentry;
|
||||
|
||||
if (!dir->busy)
|
||||
|
@ -1430,7 +1475,7 @@ struct dirent_cached* readdir_cached(DIR_CACHED* dir)
|
|||
because that modifies the d_name pointer. */
|
||||
dir->theent.startcluster = ce->startcluster;
|
||||
dir->theent.info = ce->info;
|
||||
dir->internal_entry = ce;
|
||||
dir->internal_entry = ce - dircache_root;
|
||||
|
||||
//logf("-> %s", ce->d_name);
|
||||
return &dir->theent;
|
||||
|
|
|
@ -108,25 +108,26 @@ static int open_internal(const char* pathname, int flags, bool use_cache)
|
|||
#ifdef HAVE_DIRCACHE
|
||||
if (dircache_is_enabled() && !file->write && use_cache)
|
||||
{
|
||||
const struct dircache_entry *ce;
|
||||
# ifdef HAVE_MULTIVOLUME
|
||||
int volume = strip_volume(pathname, pathnamecopy);
|
||||
# endif
|
||||
|
||||
ce = dircache_get_entry_ptr(pathname);
|
||||
if (!ce)
|
||||
int ce = dircache_get_entry_id(pathname);
|
||||
if (ce < 0)
|
||||
{
|
||||
errno = ENOENT;
|
||||
file->busy = false;
|
||||
return -7;
|
||||
}
|
||||
|
||||
long startcluster = _dircache_get_entry_startcluster(ce);
|
||||
fat_open(IF_MV2(volume,)
|
||||
ce->startcluster,
|
||||
startcluster,
|
||||
&(file->fatfile),
|
||||
NULL);
|
||||
file->size = ce->info.size;
|
||||
file->attr = ce->info.attribute;
|
||||
struct dirinfo *info = _dircache_get_entry_dirinfo(ce);
|
||||
file->size = info->size;
|
||||
file->attr = info->attribute;
|
||||
file->cacheoffset = -1;
|
||||
file->fileoffset = 0;
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ bool file_exists(const char *file)
|
|||
|
||||
#ifdef HAVE_DIRCACHE
|
||||
if (dircache_is_enabled())
|
||||
return (dircache_get_entry_ptr(file) != NULL);
|
||||
return (dircache_get_entry_id(file) >= 0);
|
||||
#endif
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
|
|
|
@ -47,22 +47,6 @@ struct travel_data {
|
|||
int pathpos;
|
||||
};
|
||||
|
||||
#define MAX_PENDING_BINDINGS 2
|
||||
struct fdbind_queue {
|
||||
char path[MAX_PATH];
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* Exported structures. */
|
||||
struct dircache_entry {
|
||||
struct dirinfo info;
|
||||
struct dircache_entry *next;
|
||||
struct dircache_entry *up;
|
||||
struct dircache_entry *down;
|
||||
long startcluster;
|
||||
char *d_name;
|
||||
};
|
||||
|
||||
struct dirent_cached {
|
||||
struct dirinfo info;
|
||||
char *d_name;
|
||||
|
@ -72,7 +56,7 @@ struct dirent_cached {
|
|||
typedef struct {
|
||||
bool busy;
|
||||
struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */
|
||||
struct dircache_entry *internal_entry; /* the current entry in the directory */
|
||||
int internal_entry; /* the current entry in the directory */
|
||||
DIR_UNCACHED *regulardir;
|
||||
} DIR_CACHED;
|
||||
|
||||
|
@ -90,8 +74,12 @@ int dircache_get_cache_size(void);
|
|||
int dircache_get_reserve_used(void);
|
||||
int dircache_get_build_ticks(void);
|
||||
void dircache_disable(void);
|
||||
const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
|
||||
size_t dircache_copy_path(const struct dircache_entry *entry, char *buf, size_t size);
|
||||
int dircache_get_entry_id(const char *filename);
|
||||
size_t dircache_copy_path(int index, char *buf, size_t size);
|
||||
|
||||
/* the next two are internal for file.c */
|
||||
long _dircache_get_entry_startcluster(int id);
|
||||
struct dirinfo* _dircache_get_entry_dirinfo(int id);
|
||||
|
||||
void dircache_bind(int fd, const char *path);
|
||||
void dircache_update_filesize(int fd, long newsize, long startcluster);
|
||||
|
|
|
@ -148,8 +148,7 @@ extern int _wrmdir(const wchar_t*);
|
|||
|
||||
|
||||
#ifdef HAVE_DIRCACHE
|
||||
struct dircache_entry;
|
||||
const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
|
||||
int dircache_get_entry_id(const char *filename);
|
||||
void dircache_add_file(const char *name, long startcluster);
|
||||
void dircache_remove(const char *name);
|
||||
void dircache_rename(const char *oldname, const char *newname);
|
||||
|
@ -409,7 +408,7 @@ int sim_open(const char *name, int o, ...)
|
|||
mode_t mode = va_arg(ap, unsigned int);
|
||||
ret = OPEN(get_sim_pathname(name), opts, mode);
|
||||
#ifdef HAVE_DIRCACHE
|
||||
if (ret >= 0 && !dircache_get_entry_ptr(name))
|
||||
if (ret >= 0 && (dircache_get_entry_id(name) < 0))
|
||||
dircache_add_file(name, 0);
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
@ -436,7 +435,7 @@ int sim_creat(const char *name, mode_t mode)
|
|||
int ret = OPEN(get_sim_pathname(name),
|
||||
O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||
#ifdef HAVE_DIRCACHE
|
||||
if (ret >= 0 && !dircache_get_entry_ptr(name))
|
||||
if (ret >= 0 && (dircache_get_entry_id(name) < 0))
|
||||
dircache_add_file(name, 0);
|
||||
#endif
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue