Tagcache update: Support removal of entries and no longer the need for
dircache to load tagcache in ram (however, dircache with tagcache is still strongly recommended). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10192 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
dae39989db
commit
9cd5c3e119
9 changed files with 465 additions and 118 deletions
|
@ -1676,7 +1676,7 @@
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_TAGCACHE
|
id: LANG_TAGCACHE
|
||||||
desc: in tag cache settings
|
desc: in settings menu
|
||||||
user:
|
user:
|
||||||
<source>
|
<source>
|
||||||
*: "Tag Cache"
|
*: "Tag Cache"
|
||||||
|
@ -1690,16 +1690,16 @@
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_TAGCACHE_DISK
|
id: LANG_TAGCACHE_DISK
|
||||||
desc: in tag cache settings
|
desc:
|
||||||
user:
|
user:
|
||||||
<source>
|
<source>
|
||||||
*: "Keep on Disk"
|
*: ""
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: "Keep on Disk"
|
*: ""
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: "Keep on Disk"
|
*: ""
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
@ -1717,17 +1717,17 @@
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_TAGCACHE_FORCE_UPDATE
|
id: LANG_TAGCACHE_INITIALIZE
|
||||||
desc: in tag cache settings
|
desc: in tag cache settings
|
||||||
user:
|
user:
|
||||||
<source>
|
<source>
|
||||||
*: "Force Tag Cache Update"
|
*: "Initialize now"
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: "Force Tag Cache Update"
|
*: "Initialize now"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: "Force Tag Cache Update"
|
*: "Initialize now"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
@ -8529,3 +8529,31 @@
|
||||||
*: "Remote Scrolling Options"
|
*: "Remote Scrolling Options"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_TAGCACHE_UPDATE
|
||||||
|
desc: in tag cache settings
|
||||||
|
user:
|
||||||
|
<source>
|
||||||
|
*: "Update now"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: "Update now"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: "Update now"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_TAGCACHE_AUTOUPDATE
|
||||||
|
desc: in tag cache settings
|
||||||
|
user:
|
||||||
|
<source>
|
||||||
|
*: "Auto update"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: "Auto update"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: "Auto update"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
|
|
@ -94,7 +94,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_BLOCK_VERSION 44
|
#define CONFIG_BLOCK_VERSION 45
|
||||||
#define CONFIG_BLOCK_SIZE 512
|
#define CONFIG_BLOCK_SIZE 512
|
||||||
#define RTC_BLOCK_SIZE 44
|
#define RTC_BLOCK_SIZE 44
|
||||||
|
|
||||||
|
@ -554,8 +554,11 @@ static const struct bit_entry hd_bits[] =
|
||||||
#ifdef HAVE_DIRCACHE
|
#ifdef HAVE_DIRCACHE
|
||||||
{1, S_O(dircache), false, "dircache", off_on },
|
{1, S_O(dircache), false, "dircache", off_on },
|
||||||
{22, S_O(dircache_size), 0, NULL, NULL },
|
{22, S_O(dircache_size), 0, NULL, NULL },
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
{1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
|
{1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
|
||||||
#endif
|
#endif
|
||||||
|
{1, S_O(tagcache_autoupdate), 0, "tagcache_autoupdate", off_on },
|
||||||
|
|
||||||
{4, S_O(default_codepage), 0, "default codepage",
|
{4, S_O(default_codepage), 0, "default codepage",
|
||||||
"iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
|
"iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
|
||||||
|
@ -563,6 +566,7 @@ static const struct bit_entry hd_bits[] =
|
||||||
{1, S_O(warnon_erase_dynplaylist), false,
|
{1, S_O(warnon_erase_dynplaylist), false,
|
||||||
"warn when erasing dynamic playlist", off_on },
|
"warn when erasing dynamic playlist", off_on },
|
||||||
|
|
||||||
|
|
||||||
/* If values are just added to the end, no need to bump the version. */
|
/* If values are just added to the end, no need to bump the version. */
|
||||||
/* new stuff to be added at the end */
|
/* new stuff to be added at the end */
|
||||||
|
|
||||||
|
|
|
@ -1520,18 +1520,51 @@ static bool dircache(void)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_DIRCACHE */
|
||||||
|
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
static bool tagcache_ram(void)
|
static bool tagcache_ram(void)
|
||||||
{
|
{
|
||||||
bool result = set_bool_options(str(LANG_TAGCACHE),
|
bool result = set_bool_options(str(LANG_TAGCACHE_RAM),
|
||||||
&global_settings.tagcache_ram,
|
&global_settings.tagcache_ram,
|
||||||
STR(LANG_TAGCACHE_RAM),
|
STR(LANG_SET_BOOL_YES),
|
||||||
STR(LANG_TAGCACHE_DISK),
|
STR(LANG_SET_BOOL_NO),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DIRCACHE */
|
#endif
|
||||||
|
|
||||||
|
static bool tagcache_autoupdate(void)
|
||||||
|
{
|
||||||
|
bool rc = set_bool_options(str(LANG_TAGCACHE_AUTOUPDATE),
|
||||||
|
&global_settings.tagcache_autoupdate,
|
||||||
|
STR(LANG_ON),
|
||||||
|
STR(LANG_OFF),
|
||||||
|
NULL);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool tagcache_settings_menu(void)
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
static const struct menu_item items[] = {
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
|
{ ID2P(LANG_TAGCACHE_RAM), tagcache_ram },
|
||||||
|
#endif
|
||||||
|
{ ID2P(LANG_TAGCACHE_AUTOUPDATE), tagcache_autoupdate },
|
||||||
|
{ ID2P(LANG_TAGCACHE_INITIALIZE), tagcache_rebuild },
|
||||||
|
{ ID2P(LANG_TAGCACHE_UPDATE), tagcache_update },
|
||||||
|
};
|
||||||
|
|
||||||
|
m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
result = menu_run(m);
|
||||||
|
menu_exit(m);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static bool playback_settings_menu(void)
|
static bool playback_settings_menu(void)
|
||||||
{
|
{
|
||||||
|
@ -1641,10 +1674,7 @@ static bool fileview_settings_menu(void)
|
||||||
{ ID2P(LANG_FILTER), dir_filter },
|
{ ID2P(LANG_FILTER), dir_filter },
|
||||||
{ ID2P(LANG_FOLLOW), browse_current },
|
{ ID2P(LANG_FOLLOW), browse_current },
|
||||||
{ ID2P(LANG_SHOW_ICONS), show_icons },
|
{ ID2P(LANG_SHOW_ICONS), show_icons },
|
||||||
#ifdef HAVE_DIRCACHE
|
{ ID2P(LANG_TAGCACHE), tagcache_settings_menu},
|
||||||
{ ID2P(LANG_TAGCACHE), tagcache_ram },
|
|
||||||
#endif
|
|
||||||
{ ID2P(LANG_TAGCACHE_FORCE_UPDATE), tagcache_force_update },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
|
m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
|
||||||
|
|
460
apps/tagcache.c
460
apps/tagcache.c
|
@ -67,7 +67,8 @@ static struct tagcache_stat stat;
|
||||||
enum tagcache_queue {
|
enum tagcache_queue {
|
||||||
Q_STOP_SCAN = 0,
|
Q_STOP_SCAN = 0,
|
||||||
Q_START_SCAN,
|
Q_START_SCAN,
|
||||||
Q_FORCE_UPDATE,
|
Q_UPDATE,
|
||||||
|
Q_REBUILD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,7 +178,7 @@ bool tagcache_is_sorted_tag(int type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
static struct index_entry *find_entry_ram(const char *filename,
|
static struct index_entry *find_entry_ram(const char *filename,
|
||||||
const struct dircache_entry *dc)
|
const struct dircache_entry *dc)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +273,7 @@ static struct index_entry *find_entry_disk(const char *filename, bool retrieve)
|
||||||
|
|
||||||
if (tfe.tag_length >= (long)sizeof(buf))
|
if (tfe.tag_length >= (long)sizeof(buf))
|
||||||
{
|
{
|
||||||
logf("too long tag");
|
logf("too long tag #1");
|
||||||
close(fd);
|
close(fd);
|
||||||
last_pos = -1;
|
last_pos = -1;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -487,6 +488,8 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
{
|
{
|
||||||
tcs->seek_list[tcs->seek_list_count] =
|
tcs->seek_list[tcs->seek_list_count] =
|
||||||
hdr->indices[i].tag_seek[tcs->type];
|
hdr->indices[i].tag_seek[tcs->type];
|
||||||
|
tcs->seek_flags[tcs->seek_list_count] =
|
||||||
|
hdr->indices[i].flag;
|
||||||
tcs->seek_list_count++;
|
tcs->seek_list_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,6 +506,10 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
while (read(tcs->masterfd, &entry, sizeof(struct index_entry)) ==
|
while (read(tcs->masterfd, &entry, sizeof(struct index_entry)) ==
|
||||||
sizeof(struct index_entry))
|
sizeof(struct index_entry))
|
||||||
{
|
{
|
||||||
|
/* Check if entry has been deleted. */
|
||||||
|
if (entry.flag & FLAG_DELETED)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (tcs->seek_list_count == SEEK_LIST_SIZE)
|
if (tcs->seek_list_count == SEEK_LIST_SIZE)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
@ -538,6 +545,10 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
read(fd, str, tfe.tag_length);
|
read(fd, str, tfe.tag_length);
|
||||||
|
|
||||||
|
/* Check if entry has been deleted. */
|
||||||
|
if (str[0] == '\0')
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_against_clause(seek, str, tcs->clause[i]))
|
if (!check_against_clause(seek, str, tcs->clause[i]))
|
||||||
|
@ -559,6 +570,7 @@ static bool build_lookup_list(struct tagcache_search *tcs)
|
||||||
{
|
{
|
||||||
tcs->seek_list[tcs->seek_list_count] =
|
tcs->seek_list[tcs->seek_list_count] =
|
||||||
entry.tag_seek[tcs->type];
|
entry.tag_seek[tcs->type];
|
||||||
|
tcs->seek_flags[tcs->seek_list_count] = entry.flag;
|
||||||
tcs->seek_list_count++;
|
tcs->seek_list_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,7 +594,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tcs->position = sizeof(struct tagcache_header);
|
tcs->position = sizeof(struct tagcache_header);
|
||||||
tcs->fd = -1;
|
|
||||||
tcs->type = tag;
|
tcs->type = tag;
|
||||||
tcs->seek_pos = 0;
|
tcs->seek_pos = 0;
|
||||||
tcs->seek_list_count = 0;
|
tcs->seek_list_count = 0;
|
||||||
|
@ -608,17 +619,15 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type);
|
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type);
|
||||||
tcs->fd = open(buf, O_RDONLY);
|
tcs->idxfd[tcs->type] = open(buf, O_RDONLY);
|
||||||
if (tcs->fd < 0)
|
if (tcs->idxfd[tcs->type] < 0)
|
||||||
{
|
{
|
||||||
logf("failed to open index");
|
logf("failed to open index");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcs->idxfd[tcs->type] = tcs->fd;
|
|
||||||
|
|
||||||
/* Check the header. */
|
/* Check the header. */
|
||||||
if (read(tcs->fd, &h, sizeof(struct tagcache_header)) !=
|
if (read(tcs->idxfd[tcs->type], &h, sizeof(struct tagcache_header)) !=
|
||||||
sizeof(struct tagcache_header) || h.magic != TAGCACHE_MAGIC)
|
sizeof(struct tagcache_header) || h.magic != TAGCACHE_MAGIC)
|
||||||
{
|
{
|
||||||
logf("incorrect header");
|
logf("incorrect header");
|
||||||
|
@ -685,7 +694,30 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tagcache_get_next(struct tagcache_search *tcs)
|
static bool open_files(struct tagcache_search *tcs)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \
|
||||||
|
? (tcs->seek_flags[tcs->seek_list_count] \
|
||||||
|
& FLAG_DIRCACHE) : 1)
|
||||||
|
|
||||||
|
static bool get_next(struct tagcache_search *tcs)
|
||||||
{
|
{
|
||||||
static char buf[MAX_PATH];
|
static char buf[MAX_PATH];
|
||||||
struct tagfile_entry entry;
|
struct tagfile_entry entry;
|
||||||
|
@ -693,7 +725,7 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
if (!tcs->valid)
|
if (!tcs->valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (tcs->fd < 0 && !tagcache_is_numeric_tag(tcs->type)
|
if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type)
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
&& !tcs->ramsearch
|
&& !tcs->ramsearch
|
||||||
#endif
|
#endif
|
||||||
|
@ -718,15 +750,20 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
tcs->seek_list_count--;
|
tcs->seek_list_count--;
|
||||||
|
|
||||||
/* Seek stream to the correct position and continue to direct fetch. */
|
/* Seek stream to the correct position and continue to direct fetch. */
|
||||||
if (!tcs->ramsearch)
|
if (!tcs->ramsearch || !TAG_FILENAME_RAM(tcs))
|
||||||
lseek(tcs->fd, tcs->seek_list[tcs->seek_list_count], SEEK_SET);
|
{
|
||||||
|
if (!open_files(tcs))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lseek(tcs->idxfd[tcs->type], tcs->seek_list[tcs->seek_list_count], SEEK_SET);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
tcs->position = tcs->seek_list[tcs->seek_list_count];
|
tcs->position = tcs->seek_list[tcs->seek_list_count];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Direct fetch. */
|
/* Direct fetch. */
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
if (tcs->ramsearch)
|
if (tcs->ramsearch && TAG_FILENAME_RAM(tcs))
|
||||||
{
|
{
|
||||||
struct tagfile_entry *ep;
|
struct tagfile_entry *ep;
|
||||||
|
|
||||||
|
@ -738,20 +775,22 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
tcs->entry_count--;
|
tcs->entry_count--;
|
||||||
tcs->result_seek = tcs->position;
|
tcs->result_seek = tcs->position;
|
||||||
|
|
||||||
|
# ifdef HAVE_DIRCACHE
|
||||||
if (tcs->type == tag_filename)
|
if (tcs->type == tag_filename)
|
||||||
{
|
{
|
||||||
dircache_copy_path((struct dircache_entry *)tcs->position,
|
dircache_copy_path((struct dircache_entry *)tcs->position,
|
||||||
buf, sizeof buf);
|
buf, sizeof buf);
|
||||||
tcs->result = buf;
|
tcs->result = buf;
|
||||||
tcs->result_len = strlen(buf) + 1;
|
tcs->result_len = strlen(buf) + 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->position];
|
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][tcs->position];
|
||||||
tcs->position += sizeof(struct tagfile_entry) + ep->tag_length;
|
tcs->position += sizeof(struct tagfile_entry) + ep->tag_length;
|
||||||
tcs->result = ep->tag_data;
|
tcs->result = ep->tag_data;
|
||||||
tcs->result_len = ep->tag_length;
|
tcs->result_len = strlen(tcs->result) + 1;
|
||||||
tcs->idx_id = ep->idx_id;
|
tcs->idx_id = ep->idx_id;
|
||||||
|
|
||||||
if (!tagcache_is_unique_tag(tcs->type))
|
if (!tagcache_is_unique_tag(tcs->type))
|
||||||
|
@ -762,8 +801,11 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
tcs->result_seek = lseek(tcs->fd, 0, SEEK_CUR);
|
if (!open_files(tcs))
|
||||||
if (read(tcs->fd, &entry, sizeof(struct tagfile_entry)) !=
|
return false;
|
||||||
|
|
||||||
|
tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR);
|
||||||
|
if (read(tcs->idxfd[tcs->type], &entry, sizeof(struct tagfile_entry)) !=
|
||||||
sizeof(struct tagfile_entry))
|
sizeof(struct tagfile_entry))
|
||||||
{
|
{
|
||||||
/* End of data. */
|
/* End of data. */
|
||||||
|
@ -775,11 +817,11 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
if (entry.tag_length > (long)sizeof(buf))
|
if (entry.tag_length > (long)sizeof(buf))
|
||||||
{
|
{
|
||||||
tcs->valid = false;
|
tcs->valid = false;
|
||||||
logf("too long tag");
|
logf("too long tag #2");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(tcs->fd, buf, entry.tag_length) != entry.tag_length)
|
if (read(tcs->idxfd[tcs->type], buf, entry.tag_length) != entry.tag_length)
|
||||||
{
|
{
|
||||||
tcs->valid = false;
|
tcs->valid = false;
|
||||||
logf("read error");
|
logf("read error");
|
||||||
|
@ -787,7 +829,7 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
tcs->result = buf;
|
tcs->result = buf;
|
||||||
tcs->result_len = entry.tag_length;
|
tcs->result_len = strlen(tcs->result) + 1;
|
||||||
tcs->idx_id = entry.idx_id;
|
tcs->idx_id = entry.idx_id;
|
||||||
if (!tagcache_is_unique_tag(tcs->type))
|
if (!tagcache_is_unique_tag(tcs->type))
|
||||||
tcs->result_seek = tcs->idx_id;
|
tcs->result_seek = tcs->idx_id;
|
||||||
|
@ -795,6 +837,17 @@ bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tagcache_get_next(struct tagcache_search *tcs)
|
||||||
|
{
|
||||||
|
while (get_next(tcs))
|
||||||
|
{
|
||||||
|
if (tcs->result_len > 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
||||||
char *buf, long size)
|
char *buf, long size)
|
||||||
{
|
{
|
||||||
|
@ -809,38 +862,29 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
if (tcs->ramsearch)
|
if (tcs->ramsearch && TAG_FILENAME_RAM(tcs))
|
||||||
{
|
{
|
||||||
|
struct tagfile_entry *ep;
|
||||||
|
|
||||||
|
# ifdef HAVE_DIRCACHE
|
||||||
if (tcs->type == tag_filename)
|
if (tcs->type == tag_filename)
|
||||||
{
|
{
|
||||||
dircache_copy_path((struct dircache_entry *)seek,
|
dircache_copy_path((struct dircache_entry *)seek,
|
||||||
buf, size);
|
buf, size);
|
||||||
}
|
return true;
|
||||||
else
|
|
||||||
{
|
|
||||||
struct tagfile_entry *ep;
|
|
||||||
|
|
||||||
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][seek];
|
|
||||||
strncpy(buf, ep->tag_data, size-1);
|
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
ep = (struct tagfile_entry *)&hdr->tags[tcs->type][seek];
|
||||||
|
strncpy(buf, ep->tag_data, size-1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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)
|
if (!open_files(tcs))
|
||||||
{
|
|
||||||
logf("File not open!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
lseek(tcs->idxfd[tcs->type], seek, SEEK_SET);
|
lseek(tcs->idxfd[tcs->type], seek, SEEK_SET);
|
||||||
if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) !=
|
if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) !=
|
||||||
|
@ -870,18 +914,6 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
static bool tagcache_delete(const char *filename)
|
|
||||||
{
|
|
||||||
struct index_entry *entry;
|
|
||||||
|
|
||||||
entry = find_entry_disk(filename, true);
|
|
||||||
if (entry == NULL)
|
|
||||||
{
|
|
||||||
logf("not found: %s", filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tagcache_modify(struct tagcache_search *tcs, int type, const char *text)
|
void tagcache_modify(struct tagcache_search *tcs, int type, const char *text)
|
||||||
{
|
{
|
||||||
struct tagentry *entry;
|
struct tagentry *entry;
|
||||||
|
@ -898,7 +930,7 @@ void tagcache_modify(struct tagcache_search *tcs, int type, const char *text)
|
||||||
tcs->seek_list[tcs->seek_list_count];
|
tcs->seek_list[tcs->seek_list_count];
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = find_entry_ram(
|
entry = find_entry_ram();
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -907,13 +939,6 @@ void tagcache_search_finish(struct tagcache_search *tcs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (tcs->fd >= 0)
|
|
||||||
{
|
|
||||||
close(tcs->fd);
|
|
||||||
tcs->fd = -1;
|
|
||||||
tcs->idxfd[tcs->type] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tcs->masterfd >= 0)
|
if (tcs->masterfd >= 0)
|
||||||
{
|
{
|
||||||
close(tcs->masterfd);
|
close(tcs->masterfd);
|
||||||
|
@ -933,7 +958,7 @@ void tagcache_search_finish(struct tagcache_search *tcs)
|
||||||
tcs->valid = false;
|
tcs->valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
static struct tagfile_entry *get_tag(const struct index_entry *entry, int tag)
|
static struct tagfile_entry *get_tag(const struct index_entry *entry, int tag)
|
||||||
{
|
{
|
||||||
return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]];
|
return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]];
|
||||||
|
@ -943,7 +968,7 @@ static long get_tag_numeric(const struct index_entry *entry, int tag)
|
||||||
{
|
{
|
||||||
return entry->tag_seek[tag];
|
return entry->tag_seek[tag];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
|
bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
|
||||||
{
|
{
|
||||||
struct index_entry *entry;
|
struct index_entry *entry;
|
||||||
|
@ -984,7 +1009,7 @@ inline void check_if_empty(char **tag)
|
||||||
|
|
||||||
#define CRC_BUF_LEN 8
|
#define CRC_BUF_LEN 8
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
static void add_tagcache(const char *path, const struct dircache_entry *dc)
|
static void add_tagcache(const char *path, const struct dircache_entry *dc)
|
||||||
#else
|
#else
|
||||||
static void add_tagcache(const char *path)
|
static void add_tagcache(const char *path)
|
||||||
|
@ -1006,8 +1031,8 @@ static void add_tagcache(const char *path)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
/* Check if the file is already cached. */
|
/* Check if the file is already cached. */
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
if (stat.ramcache)
|
if (stat.ramcache && dircache_is_enabled())
|
||||||
{
|
{
|
||||||
if (find_entry_ram(path, dc))
|
if (find_entry_ram(path, dc))
|
||||||
return ;
|
return ;
|
||||||
|
@ -1477,7 +1502,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
|
|
||||||
if (entry.tag_length >= (int)sizeof(buf))
|
if (entry.tag_length >= (int)sizeof(buf))
|
||||||
{
|
{
|
||||||
logf("too long tag");
|
logf("too long tag #3");
|
||||||
close(fd);
|
close(fd);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -1489,6 +1514,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip deleted entries. */
|
||||||
|
if (buf[0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the tag and tag id in the memory buffer. Tag id
|
* Save the tag and tag id in the memory buffer. Tag id
|
||||||
* is saved so we can later reindex the master lookup
|
* is saved so we can later reindex the master lookup
|
||||||
|
@ -1673,6 +1702,18 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
|
|
||||||
for (j = 0; j < idxbuf_pos; j++)
|
for (j = 0; j < idxbuf_pos; j++)
|
||||||
{
|
{
|
||||||
|
if (idxbuf[j].flag & FLAG_DELETED)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
|
||||||
|
idxbuf_pos--;
|
||||||
|
for (k = j; k < idxbuf_pos; k++)
|
||||||
|
idxbuf[k] = idxbuf[k+1];
|
||||||
|
|
||||||
|
j--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
idxbuf[j].tag_seek[index_type] = tempbuf_find_location(
|
idxbuf[j].tag_seek[index_type] = tempbuf_find_location(
|
||||||
idxbuf[j].tag_seek[index_type]/TAGFILE_ENTRY_CHUNK_LENGTH
|
idxbuf[j].tag_seek[index_type]/TAGFILE_ENTRY_CHUNK_LENGTH
|
||||||
+ TAGFILE_MAX_ENTRIES);
|
+ TAGFILE_MAX_ENTRIES);
|
||||||
|
@ -2008,6 +2049,117 @@ static void free_tempbuf(void)
|
||||||
tempbuf_size = 0;
|
tempbuf_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool delete_entry(long idx_id)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int tag, i;
|
||||||
|
struct index_entry idx, myidx;
|
||||||
|
struct tagcache_header hdr;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
int in_use[TAG_COUNT];
|
||||||
|
|
||||||
|
fd = open(TAGCACHE_FILE_MASTER, O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logf("master file open failed for R/W");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the header. */
|
||||||
|
read(fd, &hdr, sizeof(struct tagcache_header));
|
||||||
|
if (hdr.magic != TAGCACHE_MAGIC)
|
||||||
|
{
|
||||||
|
logf("header error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lseek(fd, idx_id * sizeof(struct index_entry), SEEK_CUR);
|
||||||
|
if (read(fd, &myidx, sizeof(struct index_entry))
|
||||||
|
!= sizeof(struct index_entry))
|
||||||
|
{
|
||||||
|
logf("read error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
myidx.flag |= FLAG_DELETED;
|
||||||
|
lseek(fd, -sizeof(struct index_entry), SEEK_CUR);
|
||||||
|
if (write(fd, &myidx, sizeof(struct index_entry))
|
||||||
|
!= sizeof(struct index_entry))
|
||||||
|
{
|
||||||
|
logf("write error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now check which tags are no longer in use (if any) */
|
||||||
|
for (tag = 0; tag < TAG_COUNT; tag++)
|
||||||
|
in_use[tag] = 0;
|
||||||
|
|
||||||
|
lseek(fd, sizeof(struct tagcache_header), SEEK_SET);
|
||||||
|
for (i = 0; i < hdr.entry_count; i++)
|
||||||
|
{
|
||||||
|
if (read(fd, &idx, sizeof(struct index_entry))
|
||||||
|
!= sizeof(struct index_entry))
|
||||||
|
{
|
||||||
|
logf("read error");
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx.flag & FLAG_DELETED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (tag = 0; tag < TAG_COUNT; tag++)
|
||||||
|
{
|
||||||
|
if (tagcache_is_numeric_tag(tag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (idx.tag_seek[tag] == myidx.tag_seek[tag])
|
||||||
|
in_use[tag]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Now delete all tags no longer in use. */
|
||||||
|
for (tag = 0; tag < TAG_COUNT; tag++)
|
||||||
|
{
|
||||||
|
if (tagcache_is_numeric_tag(tag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (in_use[tag])
|
||||||
|
{
|
||||||
|
logf("in use: %d/%d", tag, in_use[tag]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the index file, which contains the tag names. */
|
||||||
|
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
|
||||||
|
fd = open(buf, O_RDWR);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logf("open failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip the header block */
|
||||||
|
lseek(fd, myidx.tag_seek[tag] + sizeof(struct tagfile_entry), SEEK_SET);
|
||||||
|
|
||||||
|
read(fd, buf, 10);
|
||||||
|
buf[10]='\0';
|
||||||
|
logf("TAG:%s", buf);
|
||||||
|
lseek(fd, -10, SEEK_CUR);
|
||||||
|
|
||||||
|
/* Write first data byte in tag as \0 */
|
||||||
|
write(fd, "", 1);
|
||||||
|
|
||||||
|
/* Now tag data has been removed */
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
static bool allocate_tagcache(void)
|
static bool allocate_tagcache(void)
|
||||||
{
|
{
|
||||||
|
@ -2063,12 +2215,13 @@ static bool load_tagcache(void)
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* We really need the dircache for this. */
|
|
||||||
if (!dircache_is_enabled())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
logf("loading tagcache to ram...");
|
logf("loading tagcache to ram...");
|
||||||
|
|
||||||
|
# ifdef HAVE_DIRCACHE
|
||||||
|
while (dircache_is_initializing())
|
||||||
|
sleep(1);
|
||||||
|
# endif
|
||||||
|
|
||||||
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
|
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
|
@ -2151,8 +2304,11 @@ static bool load_tagcache(void)
|
||||||
hdr->entry_count[i] < tch->entry_count;
|
hdr->entry_count[i] < tch->entry_count;
|
||||||
hdr->entry_count[i]++)
|
hdr->entry_count[i]++)
|
||||||
{
|
{
|
||||||
|
long pos;
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
fe = (struct tagfile_entry *)p;
|
fe = (struct tagfile_entry *)p;
|
||||||
|
pos = lseek(fd, 0, SEEK_CUR);
|
||||||
rc = read(fd, fe, sizeof(struct tagfile_entry));
|
rc = read(fd, fe, sizeof(struct tagfile_entry));
|
||||||
if (rc != sizeof(struct tagfile_entry))
|
if (rc != sizeof(struct tagfile_entry))
|
||||||
{
|
{
|
||||||
|
@ -2165,10 +2321,23 @@ static bool load_tagcache(void)
|
||||||
/* We have a special handling for the filename tags. */
|
/* We have a special handling for the filename tags. */
|
||||||
if (i == tag_filename)
|
if (i == tag_filename)
|
||||||
{
|
{
|
||||||
|
# ifdef HAVE_DIRCACHE
|
||||||
const struct dircache_entry *dc;
|
const struct dircache_entry *dc;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// FIXME: This is wrong!
|
||||||
|
// idx = &hdr->indices[hdr->entry_count[i]];
|
||||||
|
idx = &hdr->indices[fe->idx_id];
|
||||||
|
|
||||||
|
/* Check if the entry has already been removed */
|
||||||
|
if (idx->flag & FLAG_DELETED)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (fe->tag_length >= (long)sizeof(buf)-1)
|
if (fe->tag_length >= (long)sizeof(buf)-1)
|
||||||
{
|
{
|
||||||
|
read(fd, buf, 10);
|
||||||
|
buf[10] = '\0';
|
||||||
|
logf("TAG:%s", buf);
|
||||||
logf("too long filename");
|
logf("too long filename");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2182,22 +2351,47 @@ static bool load_tagcache(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc = dircache_get_entry_ptr(buf);
|
# ifdef HAVE_DIRCACHE
|
||||||
if (dc == NULL)
|
if (dircache_is_enabled())
|
||||||
{
|
{
|
||||||
logf("Entry no longer valid.");
|
dc = dircache_get_entry_ptr(buf);
|
||||||
logf("-> %s", buf);
|
if (dc == NULL)
|
||||||
/* FIXME: Properly delete the entry. */
|
{
|
||||||
hdr->indices[hdr->entry_count[i]].flag |= FLAG_DELETED;
|
logf("Entry no longer valid.");
|
||||||
continue ;
|
logf("-> %s", buf);
|
||||||
}
|
idx->flag |= FLAG_DELETED;
|
||||||
|
delete_entry(fe->idx_id);
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
|
||||||
hdr->indices[hdr->entry_count[i]].tag_seek[tag_filename]
|
idx->flag |= FLAG_DIRCACHE;
|
||||||
= (long)dc;
|
idx->tag_seek[tag_filename] = (long)dc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
/* Check if entry has been removed. */
|
||||||
|
if (global_settings.tagcache_autoupdate)
|
||||||
|
{
|
||||||
|
int testfd;
|
||||||
|
|
||||||
|
testfd = open(buf, O_RDONLY);
|
||||||
|
if (testfd < 0)
|
||||||
|
{
|
||||||
|
logf("Entry no longer valid.");
|
||||||
|
logf("-> %s", buf);
|
||||||
|
idx->flag |= FLAG_DELETED;
|
||||||
|
delete_entry((long)idx - (long)hdr->indices);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idx->tag_seek[i] = pos;
|
||||||
|
}
|
||||||
|
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesleft -= sizeof(struct tagfile_entry) + fe->tag_length;
|
bytesleft -= sizeof(struct tagfile_entry) + fe->tag_length;
|
||||||
if (bytesleft < 0)
|
if (bytesleft < 0)
|
||||||
{
|
{
|
||||||
|
@ -2231,7 +2425,59 @@ static bool load_tagcache(void)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* HAVE_TC_RAMCACHE */
|
||||||
|
|
||||||
|
static bool check_deleted_files(void)
|
||||||
|
{
|
||||||
|
int fd, testfd;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
struct tagfile_entry tfe;
|
||||||
|
|
||||||
|
logf("reverse scan...");
|
||||||
|
snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename);
|
||||||
|
fd = open(buf, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logf("%s open fail", buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lseek(fd, sizeof(struct tagcache_header), SEEK_SET);
|
||||||
|
while (read(fd, &tfe, sizeof(struct tagfile_entry))
|
||||||
|
== sizeof(struct tagfile_entry) && queue_empty(&tagcache_queue))
|
||||||
|
{
|
||||||
|
if (tfe.tag_length >= (long)sizeof(buf)-1)
|
||||||
|
{
|
||||||
|
logf("too long tag");
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read(fd, buf, tfe.tag_length) != tfe.tag_length)
|
||||||
|
{
|
||||||
|
logf("read error");
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now check if the file exists. */
|
||||||
|
testfd = open(buf, O_RDONLY);
|
||||||
|
if (testfd < 0)
|
||||||
|
{
|
||||||
|
logf("Entry no longer valid.");
|
||||||
|
logf("-> %s", buf);
|
||||||
|
delete_entry(tfe.idx_id);
|
||||||
|
}
|
||||||
|
close(testfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
logf("done");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool check_dir(const char *dirname)
|
static bool check_dir(const char *dirname)
|
||||||
{
|
{
|
||||||
|
@ -2273,7 +2519,7 @@ static bool check_dir(const char *dirname)
|
||||||
if (entry->attribute & ATTR_DIRECTORY)
|
if (entry->attribute & ATTR_DIRECTORY)
|
||||||
check_dir(curpath);
|
check_dir(curpath);
|
||||||
else
|
else
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
|
||||||
add_tagcache(curpath, dir->internal_entry);
|
add_tagcache(curpath, dir->internal_entry);
|
||||||
#else
|
#else
|
||||||
add_tagcache(curpath);
|
add_tagcache(curpath);
|
||||||
|
@ -2423,25 +2669,41 @@ static void tagcache_thread(void)
|
||||||
check_done = false;
|
check_done = false;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case Q_FORCE_UPDATE:
|
case Q_REBUILD:
|
||||||
//remove_files();
|
remove_files();
|
||||||
build_tagcache();
|
build_tagcache();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_UPDATE:
|
||||||
|
build_tagcache();
|
||||||
|
check_deleted_files();
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
#ifdef HAVE_TC_RAMCACHE
|
|
||||||
case SYS_TIMEOUT:
|
case SYS_TIMEOUT:
|
||||||
if (check_done || !dircache_is_enabled())
|
if (check_done)
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
if (!stat.ramcache && global_settings.tagcache_ram)
|
if (!stat.ramcache && global_settings.tagcache_ram)
|
||||||
|
{
|
||||||
load_ramcache();
|
load_ramcache();
|
||||||
|
if (stat.ramcache)
|
||||||
if (stat.ramcache)
|
build_tagcache();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (global_settings.tagcache_autoupdate)
|
||||||
|
{
|
||||||
build_tagcache();
|
build_tagcache();
|
||||||
|
/* Don't do auto removal without dircache (very slow). */
|
||||||
|
#ifdef HAVE_DIRCACHE
|
||||||
|
if (dircache_is_enabled())
|
||||||
|
check_deleted_files();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
check_done = true;
|
check_done = true;
|
||||||
break ;
|
break ;
|
||||||
#endif
|
|
||||||
|
|
||||||
case Q_STOP_SCAN:
|
case Q_STOP_SCAN:
|
||||||
break ;
|
break ;
|
||||||
|
@ -2470,6 +2732,8 @@ static int get_progress(void)
|
||||||
total_count = dircache_get_entry_count();
|
total_count = dircache_get_entry_count();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TC_RAMCACHE
|
||||||
{
|
{
|
||||||
if (hdr && stat.ramcache)
|
if (hdr && stat.ramcache)
|
||||||
total_count = hdr->h.entry_count;
|
total_count = hdr->h.entry_count;
|
||||||
|
@ -2495,9 +2759,17 @@ void tagcache_start_scan(void)
|
||||||
queue_post(&tagcache_queue, Q_START_SCAN, 0);
|
queue_post(&tagcache_queue, Q_START_SCAN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tagcache_force_update(void)
|
bool tagcache_update(void)
|
||||||
{
|
{
|
||||||
queue_post(&tagcache_queue, Q_FORCE_UPDATE, 0);
|
queue_post(&tagcache_queue, Q_UPDATE, 0);
|
||||||
|
gui_syncsplash(HZ*2, true, str(LANG_TAGCACHE_FORCE_UPDATE_SPLASH));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tagcache_rebuild(void)
|
||||||
|
{
|
||||||
|
queue_post(&tagcache_queue, Q_REBUILD, 0);
|
||||||
gui_syncsplash(HZ*2, true, str(LANG_TAGCACHE_FORCE_UPDATE_SPLASH));
|
gui_syncsplash(HZ*2, true, str(LANG_TAGCACHE_FORCE_UPDATE_SPLASH));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,10 +27,6 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
|
||||||
|
|
||||||
#define TAG_COUNT 10
|
#define TAG_COUNT 10
|
||||||
|
|
||||||
#ifdef HAVE_DIRCACHE
|
|
||||||
#define HAVE_TC_RAMCACHE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allow a little drift to the filename ordering (should not be too high/low). */
|
/* Allow a little drift to the filename ordering (should not be too high/low). */
|
||||||
#define POS_HISTORY_COUNT 4
|
#define POS_HISTORY_COUNT 4
|
||||||
|
|
||||||
|
@ -70,7 +66,8 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
|
||||||
#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd"
|
#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd"
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
#define FLAG_DELETED 0x0001
|
#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
|
||||||
|
#define FLAG_DIRCACHE 0x0002 /* Filename is a dircache pointer */
|
||||||
|
|
||||||
enum clause { clause_none, clause_is, clause_gt, clause_gteq, clause_lt,
|
enum clause { clause_none, clause_is, clause_gt, clause_gteq, clause_lt,
|
||||||
clause_lteq, clause_contains, clause_begins_with, clause_ends_with };
|
clause_lteq, clause_contains, clause_begins_with, clause_ends_with };
|
||||||
|
@ -102,6 +99,7 @@ struct tagcache_search {
|
||||||
int fd, masterfd;
|
int fd, masterfd;
|
||||||
int idxfd[TAG_COUNT];
|
int idxfd[TAG_COUNT];
|
||||||
long seek_list[SEEK_LIST_SIZE];
|
long seek_list[SEEK_LIST_SIZE];
|
||||||
|
long seek_flags[SEEK_LIST_SIZE];
|
||||||
long filter_tag[TAGCACHE_MAX_FILTERS];
|
long filter_tag[TAGCACHE_MAX_FILTERS];
|
||||||
long filter_seek[TAGCACHE_MAX_FILTERS];
|
long filter_seek[TAGCACHE_MAX_FILTERS];
|
||||||
int filter_count;
|
int filter_count;
|
||||||
|
@ -147,6 +145,7 @@ void tagcache_init(void);
|
||||||
bool tagcache_is_initialized(void);
|
bool tagcache_is_initialized(void);
|
||||||
void tagcache_start_scan(void);
|
void tagcache_start_scan(void);
|
||||||
void tagcache_stop_scan(void);
|
void tagcache_stop_scan(void);
|
||||||
bool tagcache_force_update(void);
|
bool tagcache_update(void);
|
||||||
|
bool tagcache_rebuild(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -575,6 +575,7 @@ int tagtree_load(struct tree_context* c)
|
||||||
{
|
{
|
||||||
case root:
|
case root:
|
||||||
count = load_root(c);
|
count = load_root(c);
|
||||||
|
c->dirlevel = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case allsubentries:
|
case allsubentries:
|
||||||
|
|
|
@ -689,6 +689,14 @@ bool dircache_is_enabled(void)
|
||||||
return dircache_initialized;
|
return dircache_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if dircache is being initialized.
|
||||||
|
*/
|
||||||
|
bool dircache_is_initializing(void)
|
||||||
|
{
|
||||||
|
return dircache_initializing;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current number of entries (directories and files) in the cache.
|
* Returns the current number of entries (directories and files) in the cache.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -190,6 +190,10 @@
|
||||||
#define HAVE_DIRCACHE 1
|
#define HAVE_DIRCACHE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Define tagcache in ram for all players (can operate
|
||||||
|
* also without dircache). */
|
||||||
|
#define HAVE_TC_RAMCACHE 1
|
||||||
|
|
||||||
/* define for all cpus from coldfire family */
|
/* define for all cpus from coldfire family */
|
||||||
#if (CONFIG_CPU == MCF5249) || (CONFIG_CPU == MCF5250)
|
#if (CONFIG_CPU == MCF5249) || (CONFIG_CPU == MCF5250)
|
||||||
#define CPU_COLDFIRE
|
#define CPU_COLDFIRE
|
||||||
|
|
|
@ -85,6 +85,7 @@ int dircache_save(const char *path);
|
||||||
int dircache_build(int last_size);
|
int dircache_build(int last_size);
|
||||||
void* dircache_steal_buffer(long *size);
|
void* dircache_steal_buffer(long *size);
|
||||||
bool dircache_is_enabled(void);
|
bool dircache_is_enabled(void);
|
||||||
|
bool dircache_is_initializing(void);
|
||||||
int dircache_get_entry_count(void);
|
int dircache_get_entry_count(void);
|
||||||
int dircache_get_cache_size(void);
|
int dircache_get_cache_size(void);
|
||||||
int dircache_get_reserve_used(void);
|
int dircache_get_reserve_used(void);
|
||||||
|
|
Loading…
Reference in a new issue