tagcache: add a setting for customizing the database path
Add a new setting, database path: /path/to/folder to change where the database files are stored, which allows it to be shared by multiple builds when using multiboot. This avoids the need to maintain a separate copy of the database for each build. This setting can only be set from the config file; it has no menu option yet (due to lack of a GUI to pick the directory). Change-Id: Ide7b3ccdd84abb62b52f900421bd3d101773e093
This commit is contained in:
parent
f033fd390e
commit
8f582c90de
4 changed files with 71 additions and 32 deletions
|
@ -585,6 +585,7 @@ struct user_settings
|
||||||
unsigned char autoresume_paths[MAX_PATHNAME+1]; /* colon-separated list */
|
unsigned char autoresume_paths[MAX_PATHNAME+1]; /* colon-separated list */
|
||||||
bool runtimedb; /* runtime database active? */
|
bool runtimedb; /* runtime database active? */
|
||||||
unsigned char tagcache_scan_paths[MAX_PATHNAME+1];
|
unsigned char tagcache_scan_paths[MAX_PATHNAME+1];
|
||||||
|
unsigned char tagcache_db_path[MAX_PATHNAME+1];
|
||||||
#endif /* HAVE_TAGCACHE */
|
#endif /* HAVE_TAGCACHE */
|
||||||
|
|
||||||
#if LCD_DEPTH > 1
|
#if LCD_DEPTH > 1
|
||||||
|
|
|
@ -1544,6 +1544,8 @@ const struct settings_list settings[] = {
|
||||||
"gather runtime data", NULL),
|
"gather runtime data", NULL),
|
||||||
TEXT_SETTING(0, tagcache_scan_paths, "database scan paths",
|
TEXT_SETTING(0, tagcache_scan_paths, "database scan paths",
|
||||||
DEFAULT_TAGCACHE_SCAN_PATHS, NULL, NULL),
|
DEFAULT_TAGCACHE_SCAN_PATHS, NULL, NULL),
|
||||||
|
TEXT_SETTING(0, tagcache_db_path, "database path",
|
||||||
|
ROCKBOX_DIR, NULL, NULL),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* replay gain */
|
/* replay gain */
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "structec.h"
|
#include "structec.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "dircache.h"
|
#include "dircache.h"
|
||||||
|
#include "errno.h"
|
||||||
|
|
||||||
#ifndef __PCTOOL__
|
#ifndef __PCTOOL__
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -124,19 +125,19 @@
|
||||||
#define TAGCACHE_COMMAND_QUEUE_COMMIT_DELAY HZ*2
|
#define TAGCACHE_COMMAND_QUEUE_COMMIT_DELAY HZ*2
|
||||||
|
|
||||||
/* Temporary database containing new tags to be committed to the main db. */
|
/* Temporary database containing new tags to be committed to the main db. */
|
||||||
#define TAGCACHE_FILE_TEMP ROCKBOX_DIR "/database_tmp.tcd"
|
#define TAGCACHE_FILE_TEMP "database_tmp.tcd"
|
||||||
|
|
||||||
/* The main database master index and numeric data. */
|
/* The main database master index and numeric data. */
|
||||||
#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/database_idx.tcd"
|
#define TAGCACHE_FILE_MASTER "database_idx.tcd"
|
||||||
|
|
||||||
/* The main database string data. */
|
/* The main database string data. */
|
||||||
#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/database_%d.tcd"
|
#define TAGCACHE_FILE_INDEX "database_%d.tcd"
|
||||||
|
|
||||||
/* ASCII dumpfile of the DB contents. */
|
/* ASCII dumpfile of the DB contents. */
|
||||||
#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/database_changelog.txt"
|
#define TAGCACHE_FILE_CHANGELOG "database_changelog.txt"
|
||||||
|
|
||||||
/* Serialized DB. */
|
/* Serialized DB. */
|
||||||
#define TAGCACHE_STATEFILE ROCKBOX_DIR "/database_state.tcd"
|
#define TAGCACHE_STATEFILE "database_state.tcd"
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
|
#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
|
||||||
|
@ -474,6 +475,33 @@ static ssize_t ecwrite_index_entry(int fd, struct index_entry *buf)
|
||||||
return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ);
|
return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* open_db_fd and remove_db_file are noinline to minimize stack usage
|
||||||
|
*/
|
||||||
|
static int NO_INLINE open_db_fd(const char* filename, int mode)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if(mode & O_CREAT)
|
||||||
|
{
|
||||||
|
if (mkdir(global_settings.tagcache_db_path) < 0 && errno != EEXIST)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return open_pathfmt(buf, sizeof(buf), mode, "%s/%s",
|
||||||
|
global_settings.tagcache_db_path, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int NO_INLINE remove_db_file(const char* filename)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s/%s",
|
||||||
|
global_settings.tagcache_db_path, filename);
|
||||||
|
|
||||||
|
return remove(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
|
static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -484,8 +512,8 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fd = open_pathfmt(fname, sizeof(fname),
|
fd = open_pathfmt(fname, sizeof(fname),
|
||||||
write ? O_RDWR : O_RDONLY, TAGCACHE_FILE_INDEX, tag);
|
write ? O_RDWR : O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
|
||||||
|
global_settings.tagcache_db_path, tag);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf("tag file open failed: tag=%d write=%d file= " TAGCACHE_FILE_INDEX,
|
logf("tag file open failed: tag=%d write=%d file= " TAGCACHE_FILE_INDEX,
|
||||||
|
@ -512,7 +540,7 @@ static int open_master_fd(struct master_header *hdr, bool write)
|
||||||
int fd;
|
int fd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
fd = open(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY);
|
fd = open_db_fd(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf("master file open failed for R/W");
|
logf("master file open failed for R/W");
|
||||||
|
@ -862,7 +890,8 @@ static bool open_files(struct tagcache_search *tcs, int tag)
|
||||||
{
|
{
|
||||||
char fname[MAX_PATH];
|
char fname[MAX_PATH];
|
||||||
tcs->idxfd[tag] = open_pathfmt(fname, sizeof(fname),
|
tcs->idxfd[tag] = open_pathfmt(fname, sizeof(fname),
|
||||||
O_RDONLY, TAGCACHE_FILE_INDEX, tag);
|
O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
|
||||||
|
global_settings.tagcache_db_path, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcs->idxfd[tag] < 0)
|
if (tcs->idxfd[tag] < 0)
|
||||||
|
@ -1480,13 +1509,14 @@ static void remove_files(void)
|
||||||
tc_stat.ready = false;
|
tc_stat.ready = false;
|
||||||
tc_stat.ramcache = false;
|
tc_stat.ramcache = false;
|
||||||
tc_stat.econ = false;
|
tc_stat.econ = false;
|
||||||
remove(TAGCACHE_FILE_MASTER);
|
remove_db_file(TAGCACHE_FILE_MASTER);
|
||||||
for (i = 0; i < TAG_COUNT; i++)
|
for (i = 0; i < TAG_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (TAGCACHE_IS_NUMERIC(i))
|
if (TAGCACHE_IS_NUMERIC(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, i);
|
snprintf(buf, bufsz, "%s/" TAGCACHE_FILE_INDEX,
|
||||||
|
global_settings.tagcache_db_path, i);
|
||||||
remove(buf);
|
remove(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1645,7 +1675,8 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
|
||||||
{
|
{
|
||||||
char fname[MAX_PATH];
|
char fname[MAX_PATH];
|
||||||
tcs->idxfd[clause->tag] = open_pathfmt(fname, sizeof(fname), O_RDONLY,
|
tcs->idxfd[clause->tag] = open_pathfmt(fname, sizeof(fname), O_RDONLY,
|
||||||
TAGCACHE_FILE_INDEX, clause->tag);
|
"%s/" TAGCACHE_FILE_INDEX,
|
||||||
|
global_settings.tagcache_db_path, clause->tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2793,9 +2824,13 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
/**
|
/**
|
||||||
* Creating new index file to store the tags. No need to preload
|
* Creating new index file to store the tags. No need to preload
|
||||||
* anything whether the index type is sorted or not.
|
* anything whether the index type is sorted or not.
|
||||||
|
*
|
||||||
|
* Note: although we are creating a file under the db path, it must
|
||||||
|
* already exist by this point so no mkdir is required.
|
||||||
*/
|
*/
|
||||||
fd = open_pathfmt(buf, bufsz, O_WRONLY | O_CREAT | O_TRUNC,
|
fd = open_pathfmt(buf, bufsz, O_WRONLY | O_CREAT | O_TRUNC,
|
||||||
TAGCACHE_FILE_INDEX, index_type);
|
"%s/" TAGCACHE_FILE_INDEX,
|
||||||
|
global_settings.tagcache_db_path, index_type);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf(TAGCACHE_FILE_INDEX " open fail", index_type);
|
logf(TAGCACHE_FILE_INDEX " open fail", index_type);
|
||||||
|
@ -2817,12 +2852,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
|
||||||
|
|
||||||
/* Loading the tag lookup file as "master file". */
|
/* Loading the tag lookup file as "master file". */
|
||||||
logf("Loading index file");
|
logf("Loading index file");
|
||||||
masterfd = open(TAGCACHE_FILE_MASTER, O_RDWR);
|
masterfd = open_db_fd(TAGCACHE_FILE_MASTER, O_RDWR);
|
||||||
|
|
||||||
if (masterfd < 0)
|
if (masterfd < 0)
|
||||||
{
|
{
|
||||||
logf("Creating new DB");
|
logf("Creating new DB");
|
||||||
masterfd = open(TAGCACHE_FILE_MASTER, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
masterfd = open_db_fd(TAGCACHE_FILE_MASTER, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
|
||||||
if (masterfd < 0)
|
if (masterfd < 0)
|
||||||
{
|
{
|
||||||
|
@ -3149,7 +3184,7 @@ static bool commit(void)
|
||||||
while (write_lock)
|
while (write_lock)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY);
|
tmpfd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDONLY);
|
||||||
if (tmpfd < 0)
|
if (tmpfd < 0)
|
||||||
{
|
{
|
||||||
logf("nothing to commit");
|
logf("nothing to commit");
|
||||||
|
@ -3165,7 +3200,7 @@ static bool commit(void)
|
||||||
{
|
{
|
||||||
logf("incorrect tmpheader");
|
logf("incorrect tmpheader");
|
||||||
close(tmpfd);
|
close(tmpfd);
|
||||||
remove(TAGCACHE_FILE_TEMP);
|
remove_db_file(TAGCACHE_FILE_TEMP);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3176,7 +3211,7 @@ static bool commit(void)
|
||||||
tc_stat.ready = check_all_headers();
|
tc_stat.ready = check_all_headers();
|
||||||
|
|
||||||
#ifdef HAVE_EEPROM_SETTINGS
|
#ifdef HAVE_EEPROM_SETTINGS
|
||||||
remove(TAGCACHE_STATEFILE);
|
remove_db_file(TAGCACHE_STATEFILE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* At first be sure to unload the ramcache! */
|
/* At first be sure to unload the ramcache! */
|
||||||
|
@ -3268,7 +3303,7 @@ static bool commit(void)
|
||||||
if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
|
if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
|
||||||
goto commit_error;
|
goto commit_error;
|
||||||
|
|
||||||
remove(TAGCACHE_FILE_TEMP);
|
remove_db_file(TAGCACHE_FILE_TEMP);
|
||||||
|
|
||||||
tcmh.tch.entry_count += tch.entry_count;
|
tcmh.tch.entry_count += tch.entry_count;
|
||||||
tcmh.tch.datasize = sizeof(struct master_header)
|
tcmh.tch.datasize = sizeof(struct master_header)
|
||||||
|
@ -3681,7 +3716,7 @@ bool tagcache_import_changelog(void)
|
||||||
while (read_lock)
|
while (read_lock)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
clfd = open_db_fd(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
|
||||||
if (clfd < 0)
|
if (clfd < 0)
|
||||||
{
|
{
|
||||||
logf("failure to open changelog");
|
logf("failure to open changelog");
|
||||||
|
@ -3736,7 +3771,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Initialize the changelog */
|
/* Initialize the changelog */
|
||||||
clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
clfd = open_db_fd(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
if (clfd < 0)
|
if (clfd < 0)
|
||||||
{
|
{
|
||||||
logf("failure to open changelog");
|
logf("failure to open changelog");
|
||||||
|
@ -4104,7 +4139,7 @@ static bool tagcache_dumpload(void)
|
||||||
tcramcache.handle = 0;
|
tcramcache.handle = 0;
|
||||||
tcramcache.hdr = NULL;
|
tcramcache.hdr = NULL;
|
||||||
|
|
||||||
fd = open(TAGCACHE_STATEFILE, O_RDONLY);
|
fd = open_db_fd(TAGCACHE_STATEFILE, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf("no tagcache statedump");
|
logf("no tagcache statedump");
|
||||||
|
@ -4164,7 +4199,7 @@ static bool tagcache_dumpsave(void)
|
||||||
if (!tc_stat.ramcache)
|
if (!tc_stat.ramcache)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
fd = open_db_fd(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf("failed to create a statedump");
|
logf("failed to create a statedump");
|
||||||
|
@ -4208,7 +4243,7 @@ static bool load_tagcache(void)
|
||||||
|
|
||||||
tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */
|
tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */
|
||||||
|
|
||||||
fd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
|
fd = open_db_fd(TAGCACHE_FILE_MASTER, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf("tagcache open failed");
|
logf("tagcache open failed");
|
||||||
|
@ -4451,8 +4486,8 @@ static bool check_deleted_files(void)
|
||||||
struct tagfile_entry tfe;
|
struct tagfile_entry tfe;
|
||||||
|
|
||||||
logf("reverse scan...");
|
logf("reverse scan...");
|
||||||
|
fd = open_pathfmt(buf, bufsz, O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
|
||||||
fd = open_pathfmt(buf, bufsz, O_RDONLY, TAGCACHE_FILE_INDEX, tag_filename);
|
global_settings.tagcache_db_path, tag_filename);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
logf(TAGCACHE_FILE_INDEX " open fail", tag_filename);
|
logf(TAGCACHE_FILE_INDEX " open fail", tag_filename);
|
||||||
|
@ -4735,7 +4770,7 @@ void do_tagcache_build(const char *path[])
|
||||||
|
|
||||||
logf("updating tagcache");
|
logf("updating tagcache");
|
||||||
|
|
||||||
cachefd = open(TAGCACHE_FILE_TEMP, O_RDONLY);
|
cachefd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDONLY);
|
||||||
if (cachefd >= 0)
|
if (cachefd >= 0)
|
||||||
{
|
{
|
||||||
logf("skipping, cache already waiting for commit");
|
logf("skipping, cache already waiting for commit");
|
||||||
|
@ -4743,7 +4778,7 @@ void do_tagcache_build(const char *path[])
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
cachefd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC);
|
||||||
if (cachefd < 0)
|
if (cachefd < 0)
|
||||||
{
|
{
|
||||||
logf("master file open failed: %s", TAGCACHE_FILE_TEMP);
|
logf("master file open failed: %s", TAGCACHE_FILE_TEMP);
|
||||||
|
@ -4872,7 +4907,7 @@ void tagcache_unload_ramcache(void)
|
||||||
{
|
{
|
||||||
tc_stat.ramcache = false;
|
tc_stat.ramcache = false;
|
||||||
/* Just to make sure there is no statefile present. */
|
/* Just to make sure there is no statefile present. */
|
||||||
// remove(TAGCACHE_STATEFILE);
|
// remove_db_file(TAGCACHE_STATEFILE);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TC_RAMCACHE */
|
#endif /* HAVE_TC_RAMCACHE */
|
||||||
|
|
||||||
|
@ -4897,7 +4932,7 @@ static void tagcache_thread(void)
|
||||||
check_done = tagcache_dumpload();
|
check_done = tagcache_dumpload();
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(TAGCACHE_STATEFILE);
|
remove_db_file(TAGCACHE_STATEFILE);
|
||||||
#endif /* HAVE_EEPROM_SETTINGS */
|
#endif /* HAVE_EEPROM_SETTINGS */
|
||||||
|
|
||||||
/* Allocate space for the tagcache if found on disk. */
|
/* Allocate space for the tagcache if found on disk. */
|
||||||
|
@ -4930,7 +4965,7 @@ static void tagcache_thread(void)
|
||||||
|
|
||||||
case Q_REBUILD:
|
case Q_REBUILD:
|
||||||
remove_files();
|
remove_files();
|
||||||
remove(TAGCACHE_FILE_TEMP);
|
remove_db_file(TAGCACHE_FILE_TEMP);
|
||||||
tagcache_build();
|
tagcache_build();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -5014,7 +5049,7 @@ void tagcache_shutdown(void)
|
||||||
|
|
||||||
void tagcache_remove_statefile(void)
|
void tagcache_remove_statefile(void)
|
||||||
{
|
{
|
||||||
remove(TAGCACHE_STATEFILE);
|
remove_db_file(TAGCACHE_STATEFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_progress(void)
|
static int get_progress(void)
|
||||||
|
|
|
@ -250,6 +250,7 @@
|
||||||
keyclick repeats & on, off & N/A\\
|
keyclick repeats & on, off & N/A\\
|
||||||
dircache & on, off & N/A\\
|
dircache & on, off & N/A\\
|
||||||
tagcache\_ram & on, off & N/A\\
|
tagcache\_ram & on, off & N/A\\
|
||||||
|
database path & path to a directory & N/A\\
|
||||||
|
|
||||||
\opt{touchpad}{
|
\opt{touchpad}{
|
||||||
\opt{GIGABEAT_PAD}{
|
\opt{GIGABEAT_PAD}{
|
||||||
|
|
Loading…
Reference in a new issue