Better header checking. Only manually remove incorrect entries. Fixed
a bug and performance issue with find entry from disk by filename. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10291 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b34c8fcaf2
commit
29fa15f521
1 changed files with 95 additions and 92 deletions
183
apps/tagcache.c
183
apps/tagcache.c
|
@ -211,6 +211,37 @@ bool tagcache_is_sorted_tag(int type)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
|
||||
{
|
||||
int fd;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
if (tagcache_is_numeric_tag(tag) || tag < 0 || tag >= TAG_COUNT)
|
||||
return -1;
|
||||
|
||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
|
||||
|
||||
fd = open(buf, write ? O_RDWR : O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
logf("tag file open failed: %d", tag);
|
||||
stat.ready = false;
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Check the header. */
|
||||
read(fd, hdr, sizeof(struct tagcache_header));
|
||||
if (hdr->magic != TAGCACHE_MAGIC)
|
||||
{
|
||||
logf("header error");
|
||||
stat.ready = false;
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||
static long find_entry_ram(const char *filename,
|
||||
const struct dircache_entry *dc)
|
||||
|
@ -266,6 +297,7 @@ static long find_entry_ram(const char *filename,
|
|||
|
||||
static long find_entry_disk(const char *filename)
|
||||
{
|
||||
struct tagcache_header tch;
|
||||
static long last_pos = -1;
|
||||
long pos_history[POS_HISTORY_COUNT];
|
||||
long pos_history_idx = 0;
|
||||
|
@ -276,11 +308,14 @@ static long find_entry_disk(const char *filename)
|
|||
int i;
|
||||
int pos = -1;
|
||||
|
||||
if (!stat.ready)
|
||||
return -2;
|
||||
|
||||
fd = filenametag_fd;
|
||||
if (fd < 0)
|
||||
{
|
||||
last_pos = -1;
|
||||
if ( (fd = open(TAGCACHE_FILE_MASTER, O_RDONLY)) < 0)
|
||||
if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -288,8 +323,6 @@ static long find_entry_disk(const char *filename)
|
|||
|
||||
if (last_pos > 0)
|
||||
lseek(fd, last_pos, SEEK_SET);
|
||||
else
|
||||
lseek(fd, sizeof(struct master_header), SEEK_SET);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -374,6 +407,9 @@ bool tagcache_find_index(struct tagcache_search *tcs, const char *filename)
|
|||
{
|
||||
int idx_id;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
idx_id = find_index(filename);
|
||||
if (idx_id < 0)
|
||||
return false;
|
||||
|
@ -444,6 +480,9 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
|
|||
{
|
||||
struct index_entry idx;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
if (!tagcache_is_numeric_tag(tag))
|
||||
return -1;
|
||||
|
||||
|
@ -672,6 +711,7 @@ static void remove_files(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int open_master_fd(struct master_header *hdr, bool write)
|
||||
{
|
||||
int fd;
|
||||
|
@ -691,7 +731,6 @@ static int open_master_fd(struct master_header *hdr, bool write)
|
|||
logf("header error");
|
||||
stat.ready = false;
|
||||
close(fd);
|
||||
remove_files();
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -702,7 +741,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
|||
{
|
||||
struct tagcache_header tag_hdr;
|
||||
struct master_header master_hdr;
|
||||
char buf[MAX_PATH];
|
||||
int i;
|
||||
|
||||
if (tcs->valid)
|
||||
|
@ -737,21 +775,9 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
|||
if (tagcache_is_numeric_tag(tcs->type))
|
||||
return true;
|
||||
|
||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type);
|
||||
tcs->idxfd[tcs->type] = open(buf, O_RDONLY);
|
||||
tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false);
|
||||
if (tcs->idxfd[tcs->type] < 0)
|
||||
{
|
||||
logf("failed to open index");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the header. */
|
||||
if (read(tcs->idxfd[tcs->type], &tag_hdr, sizeof(struct tagcache_header)) !=
|
||||
sizeof(struct tagcache_header) || tag_hdr.magic != TAGCACHE_MAGIC)
|
||||
{
|
||||
logf("incorrect header");
|
||||
return false;
|
||||
}
|
||||
|
||||
tcs->masterfd = open_master_fd(&master_hdr, false);
|
||||
|
||||
|
@ -829,7 +855,7 @@ static bool get_next(struct tagcache_search *tcs)
|
|||
static char buf[MAX_PATH];
|
||||
struct tagfile_entry entry;
|
||||
|
||||
if (!tcs->valid)
|
||||
if (!tcs->valid || !stat.ready)
|
||||
return false;
|
||||
|
||||
if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type)
|
||||
|
@ -1087,6 +1113,9 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
|
|||
struct index_entry *entry;
|
||||
int idx_id;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
/* Find the corresponding entry in tagcache. */
|
||||
idx_id = find_entry_ram(filename, NULL);
|
||||
if (idx_id < 0 || !stat.ramcache)
|
||||
|
@ -1156,8 +1185,11 @@ static void add_tagcache(const char *path)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (find_entry_disk(path) >= 0)
|
||||
return ;
|
||||
if (filenametag_fd >= 0)
|
||||
{
|
||||
if (find_entry_disk(path) >= 0)
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
|
@ -1563,20 +1595,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
|||
memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **));
|
||||
|
||||
/* Open the index file, which contains the tag names. */
|
||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type);
|
||||
fd = open(buf, O_RDWR);
|
||||
fd = open_tag_fd(&tch, index_type, true);
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
/* Read the header. */
|
||||
if (read(fd, &tch, sizeof(struct tagcache_header)) !=
|
||||
sizeof(struct tagcache_header) || tch.magic != TAGCACHE_MAGIC)
|
||||
{
|
||||
logf("header error");
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* If tag file contains unique tags (sorted index), we will load
|
||||
* it entirely into memory so we can resort it later for use with
|
||||
|
@ -1991,7 +2013,6 @@ static bool commit(void)
|
|||
{
|
||||
logf("incorrect header");
|
||||
close(tmpfd);
|
||||
remove_files();
|
||||
remove(TAGCACHE_FILE_TEMP);
|
||||
return false;
|
||||
}
|
||||
|
@ -2159,6 +2180,9 @@ static bool update_current_serial(long serial)
|
|||
|
||||
long tagcache_increase_serial(void)
|
||||
{
|
||||
if (!stat.ready)
|
||||
return -2;
|
||||
|
||||
if (!update_current_serial(current_serial + 1))
|
||||
return -1;
|
||||
|
||||
|
@ -2174,6 +2198,9 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data)
|
|||
{
|
||||
struct index_entry idx;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
if (!tagcache_is_numeric_tag(tag))
|
||||
return false;
|
||||
|
||||
|
@ -2378,6 +2405,9 @@ bool tagcache_import_changelog(void)
|
|||
char buf[512];
|
||||
int pos = 0;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
||||
if (clfd < 0)
|
||||
{
|
||||
|
@ -2444,6 +2474,9 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
|
|||
int clfd;
|
||||
int i, j;
|
||||
|
||||
if (!stat.ready)
|
||||
return false;
|
||||
|
||||
if (!tagcache_search(tcs, tag_filename))
|
||||
return false;
|
||||
|
||||
|
@ -2621,33 +2654,19 @@ static bool delete_entry(long idx_id)
|
|||
#ifdef HAVE_TC_RAMCACHE
|
||||
static bool allocate_tagcache(void)
|
||||
{
|
||||
int rc, len;
|
||||
int fd;
|
||||
|
||||
hdr = NULL;
|
||||
|
||||
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
logf("no tagcache file found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Load the header. */
|
||||
hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04);
|
||||
memset(hdr, 0, sizeof(struct ramcache_header));
|
||||
len = sizeof(struct master_header);
|
||||
rc = read(fd, &hdr->h, len);
|
||||
close(fd);
|
||||
|
||||
if (hdr->h.tch.magic != TAGCACHE_MAGIC || rc != len)
|
||||
if ( (fd = open_master_fd(&hdr->h, false)) < 0)
|
||||
{
|
||||
logf("incorrect header");
|
||||
remove_files();
|
||||
hdr = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
hdr->indices = (struct index_entry *)(hdr + 1);
|
||||
|
||||
/**
|
||||
|
@ -2734,26 +2753,12 @@ static bool load_tagcache(void)
|
|||
p = (char *)((long)p & ~0x03) + 0x04;
|
||||
hdr->tags[tag] = p;
|
||||
|
||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
|
||||
fd = open(buf, O_RDONLY);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
logf("%s open fail", buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the header. */
|
||||
tch = (struct tagcache_header *)p;
|
||||
rc = read(fd, tch, sizeof(struct tagcache_header));
|
||||
p += rc;
|
||||
if (rc != sizeof(struct tagcache_header) ||
|
||||
tch->magic != TAGCACHE_MAGIC)
|
||||
{
|
||||
logf("incorrect header");
|
||||
close(fd);
|
||||
p += sizeof(struct tagcache_header);
|
||||
|
||||
if ( (fd = open_tag_fd(tch, tag, false)) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (hdr->entry_count[tag] = 0;
|
||||
hdr->entry_count[tag] < tch->entry_count;
|
||||
|
@ -3004,7 +3009,6 @@ static void build_tagcache(void)
|
|||
{
|
||||
struct tagcache_header header;
|
||||
bool ret;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
curpath[0] = '\0';
|
||||
data_size = 0;
|
||||
|
@ -3028,20 +3032,7 @@ static void build_tagcache(void)
|
|||
return ;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename);
|
||||
filenametag_fd = open(buf, O_RDONLY);
|
||||
|
||||
if (filenametag_fd >= 0)
|
||||
{
|
||||
if (read(filenametag_fd, &header, sizeof(struct tagcache_header)) !=
|
||||
sizeof(struct tagcache_header) || header.magic != TAGCACHE_MAGIC)
|
||||
{
|
||||
logf("header error");
|
||||
close(filenametag_fd);
|
||||
filenametag_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
filenametag_fd = open_tag_fd(&header, tag_filename, false);
|
||||
|
||||
cpu_boost(true);
|
||||
|
||||
|
@ -3095,18 +3086,17 @@ static void load_ramcache(void)
|
|||
stat.ramcache = load_tagcache();
|
||||
|
||||
if (!stat.ramcache)
|
||||
{
|
||||
hdr = NULL;
|
||||
remove_files();
|
||||
}
|
||||
|
||||
cpu_boost(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool check_master_fd(void)
|
||||
static bool check_all_headers(void)
|
||||
{
|
||||
struct master_header myhdr;
|
||||
struct tagcache_header tch;
|
||||
int tag;
|
||||
int fd;
|
||||
|
||||
if ( (fd = open_master_fd(&myhdr, false)) < 0)
|
||||
|
@ -3115,6 +3105,17 @@ static bool check_master_fd(void)
|
|||
close(fd);
|
||||
current_serial = myhdr.serial;
|
||||
|
||||
for (tag = 0; tag < TAG_COUNT; tag++)
|
||||
{
|
||||
if (tagcache_is_numeric_tag(tag))
|
||||
continue;
|
||||
|
||||
if ( (fd = open_tag_fd(&tch, tag, false)) < 0)
|
||||
return false;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3137,11 +3138,13 @@ static void tagcache_thread(void)
|
|||
#endif
|
||||
|
||||
cpu_boost(false);
|
||||
|
||||
stat.ready = check_master_fd();
|
||||
|
||||
stat.initialized = true;
|
||||
|
||||
/* Don't delay bootup with the header check but do it on background. */
|
||||
sleep(HZ);
|
||||
stat.ready = check_all_headers();
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
queue_wait_w_tmo(&tagcache_queue, &ev, HZ);
|
||||
|
@ -3163,7 +3166,7 @@ static void tagcache_thread(void)
|
|||
break ;
|
||||
|
||||
case SYS_TIMEOUT:
|
||||
if (check_done)
|
||||
if (check_done || !stat.ready)
|
||||
break ;
|
||||
|
||||
#ifdef HAVE_TC_RAMCACHE
|
||||
|
|
Loading…
Reference in a new issue