summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playlist.c160
-rw-r--r--apps/playlist.h4
-rw-r--r--apps/tagcache.c150
-rw-r--r--firmware/export/config.h2
4 files changed, 171 insertions, 145 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 015e41ae0e..176cfc3af7 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -106,8 +106,9 @@
106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */ 106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */
107#include "panic.h" 107#include "panic.h"
108#include "logdiskf.h" 108#include "logdiskf.h"
109 109#ifdef HAVE_DIRCACHE
110#undef HAVE_DIRCACHE 110#include "dircache.h"
111#endif
111 112
112#define PLAYLIST_CONTROL_FILE_VERSION 2 113#define PLAYLIST_CONTROL_FILE_VERSION 2
113 114
@@ -205,6 +206,25 @@ static const char playlist_thread_name[] = "playlist cachectrl";
205static struct mutex current_playlist_mutex SHAREDBSS_ATTR; 206static struct mutex current_playlist_mutex SHAREDBSS_ATTR;
206static struct mutex created_playlist_mutex SHAREDBSS_ATTR; 207static struct mutex created_playlist_mutex SHAREDBSS_ATTR;
207 208
209#ifdef HAVE_DIRCACHE
210static void copy_filerefs(struct dircache_fileref *dcfto,
211 const struct dircache_fileref *dcffrom,
212 int count)
213{
214 if (!dcfto)
215 return;
216
217 if (dcffrom)
218 memmove(dcfto, dcffrom, count * sizeof (*dcfto));
219 else
220 {
221 /* just initialize the destination */
222 for (int i = 0; i < count; i++, dcfto++)
223 dircache_fileref_init(dcfto);
224 }
225}
226#endif /* HAVE_DIRCACHE */
227
208/* Check if the filename suggests M3U or M3U8 format. */ 228/* Check if the filename suggests M3U or M3U8 format. */
209static bool is_m3u8(const char* filename) 229static bool is_m3u8(const char* filename)
210{ 230{
@@ -401,6 +421,8 @@ static int recreate_control(struct playlist_info* playlist)
401 int i; 421 int i;
402 int result = 0; 422 int result = 0;
403 423
424 temp_file[0] = 0;
425
404 if(playlist->control_fd >= 0) 426 if(playlist->control_fd >= 0)
405 { 427 {
406 char* dir = playlist->filename; 428 char* dir = playlist->filename;
@@ -408,6 +430,7 @@ static int recreate_control(struct playlist_info* playlist)
408 char c = playlist->filename[playlist->dirlen-1]; 430 char c = playlist->filename[playlist->dirlen-1];
409 431
410 close(playlist->control_fd); 432 close(playlist->control_fd);
433 playlist->control_fd = 0;
411 434
412 snprintf(temp_file, sizeof(temp_file), "%s_temp", 435 snprintf(temp_file, sizeof(temp_file), "%s_temp",
413 playlist->control_filename); 436 playlist->control_filename);
@@ -571,10 +594,9 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
571 594
572 /* Store a new entry */ 595 /* Store a new entry */
573 playlist->indices[ playlist->amount ] = i+count; 596 playlist->indices[ playlist->amount ] = i+count;
574#ifdef HAVE_DIRCACHE 597 #ifdef HAVE_DIRCACHE
575 if (playlist->filenames) 598 copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1);
576 playlist->filenames[ playlist->amount ] = -1; 599 #endif
577#endif
578 playlist->amount++; 600 playlist->amount++;
579 } 601 }
580 } 602 }
@@ -779,8 +801,8 @@ static int add_track_to_playlist(struct playlist_info* playlist,
779 { 801 {
780 playlist->indices[i] = playlist->indices[i-1]; 802 playlist->indices[i] = playlist->indices[i-1];
781#ifdef HAVE_DIRCACHE 803#ifdef HAVE_DIRCACHE
782 if (playlist->filenames) 804 if (playlist->dcfrefs)
783 playlist->filenames[i] = playlist->filenames[i-1]; 805 playlist->dcfrefs[i] = playlist->dcfrefs[i-1];
784#endif 806#endif
785 } 807 }
786 808
@@ -814,8 +836,7 @@ static int add_track_to_playlist(struct playlist_info* playlist,
814 playlist->indices[insert_position] = flags | seek_pos; 836 playlist->indices[insert_position] = flags | seek_pos;
815 837
816#ifdef HAVE_DIRCACHE 838#ifdef HAVE_DIRCACHE
817 if (playlist->filenames) 839 copy_filerefs(&playlist->dcfrefs[insert_position], NULL, 1);
818 playlist->filenames[insert_position] = -1;
819#endif 840#endif
820 841
821 playlist->amount++; 842 playlist->amount++;
@@ -886,8 +907,8 @@ static int remove_track_from_playlist(struct playlist_info* playlist,
886 { 907 {
887 playlist->indices[i] = playlist->indices[i+1]; 908 playlist->indices[i] = playlist->indices[i+1];
888#ifdef HAVE_DIRCACHE 909#ifdef HAVE_DIRCACHE
889 if (playlist->filenames) 910 if (playlist->dcfrefs)
890 playlist->filenames[i] = playlist->filenames[i+1]; 911 playlist->dcfrefs[i] = playlist->dcfrefs[i+1];
891#endif 912#endif
892 } 913 }
893 914
@@ -934,7 +955,6 @@ static int randomise_playlist(struct playlist_info* playlist,
934{ 955{
935 int count; 956 int count;
936 int candidate; 957 int candidate;
937 long store;
938 unsigned int current = playlist->indices[playlist->index]; 958 unsigned int current = playlist->indices[playlist->index];
939 959
940 /* seed 0 is used to identify sorted playlist for resume purposes */ 960 /* seed 0 is used to identify sorted playlist for resume purposes */
@@ -951,15 +971,15 @@ static int randomise_playlist(struct playlist_info* playlist,
951 candidate = rand() % (count + 1); 971 candidate = rand() % (count + 1);
952 972
953 /* now swap the values at the 'count' and 'candidate' positions */ 973 /* now swap the values at the 'count' and 'candidate' positions */
954 store = playlist->indices[candidate]; 974 int indextmp = playlist->indices[candidate];
955 playlist->indices[candidate] = playlist->indices[count]; 975 playlist->indices[candidate] = playlist->indices[count];
956 playlist->indices[count] = store; 976 playlist->indices[count] = indextmp;
957#ifdef HAVE_DIRCACHE 977#ifdef HAVE_DIRCACHE
958 if (playlist->filenames) 978 if (playlist->dcfrefs)
959 { 979 {
960 store = playlist->filenames[candidate]; 980 struct dircache_fileref dcftmp = playlist->dcfrefs[candidate];
961 playlist->filenames[candidate] = playlist->filenames[count]; 981 playlist->dcfrefs[candidate] = playlist->dcfrefs[count];
962 playlist->filenames[count] = store; 982 playlist->dcfrefs[count] = dcftmp;
963 } 983 }
964#endif 984#endif
965 } 985 }
@@ -1001,7 +1021,7 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
1001 /** We need to re-check the song names from disk because qsort can't 1021 /** We need to re-check the song names from disk because qsort can't
1002 * sort two arrays at once :/ 1022 * sort two arrays at once :/
1003 * FIXME: Please implement a better way to do this. */ 1023 * FIXME: Please implement a better way to do this. */
1004 memset((void*)playlist->filenames, 0xff, playlist->max_playlist_size * sizeof(int)); 1024 copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size);
1005 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0); 1025 queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
1006#endif 1026#endif
1007 1027
@@ -1245,11 +1265,6 @@ static void playlist_flush_callback(void)
1245 } 1265 }
1246} 1266}
1247 1267
1248static bool is_dircache_pointers_intact(void)
1249{
1250 return dircache_get_appflag(DIRCACHE_APPFLAG_PLAYLIST) ? true : false;
1251}
1252
1253static void playlist_thread(void) 1268static void playlist_thread(void)
1254{ 1269{
1255 struct queue_event ev; 1270 struct queue_event ev;
@@ -1290,24 +1305,26 @@ static void playlist_thread(void)
1290 register_storage_idle_func(playlist_flush_callback); 1305 register_storage_idle_func(playlist_flush_callback);
1291 } 1306 }
1292 1307
1293 if (!dircache_is_enabled() || !playlist->filenames 1308 if (!playlist->dcfrefs || playlist->amount <= 0)
1294 || playlist->amount <= 0)
1295 {
1296 break ; 1309 break ;
1297 }
1298 1310
1299 /* Check if previously loaded pointers are intact. */ 1311 /* Check if previously loaded pointers are intact. */
1300 if (is_dircache_pointers_intact() && !dirty_pointers) 1312 if (!dirty_pointers)
1301 break ; 1313 break ;
1302 1314
1303#ifdef HAVE_ADJUSTABLE_CPU_FREQ 1315 struct dircache_info info;
1304 cpu_boost(true); 1316 dircache_get_info(&info);
1305#endif 1317
1318 if (info.status != DIRCACHE_READY)
1319 break ;
1320
1321 trigger_cpu_boost();
1322
1306 for (index = 0; index < playlist->amount 1323 for (index = 0; index < playlist->amount
1307 && queue_empty(&playlist_queue); index++) 1324 && queue_empty(&playlist_queue); index++)
1308 { 1325 {
1309 /* Process only pointers that are not already loaded. */ 1326 /* Process only pointers that are superficially stale. */
1310 if (is_dircache_pointers_intact() && playlist->filenames[index] >= 0) 1327 if (dircache_search(DCS_FILEREF, &playlist->dcfrefs[index], NULL) == 0)
1311 continue ; 1328 continue ;
1312 1329
1313 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; 1330 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
@@ -1320,19 +1337,16 @@ static void playlist_thread(void)
1320 break ; 1337 break ;
1321 } 1338 }
1322 1339
1323 /* Set the dircache entry pointer. */ 1340 /* Obtain the dircache file entry cookie. */
1324 playlist->filenames[index] = dircache_get_entry_id(tmp); 1341 dircache_search(DCS_CACHED_PATH | DCS_UPDATE_FILEREF,
1342 &playlist->dcfrefs[index], tmp);
1325 1343
1326 /* And be on background so user doesn't notice any delays. */ 1344 /* And be on background so user doesn't notice any delays. */
1327 yield(); 1345 yield();
1328 } 1346 }
1329 1347
1330 if (dircache_is_enabled()) 1348 cancel_cpu_boost();
1331 dircache_set_appflag(DIRCACHE_APPFLAG_PLAYLIST); 1349
1332
1333#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1334 cpu_boost(false);
1335#endif
1336 if (index == playlist->amount) 1350 if (index == playlist->amount)
1337 dirty_pointers = false; 1351 dirty_pointers = false;
1338 1352
@@ -1364,17 +1378,12 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1364 buf_length = MAX_PATH+1; 1378 buf_length = MAX_PATH+1;
1365 1379
1366#ifdef HAVE_DIRCACHE 1380#ifdef HAVE_DIRCACHE
1367 if (is_dircache_pointers_intact() && playlist->filenames) 1381 if (playlist->dcfrefs)
1368 { 1382 {
1369 if (playlist->filenames[index] >= 0) 1383 max = dircache_get_fileref_path(&playlist->dcfrefs[index],
1370 { 1384 tmp_buf, sizeof(tmp_buf));
1371 max = dircache_copy_path(playlist->filenames[index],
1372 tmp_buf, sizeof(tmp_buf)-1);
1373 }
1374 } 1385 }
1375#else 1386#endif /* HAVE_DIRCACHE */
1376 (void)index;
1377#endif
1378 1387
1379 if (playlist->in_ram && !control_file && max < 0) 1388 if (playlist->in_ram && !control_file && max < 0)
1380 { 1389 {
@@ -1406,12 +1415,16 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1406 { 1415 {
1407 max = read(fd, tmp_buf, MIN((size_t) buf_length, sizeof(tmp_buf))); 1416 max = read(fd, tmp_buf, MIN((size_t) buf_length, sizeof(tmp_buf)));
1408 1417
1409 if ((max > 0) && !utf8) 1418 if (max > 0)
1410 { 1419 {
1420 /* playlist file may end without a new line - terminate buffer */
1421 tmp_buf[MIN(max, (int)sizeof(tmp_buf) - 1)] = '\0';
1422
1411 /* Use dir_buf as a temporary buffer. Note that dir_buf must 1423 /* Use dir_buf as a temporary buffer. Note that dir_buf must
1412 * be as large as tmp_buf. 1424 * be as large as tmp_buf.
1413 */ 1425 */
1414 max = convert_m3u(tmp_buf, max, sizeof(tmp_buf), dir_buf); 1426 if (!utf8)
1427 max = convert_m3u(tmp_buf, max, sizeof(tmp_buf), dir_buf);
1415 } 1428 }
1416 } 1429 }
1417 } 1430 }
@@ -1432,6 +1445,8 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1432 strlcpy(dir_buf, playlist->filename, playlist->dirlen); 1445 strlcpy(dir_buf, playlist->filename, playlist->dirlen);
1433 1446
1434 return format_track_path(buf, tmp_buf, buf_length, dir_buf); 1447 return format_track_path(buf, tmp_buf, buf_length, dir_buf);
1448
1449 (void)index;
1435} 1450}
1436 1451
1437static int get_next_directory(char *dir){ 1452static int get_next_directory(char *dir){
@@ -1974,11 +1989,12 @@ static int move_callback(int handle, void* current, void* new)
1974 struct playlist_info* playlist = &current_playlist; 1989 struct playlist_info* playlist = &current_playlist;
1975 if (current == playlist->indices) 1990 if (current == playlist->indices)
1976 playlist->indices = new; 1991 playlist->indices = new;
1977 else if (current == playlist->filenames)
1978 playlist->filenames = new;
1979 else if (current == playlist->buffer) 1992 else if (current == playlist->buffer)
1980 playlist->buffer = new; 1993 playlist->buffer = new;
1981 1994#ifdef HAVE_DIRCACHE
1995 else if (current == playlist->dcfrefs)
1996 playlist->dcfrefs = new;
1997#endif /* HAVE_DIRCACHE */
1982 return BUFLIB_CB_OK; 1998 return BUFLIB_CB_OK;
1983} 1999}
1984 2000
@@ -2019,15 +2035,15 @@ void playlist_init(void)
2019 2035
2020#ifdef HAVE_DIRCACHE 2036#ifdef HAVE_DIRCACHE
2021 handle = core_alloc_ex("playlist dc", 2037 handle = core_alloc_ex("playlist dc",
2022 playlist->max_playlist_size * sizeof(int), &ops); 2038 playlist->max_playlist_size * sizeof(*playlist->dcfrefs), &ops);
2023 playlist->filenames = core_get_data(handle); 2039 playlist->dcfrefs = core_get_data(handle);
2024 memset((void*)playlist->filenames, 0xff, 2040 copy_filerefs(playlist->dcfrefs, NULL, playlist->max_playlist_size);
2025 playlist->max_playlist_size * sizeof(int));
2026 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack), 2041 create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack),
2027 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND) 2042 0, playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND)
2028 IF_COP(, CPU)); 2043 IF_COP(, CPU));
2044
2029 queue_init(&playlist_queue, true); 2045 queue_init(&playlist_queue, true);
2030#endif 2046#endif /* HAVE_DIRCACHE */
2031} 2047}
2032 2048
2033/* 2049/*
@@ -2513,8 +2529,9 @@ int playlist_add(const char *filename)
2513 2529
2514 playlist->indices[playlist->amount] = playlist->buffer_end_pos; 2530 playlist->indices[playlist->amount] = playlist->buffer_end_pos;
2515#ifdef HAVE_DIRCACHE 2531#ifdef HAVE_DIRCACHE
2516 playlist->filenames[playlist->amount] = -1; 2532 copy_filerefs(&playlist->dcfrefs[playlist->amount], NULL, 1);
2517#endif 2533#endif
2534
2518 playlist->amount++; 2535 playlist->amount++;
2519 2536
2520 strcpy((char*)&playlist->buffer[playlist->buffer_end_pos], filename); 2537 strcpy((char*)&playlist->buffer[playlist->buffer_end_pos], filename);
@@ -2863,18 +2880,19 @@ int playlist_create_ex(struct playlist_info* playlist,
2863 2880
2864 if (index_buffer) 2881 if (index_buffer)
2865 { 2882 {
2866 int num_indices = index_buffer_size / sizeof(int); 2883 size_t unit_size = sizeof (*playlist->indices);
2867
2868#ifdef HAVE_DIRCACHE 2884#ifdef HAVE_DIRCACHE
2869 num_indices /= 2; 2885 unit_size += sizeof (*playlist->dcfrefs);
2870#endif 2886#endif
2887 int num_indices = index_buffer_size / unit_size;
2888
2871 if (num_indices > global_settings.max_files_in_playlist) 2889 if (num_indices > global_settings.max_files_in_playlist)
2872 num_indices = global_settings.max_files_in_playlist; 2890 num_indices = global_settings.max_files_in_playlist;
2873 2891
2874 playlist->max_playlist_size = num_indices; 2892 playlist->max_playlist_size = num_indices;
2875 playlist->indices = index_buffer; 2893 playlist->indices = index_buffer;
2876#ifdef HAVE_DIRCACHE 2894#ifdef HAVE_DIRCACHE
2877 playlist->filenames = (int*)&playlist->indices[num_indices]; 2895 playlist->dcfrefs = (void *)&playlist->indices[num_indices];
2878#endif 2896#endif
2879 } 2897 }
2880 else 2898 else
@@ -2882,7 +2900,7 @@ int playlist_create_ex(struct playlist_info* playlist,
2882 playlist->max_playlist_size = current_playlist.max_playlist_size; 2900 playlist->max_playlist_size = current_playlist.max_playlist_size;
2883 playlist->indices = current_playlist.indices; 2901 playlist->indices = current_playlist.indices;
2884#ifdef HAVE_DIRCACHE 2902#ifdef HAVE_DIRCACHE
2885 playlist->filenames = current_playlist.filenames; 2903 playlist->dcfrefs = current_playlist.dcfrefs;
2886#endif 2904#endif
2887 } 2905 }
2888 2906
@@ -2942,8 +2960,8 @@ int playlist_set_current(struct playlist_info* playlist)
2942 memcpy((void*)current_playlist.indices, (void*)playlist->indices, 2960 memcpy((void*)current_playlist.indices, (void*)playlist->indices,
2943 playlist->max_playlist_size*sizeof(int)); 2961 playlist->max_playlist_size*sizeof(int));
2944#ifdef HAVE_DIRCACHE 2962#ifdef HAVE_DIRCACHE
2945 memcpy((void*)current_playlist.filenames, (void*)playlist->filenames, 2963 copy_filerefs(current_playlist.dcfrefs, playlist->dcfrefs,
2946 playlist->max_playlist_size*sizeof(int)); 2964 playlist->max_playlist_size);
2947#endif 2965#endif
2948 } 2966 }
2949 2967
diff --git a/apps/playlist.h b/apps/playlist.h
index a331838fde..6048001ff7 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -82,7 +82,9 @@ struct playlist_info
82 bool control_created; /* has control file been created? */ 82 bool control_created; /* has control file been created? */
83 int dirlen; /* Length of the path to the playlist file */ 83 int dirlen; /* Length of the path to the playlist file */
84 volatile unsigned long *indices; /* array of indices */ 84 volatile unsigned long *indices; /* array of indices */
85 volatile int *filenames; /* Array of dircache indices */ 85#ifdef HAVE_DIRCACHE
86 struct dircache_fileref *dcfrefs; /* Dircache entry shortcuts */
87#endif
86 int max_playlist_size; /* Max number of files in playlist. Mirror of 88 int max_playlist_size; /* Max number of files in playlist. Mirror of
87 global_settings.max_files_in_playlist */ 89 global_settings.max_files_in_playlist */
88 bool in_ram; /* playlist stored in ram (dirplay) */ 90 bool in_ram; /* playlist stored in ram (dirplay) */
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 2b6041227b..df252ca0bc 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -90,6 +90,10 @@
90 90
91#undef HAVE_DIRCACHE 91#undef HAVE_DIRCACHE
92 92
93#ifdef HAVE_DIRCACHE
94#include "dircache.h"
95#endif
96
93#ifdef __PCTOOL__ 97#ifdef __PCTOOL__
94#define yield() do { } while(0) 98#define yield() do { } while(0)
95#define sim_sleep(timeout) do { } while(0) 99#define sim_sleep(timeout) do { } while(0)
@@ -112,6 +116,9 @@ static long tempbufidx; /* Current location in buffer. */
112static size_t tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */ 116static size_t tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */
113static long tempbuf_left; /* Buffer space left. */ 117static long tempbuf_left; /* Buffer space left. */
114static long tempbuf_pos; 118static long tempbuf_pos;
119#ifndef __PCTOOL__
120static int tempbuf_handle;
121#endif
115 122
116#define SORTED_TAGS_COUNT 8 123#define SORTED_TAGS_COUNT 8
117#define TAGCACHE_IS_UNIQUE(tag) (BIT_N(tag) & TAGCACHE_UNIQUE_TAGS) 124#define TAGCACHE_IS_UNIQUE(tag) (BIT_N(tag) & TAGCACHE_UNIQUE_TAGS)
@@ -289,17 +296,6 @@ static ssize_t ecwrite_index_entry(int fd, struct index_entry *buf)
289 return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ); 296 return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ);
290} 297}
291 298
292#ifdef HAVE_DIRCACHE
293/**
294 * Returns true if specified flag is still present, i.e., dircache
295 * has not been reloaded.
296 */
297static bool is_dircache_intact(void)
298{
299 return dircache_get_appflag(DIRCACHE_APPFLAG_TAGCACHE);
300}
301#endif
302
303static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) 299static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
304{ 300{
305 int fd; 301 int fd;
@@ -434,7 +430,7 @@ static long find_entry_ram(const char *filename, int dc)
434 430
435 return -1; 431 return -1;
436} 432}
437#endif 433#endif /* defined (HAVE_TC_RAMCACHE) && defined (HAVE_DIRCACHE) */
438 434
439static long find_entry_disk(const char *filename_raw, bool localfd) 435static long find_entry_disk(const char *filename_raw, bool localfd)
440{ 436{
@@ -590,7 +586,7 @@ static bool get_index(int masterfd, int idxid,
590 if (ramcache_hdr->indices[idxid].flag & FLAG_DELETED) 586 if (ramcache_hdr->indices[idxid].flag & FLAG_DELETED)
591 return false; 587 return false;
592 588
593# ifdef HAVE_DIRCACHE 589#ifdef HAVE_DIRCACHE
594 if (!(ramcache_hdr->indices[idxid].flag & FLAG_DIRCACHE) 590 if (!(ramcache_hdr->indices[idxid].flag & FLAG_DIRCACHE)
595 || is_dircache_intact()) 591 || is_dircache_intact())
596#endif 592#endif
@@ -599,8 +595,6 @@ static bool get_index(int masterfd, int idxid,
599 return true; 595 return true;
600 } 596 }
601 } 597 }
602#else
603 (void)use_ram;
604#endif 598#endif
605 599
606 if (masterfd < 0) 600 if (masterfd < 0)
@@ -632,6 +626,8 @@ static bool get_index(int masterfd, int idxid,
632 return false; 626 return false;
633 627
634 return true; 628 return true;
629
630 (void)use_ram;
635} 631}
636 632
637#ifndef __PCTOOL__ 633#ifndef __PCTOOL__
@@ -724,7 +720,7 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
724 { 720 {
725 struct tagfile_entry *ep; 721 struct tagfile_entry *ep;
726 722
727# ifdef HAVE_DIRCACHE 723#ifdef HAVE_DIRCACHE
728 if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE)) 724 if (tag == tag_filename && (idx->flag & FLAG_DIRCACHE))
729 { 725 {
730 /* for tag_filename, seek is a dircache index */ 726 /* for tag_filename, seek is a dircache index */
@@ -745,7 +741,7 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
745 } 741 }
746 } 742 }
747 else 743 else
748# endif 744#endif /* HAVE_DIRCACHE */
749 if (tag != tag_filename) 745 if (tag != tag_filename)
750 { 746 {
751 ep = (struct tagfile_entry *)&ramcache_hdr->tags[tag][seek]; 747 ep = (struct tagfile_entry *)&ramcache_hdr->tags[tag][seek];
@@ -1511,8 +1507,7 @@ static bool get_next(struct tagcache_search *tcs)
1511#ifdef HAVE_TC_RAMCACHE 1507#ifdef HAVE_TC_RAMCACHE
1512 if (tcs->ramsearch) 1508 if (tcs->ramsearch)
1513 { 1509 {
1514 1510#ifdef HAVE_DIRCACHE
1515#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1516 if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE)) 1511 if (tcs->type == tag_filename && (flag & FLAG_DIRCACHE))
1517 { 1512 {
1518 if (is_dircache_intact()) 1513 if (is_dircache_intact())
@@ -1537,7 +1532,7 @@ static bool get_next(struct tagcache_search *tcs)
1537 } 1532 }
1538 } 1533 }
1539 else 1534 else
1540#endif 1535#endif /* HAVE_DIRCACHE */
1541 if (tcs->type != tag_filename) 1536 if (tcs->type != tag_filename)
1542 { 1537 {
1543 struct tagfile_entry *ep; 1538 struct tagfile_entry *ep;
@@ -1766,6 +1761,13 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
1766 1761
1767 return true; 1762 return true;
1768} 1763}
1764#elif defined (HAVE_TC_RAMCACHE)
1765/* temporary dummy function until integration is sorted out --jethead71 */
1766bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
1767{
1768 return false;
1769 (void)id3; (void)filename;
1770}
1769#endif 1771#endif
1770 1772
1771static inline void write_item(const char *item) 1773static inline void write_item(const char *item)
@@ -2982,27 +2984,25 @@ static bool commit(void)
2982#ifdef HAVE_TC_RAMCACHE 2984#ifdef HAVE_TC_RAMCACHE
2983 tc_stat.ramcache = false; 2985 tc_stat.ramcache = false;
2984#endif 2986#endif
2985 2987
2988 /* Beyond here, jump to commit_error to undo locks and restore dircache */
2989 rc = false;
2986 read_lock++; 2990 read_lock++;
2987 2991
2988 /* Try to steal every buffer we can :) */ 2992 /* Try to steal every buffer we can :) */
2989 if (tempbuf_size == 0) 2993 if (tempbuf_size == 0)
2990 local_allocation = true; 2994 local_allocation = true;
2991 2995
2992#if 0 /* FIXME: How much big? dircache buffer can no longer be taken but
2993 may be freed to make room and the cache resumed. --jethead71 */
2994#ifdef HAVE_DIRCACHE 2996#ifdef HAVE_DIRCACHE
2995 if (tempbuf_size == 0) 2997 if (tempbuf_size == 0)
2996 { 2998 {
2997 /* Shut down dircache to free its allocation. */ 2999 /* Suspend dircache to free its allocation. */
2998 dircache_free_buffer(); 3000 dircache_free_buffer();
2999 if (tempbuf_size > 0) 3001 dircache_buffer_stolen = true;
3000 { 3002
3001 dircache_buffer_stolen = true; 3003 allocate_tempbuf();
3002 }
3003 } 3004 }
3004#endif 3005#endif /* HAVE_DIRCACHE */
3005#endif
3006 3006
3007#ifdef HAVE_TC_RAMCACHE 3007#ifdef HAVE_TC_RAMCACHE
3008 if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) 3008 if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0)
@@ -3021,8 +3021,7 @@ static bool commit(void)
3021 logf("delaying commit until next boot"); 3021 logf("delaying commit until next boot");
3022 tc_stat.commit_delayed = true; 3022 tc_stat.commit_delayed = true;
3023 close(tmpfd); 3023 close(tmpfd);
3024 read_lock--; 3024 goto commit_error;
3025 return false;
3026 } 3025 }
3027 3026
3028 logf("commit %ld entries...", tch.entry_count); 3027 logf("commit %ld entries...", tch.entry_count);
@@ -3053,8 +3052,7 @@ static bool commit(void)
3053 tc_stat.commit_delayed = true; 3052 tc_stat.commit_delayed = true;
3054 3053
3055 tc_stat.commit_step = 0; 3054 tc_stat.commit_step = 0;
3056 read_lock--; 3055 goto commit_error;
3057 return false;
3058 } 3056 }
3059 } 3057 }
3060 3058
@@ -3063,8 +3061,7 @@ static bool commit(void)
3063 logf("Failure to commit numeric indices"); 3061 logf("Failure to commit numeric indices");
3064 close(tmpfd); 3062 close(tmpfd);
3065 tc_stat.commit_step = 0; 3063 tc_stat.commit_step = 0;
3066 read_lock--; 3064 goto commit_error;
3067 return false;
3068 } 3065 }
3069 3066
3070 close(tmpfd); 3067 close(tmpfd);
@@ -3073,10 +3070,7 @@ static bool commit(void)
3073 3070
3074 /* Update the master index headers. */ 3071 /* Update the master index headers. */
3075 if ( (masterfd = open_master_fd(&tcmh, true)) < 0) 3072 if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
3076 { 3073 goto commit_error;
3077 read_lock--;
3078 return false;
3079 }
3080 3074
3081 remove(TAGCACHE_FILE_TEMP); 3075 remove(TAGCACHE_FILE_TEMP);
3082 3076
@@ -3101,39 +3095,53 @@ static bool commit(void)
3101 tempbuf_size = 0; 3095 tempbuf_size = 0;
3102 } 3096 }
3103 3097
3104#ifdef HAVE_DIRCACHE
3105 /* Rebuild the dircache, if we stole the buffer. */
3106 if (dircache_buffer_stolen)
3107 dircache_resume();
3108#endif
3109
3110#ifdef HAVE_TC_RAMCACHE 3098#ifdef HAVE_TC_RAMCACHE
3111 if (ramcache_buffer_stolen) 3099 if (ramcache_buffer_stolen)
3100 {
3101 ramcache_buffer_stolen = false;
3112 move_lock--; 3102 move_lock--;
3103 }
3104
3113 /* Reload tagcache. */ 3105 /* Reload tagcache. */
3114 if (tc_stat.ramcache_allocated > 0) 3106 if (tc_stat.ramcache_allocated > 0)
3115 tagcache_start_scan(); 3107 tagcache_start_scan();
3116#endif 3108#endif
3117 3109
3110 rc = true;
3111
3112commit_error:
3113#ifdef HAVE_TC_RAMCACHE
3114 if (ramcache_buffer_stolen)
3115 move_lock--;
3116#endif
3117
3118 read_lock--; 3118 read_lock--;
3119
3120 return true;
3121}
3122 3119
3123#ifndef __PCTOOL__ 3120#ifdef HAVE_DIRCACHE
3124static int tempbuf_handle; 3121 /* Resume the dircache, if we stole the buffer. */
3122 if (dircache_buffer_stolen)
3123 dircache_resume();
3125#endif 3124#endif
3125
3126 return rc;
3127}
3126 3128
3127static void allocate_tempbuf(void) 3129static void allocate_tempbuf(void)
3128{ 3130{
3129 /* Yeah, malloc would be really nice now :) */ 3131 /* Yeah, malloc would be really nice now :) */
3132 size_t size;
3133 tempbuf_size = 0;
3134
3130#ifdef __PCTOOL__ 3135#ifdef __PCTOOL__
3131 tempbuf_size = 32*1024*1024; 3136 size = 32*1024*1024;
3132 tempbuf = malloc(tempbuf_size); 3137 tempbuf = malloc(size);
3133#else 3138#else
3134 tempbuf_handle = core_alloc_maximum("tc tempbuf", &tempbuf_size, NULL); 3139 tempbuf_handle = core_alloc_maximum("tc tempbuf", &size, NULL);
3135 tempbuf = core_get_data(tempbuf_handle); 3140 tempbuf = core_get_data(tempbuf_handle);
3136#endif 3141#endif
3142
3143 if (tempbuf)
3144 tempbuf_size = size;
3137} 3145}
3138 3146
3139static void free_tempbuf(void) 3147static void free_tempbuf(void)
@@ -4133,9 +4141,14 @@ static bool load_tagcache(void)
4133 goto failure; 4141 goto failure;
4134 } 4142 }
4135 4143
4136# ifdef HAVE_DIRCACHE 4144 if (global_settings.tagcache_autoupdate)
4137 if (dircache_is_enabled())
4138 { 4145 {
4146 /* Check if entry has been removed. */
4147 #ifdef HAVE_DIRCACHE
4148 /* This will be very slow unless dircache is enabled
4149 or target is flash based. */
4150##################
4151 if (dircache_search( /* will get this! -- jethead71 */
4139 dc = dircache_get_entry_id(buf); 4152 dc = dircache_get_entry_id(buf);
4140 if (dc < 0) 4153 if (dc < 0)
4141 { 4154 {
@@ -4148,24 +4161,17 @@ static bool load_tagcache(void)
4148 4161
4149 idx->flag |= FLAG_DIRCACHE; 4162 idx->flag |= FLAG_DIRCACHE;
4150 idx->tag_seek[tag_filename] = dc; 4163 idx->tag_seek[tag_filename] = dc;
4151 } 4164 #else /* ndef HAVE_DIRCACHE */
4152 else 4165 /* This will be very slow unless target is flash based;
4153# endif 4166 do it anyway for consistency. */
4154 { 4167 if (!file_exists(buf))
4155 /* This will be very slow unless dircache is enabled
4156 or target is flash based, but do it anyway for
4157 consistency. */
4158 /* Check if entry has been removed. */
4159 if (global_settings.tagcache_autoupdate)
4160 { 4168 {
4161 if (!file_exists(buf)) 4169 logf("Entry no longer valid.");
4162 { 4170 logf("-> %s", buf);
4163 logf("Entry no longer valid."); 4171 delete_entry(fe->idx_id);
4164 logf("-> %s", buf); 4172 continue;
4165 delete_entry(fe->idx_id);
4166 continue;
4167 }
4168 } 4173 }
4174 #endif /* HAVE_DIRCACHE */
4169 } 4175 }
4170 4176
4171 continue ; 4177 continue ;
diff --git a/firmware/export/config.h b/firmware/export/config.h
index b769b63c32..73464526a6 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -853,7 +853,7 @@ Lyre prototype 1 */
853#define HAVE_DIRCACHE 853#define HAVE_DIRCACHE
854#endif 854#endif
855#ifdef HAVE_TAGCACHE 855#ifdef HAVE_TAGCACHE
856//#define HAVE_TC_RAMCACHE 856#define HAVE_TC_RAMCACHE
857#endif 857#endif
858#endif 858#endif
859 859