diff options
| author | Miika Pekkarinen <miipekk@ihme.org> | 2006-04-10 10:26:24 +0000 |
|---|---|---|
| committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-04-10 10:26:24 +0000 |
| commit | 58fe4dea05f104111e8dfb5063df0d7aba504ea0 (patch) | |
| tree | 72c3613274475f380bc76ccb097b559061a1e617 /apps/tagcache.c | |
| parent | 2caad6fbc112c7b0d8f54383e9406063661aa127 (diff) | |
| download | rockbox-58fe4dea05f104111e8dfb5063df0d7aba504ea0.zip rockbox-58fe4dea05f104111e8dfb5063df0d7aba504ea0.tar.gz rockbox-58fe4dea05f104111e8dfb5063df0d7aba504ea0.tar.bz2 rockbox-58fe4dea05f104111e8dfb5063df0d7aba504ea0.tar.xz | |
Major improvement in playlist creation speed with tagcache. Fixed also
the sorting bug.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9592 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tagcache.c')
| -rw-r--r-- | apps/tagcache.c | 148 |
1 files changed, 111 insertions, 37 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 3a6a78c..b6b12b7 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -52,7 +52,11 @@ static long tempbuf_pos; /* Tags we want to get sorted (loaded to the tempbuf). */ static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, tag_composer, tag_title }; + +/* Uniqued tags (we can use these tags with filters and conditional clauses). */ static const int unique_tags[] = { tag_artist, tag_album, tag_genre, tag_composer }; + +/* Numeric tags (we can use these tags with conditional clauses). */ static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length, tag_bitrate }; /* Queue commands. */ @@ -145,6 +149,32 @@ bool tagcache_is_numeric_tag(int type) return false; } +bool tagcache_is_unique_tag(int type) +{ + int i; + + for (i = 0; i < (int)(sizeof(unique_tags)/sizeof(unique_tags[0])); i++) + { + if (type == unique_tags[i]) + return true; + } + + return false; +} + +bool tagcache_is_sorted_tag(int type) +{ + int i; + + for (i = 0; i < (int)(sizeof(sorted_tags)/sizeof(sorted_tags[0])); i++) + { + if (type == sorted_tags[i]) + return true; + } + + return false; +} + #ifdef HAVE_TC_RAMCACHE static struct index_entry *find_entry_ram(const char *filename, const struct dircache_entry *dc) @@ -324,21 +354,20 @@ static struct index_entry *find_entry_disk(const char *filename, bool retrieve) return &idx; } -long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) +static long tagcache_get_seek(const struct tagcache_search *tcs, + int tag, int idxid) { struct index_entry idx; - if (!tagcache_is_numeric_tag(tag)) - return -1; - #ifdef HAVE_TC_RAMCACHE if (tcs->ramsearch) { - return hdr->indices[tcs->idx_id].tag_seek[tag]; + return hdr->indices[idxid].tag_seek[tag]; } #endif - lseek(tcs->masterfd, tcs->idx_id * sizeof(struct index_entry), SEEK_CUR); + lseek(tcs->masterfd, idxid * sizeof(struct index_entry) + + sizeof(struct tagcache_header), SEEK_SET); if (read(tcs->masterfd, &idx, sizeof(struct index_entry)) != sizeof(struct index_entry)) { @@ -349,6 +378,15 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) return idx.tag_seek[tag]; } +long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) +{ + + if (!tagcache_is_numeric_tag(tag)) + return -1; + + return tagcache_get_seek(tcs, tag, tcs->idx_id); +} + static bool check_against_clause(long numeric, const char *str, const struct tagcache_search_clause *clause) { @@ -520,6 +558,7 @@ static bool build_lookup_list(struct tagcache_search *tcs) return tcs->seek_list_count > 0; } + bool tagcache_search(struct tagcache_search *tcs, int tag) { struct tagcache_header h; @@ -601,6 +640,9 @@ bool tagcache_search_add_filter(struct tagcache_search *tcs, if (tcs->filter_count == TAGCACHE_MAX_FILTERS) return false; + if (!tagcache_is_unique_tag(tag) || tagcache_is_numeric_tag(tag)) + return false; + tcs->filter_tag[tcs->filter_count] = tag; tcs->filter_seek[tcs->filter_count] = seek; tcs->filter_count++; @@ -699,6 +741,9 @@ bool tagcache_get_next(struct tagcache_search *tcs) tcs->result = ep->tag_data; tcs->result_len = ep->tag_length; tcs->idx_id = ep->idx_id; + + if (!tagcache_is_unique_tag(tcs->type)) + tcs->result_seek = tcs->idx_id; return true; } @@ -732,6 +777,61 @@ bool tagcache_get_next(struct tagcache_search *tcs) tcs->result = buf; tcs->result_len = entry.tag_length; tcs->idx_id = entry.idx_id; + if (!tagcache_is_unique_tag(tcs->type)) + tcs->result_seek = tcs->idx_id; + + return true; +} + +bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, + char *buf, long size) +{ + struct tagfile_entry tfe; + long seek; + + seek = tagcache_get_seek(tcs, tcs->type, idxid); + if (seek < 0) + { + logf("Retrieve failed"); + return false; + } + + if (tcs->idxfd[tcs->type] < 0) + { + char fn[MAX_PATH]; + + snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tcs->type); + tcs->idxfd[tcs->type] = open(fn, O_RDONLY); + } + + if (tcs->idxfd[tcs->type] < 0) + { + logf("File not open!"); + return false; + } + + lseek(tcs->idxfd[tcs->type], seek, SEEK_SET); + if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) != + sizeof(struct tagfile_entry)) + { + logf("read error"); + return false; + } + + if (tfe.tag_length >= size) + { + logf("too small buffer"); + return false; + } + + if (read(tcs->idxfd[tcs->type], buf, tfe.tag_length) != + tfe.tag_length) + { + logf("read error #2"); + return false; + } + + buf[tfe.tag_length] = '\0'; return true; } @@ -1154,32 +1254,6 @@ static int tempbuf_find_location(int id) return entry->seek; } -static bool is_unique_tag(int type) -{ - int i; - - for (i = 0; i < (int)(sizeof(unique_tags)/sizeof(unique_tags[0])); i++) - { - if (type == unique_tags[i]) - return true; - } - - return false; -} - -static bool is_sorted_tag(int type) -{ - int i; - - for (i = 0; i < (int)(sizeof(sorted_tags)/sizeof(sorted_tags[0])); i++) - { - if (type == sorted_tags[i]) - return true; - } - - return false; -} - static bool build_numeric_index(int index_type, struct tagcache_header *h, int tmpfd) { struct tagcache_header tch; @@ -1318,7 +1392,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) * it entirely into memory so we can resort it later for use with * chunked browsing. */ - if (is_sorted_tag(index_type)) + if (tagcache_is_sorted_tag(index_type)) { for (i = 0; i < tch.entry_count; i++) { @@ -1445,7 +1519,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) * Load new unique tags in memory to be sorted later and added * to the master lookup file. */ - if (is_sorted_tag(index_type)) + if (tagcache_is_sorted_tag(index_type)) { lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); /* h is the header of the temporary file containing new tags. */ @@ -1478,7 +1552,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) goto error_exit; } - if (is_unique_tag(index_type)) + if (tagcache_is_unique_tag(index_type)) error = !tempbuf_unique_insert(buf, i); else error = !tempbuf_insert(buf, i, tch.entry_count + i); @@ -1563,7 +1637,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) } /* Read entry headers. */ - if (!is_sorted_tag(index_type)) + if (!tagcache_is_sorted_tag(index_type)) { struct temp_file_entry entry; struct tagfile_entry fe; @@ -1634,7 +1708,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) } /* Finally write the uniqued tag index file. */ - if (is_sorted_tag(index_type)) + if (tagcache_is_sorted_tag(index_type)) { tch.magic = TAGCACHE_MAGIC; tch.entry_count = tempbufidx; |