diff options
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 246 |
1 files changed, 231 insertions, 15 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 5214e508e8..bc463ab142 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "lang.h" | 32 | #include "lang.h" |
33 | #include "tagcache.h" | 33 | #include "tagcache.h" |
34 | #include "buffer.h" | 34 | #include "buffer.h" |
35 | #include "atoi.h" | ||
35 | 36 | ||
36 | /* Tag Cache thread. */ | 37 | /* Tag Cache thread. */ |
37 | static struct event_queue tagcache_queue; | 38 | static struct event_queue tagcache_queue; |
@@ -50,8 +51,9 @@ static long tempbuf_left; /* Buffer space left. */ | |||
50 | static long tempbuf_pos; | 51 | static long tempbuf_pos; |
51 | 52 | ||
52 | /* Tags we want to get sorted (loaded to the tempbuf). */ | 53 | /* Tags we want to get sorted (loaded to the tempbuf). */ |
53 | static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, tag_title }; | 54 | static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, tag_composer, tag_title }; |
54 | static const int unique_tags[] = { tag_artist, tag_album, tag_genre }; | 55 | static const int unique_tags[] = { tag_artist, tag_album, tag_genre, tag_composer }; |
56 | static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length, tag_bitrate }; | ||
55 | 57 | ||
56 | /* Queue commands. */ | 58 | /* Queue commands. */ |
57 | #define Q_STOP_SCAN 0 | 59 | #define Q_STOP_SCAN 0 |
@@ -63,15 +65,15 @@ static const int unique_tags[] = { tag_artist, tag_album, tag_genre }; | |||
63 | #define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" | 65 | #define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" |
64 | #define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" | 66 | #define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" |
65 | 67 | ||
68 | /* Tag Cache Header version 'TCHxx' */ | ||
69 | #define TAGCACHE_MAGIC 0x54434801 | ||
70 | |||
66 | /* Tag database structures. */ | 71 | /* Tag database structures. */ |
67 | #define TAGCACHE_MAGIC 0x01020317 | ||
68 | 72 | ||
69 | /* Variable-length tag entry in tag files. */ | 73 | /* Variable-length tag entry in tag files. */ |
70 | struct tagfile_entry { | 74 | struct tagfile_entry { |
71 | short tag_length; | 75 | short tag_length; |
72 | #ifdef ROCKBOX_STRICT_ALIGN | 76 | short idx_id; |
73 | short padding; | ||
74 | #endif | ||
75 | char tag_data[0]; | 77 | char tag_data[0]; |
76 | }; | 78 | }; |
77 | 79 | ||
@@ -118,6 +120,7 @@ struct tempbuf_id { | |||
118 | 120 | ||
119 | struct tempbuf_searchidx { | 121 | struct tempbuf_searchidx { |
120 | struct tempbuf_id *id; | 122 | struct tempbuf_id *id; |
123 | long idx_id; | ||
121 | char *str; | 124 | char *str; |
122 | int seek; | 125 | int seek; |
123 | }; | 126 | }; |
@@ -129,6 +132,19 @@ static int total_entry_count = 0; | |||
129 | static int data_size = 0; | 132 | static int data_size = 0; |
130 | static int processed_dir_count; | 133 | static int processed_dir_count; |
131 | 134 | ||
135 | static bool is_numeric_tag(int type) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | for (i = 0; i < (int)(sizeof(numeric_tags)/sizeof(numeric_tags[0])); i++) | ||
140 | { | ||
141 | if (type == numeric_tags[i]) | ||
142 | return true; | ||
143 | } | ||
144 | |||
145 | return false; | ||
146 | } | ||
147 | |||
132 | #ifdef HAVE_TC_RAMCACHE | 148 | #ifdef HAVE_TC_RAMCACHE |
133 | static struct index_entry *find_entry_ram(const char *filename, | 149 | static struct index_entry *find_entry_ram(const char *filename, |
134 | const struct dircache_entry *dc) | 150 | const struct dircache_entry *dc) |
@@ -308,6 +324,50 @@ static struct index_entry *find_entry_disk(const char *filename, bool retrieve) | |||
308 | return &idx; | 324 | return &idx; |
309 | } | 325 | } |
310 | 326 | ||
327 | long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) | ||
328 | { | ||
329 | struct tagcache_header tch; | ||
330 | struct index_entry idx; | ||
331 | int masterfd; | ||
332 | |||
333 | if (!is_numeric_tag(tag)) | ||
334 | return -1; | ||
335 | |||
336 | #ifdef HAVE_TC_RAMCACHE | ||
337 | if (tcs->ramsearch) | ||
338 | { | ||
339 | return hdr->indices[tcs->idx_id].tag_seek[tag]; | ||
340 | } | ||
341 | #endif | ||
342 | |||
343 | masterfd = open(TAGCACHE_FILE_MASTER, O_RDONLY); | ||
344 | |||
345 | if (masterfd < 0) | ||
346 | { | ||
347 | logf("open fail"); | ||
348 | return -2; | ||
349 | } | ||
350 | |||
351 | if (read(masterfd, &tch, sizeof(struct tagcache_header)) != | ||
352 | sizeof(struct tagcache_header) || tch.magic != TAGCACHE_MAGIC) | ||
353 | { | ||
354 | logf("header error"); | ||
355 | return -3; | ||
356 | } | ||
357 | |||
358 | lseek(masterfd, tcs->idx_id * sizeof(struct index_entry), SEEK_CUR); | ||
359 | if (read(masterfd, &idx, sizeof(struct index_entry)) != | ||
360 | sizeof(struct index_entry)) | ||
361 | { | ||
362 | logf("read error #3"); | ||
363 | close(masterfd); | ||
364 | return -4; | ||
365 | } | ||
366 | close(masterfd); | ||
367 | |||
368 | return idx.tag_seek[tag]; | ||
369 | } | ||
370 | |||
311 | static bool build_lookup_list(struct tagcache_search *tcs) | 371 | static bool build_lookup_list(struct tagcache_search *tcs) |
312 | { | 372 | { |
313 | struct tagcache_header header; | 373 | struct tagcache_header header; |
@@ -443,6 +503,9 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
443 | else | 503 | else |
444 | #endif | 504 | #endif |
445 | { | 505 | { |
506 | if (is_numeric_tag(tcs->type)) | ||
507 | return true; | ||
508 | |||
446 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type); | 509 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type); |
447 | tcs->fd = open(buf, O_RDONLY); | 510 | tcs->fd = open(buf, O_RDONLY); |
448 | if (tcs->fd < 0) | 511 | if (tcs->fd < 0) |
@@ -484,13 +547,17 @@ bool tagcache_get_next(struct tagcache_search *tcs) | |||
484 | if (!tcs->valid) | 547 | if (!tcs->valid) |
485 | return false; | 548 | return false; |
486 | 549 | ||
487 | if (tcs->fd < 0 | 550 | if (tcs->fd < 0 && !is_numeric_tag(tcs->type) |
488 | #ifdef HAVE_TC_RAMCACHE | 551 | #ifdef HAVE_TC_RAMCACHE |
489 | && !tcs->ramsearch | 552 | && !tcs->ramsearch |
490 | #endif | 553 | #endif |
491 | ) | 554 | ) |
492 | return false; | 555 | return false; |
493 | 556 | ||
557 | /* Searching not supported for numeric tags yet. */ | ||
558 | if (is_numeric_tag(tcs->type)) | ||
559 | return false; | ||
560 | |||
494 | /* Relative fetch. */ | 561 | /* Relative fetch. */ |
495 | if (tcs->filter_count > 0) | 562 | if (tcs->filter_count > 0) |
496 | { | 563 | { |
@@ -539,6 +606,7 @@ bool tagcache_get_next(struct tagcache_search *tcs) | |||
539 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; | 606 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; |
540 | tcs->result = ep->tag_data; | 607 | tcs->result = ep->tag_data; |
541 | tcs->result_len = ep->tag_length; | 608 | tcs->result_len = ep->tag_length; |
609 | tcs->idx_id = ep->idx_id; | ||
542 | 610 | ||
543 | return true; | 611 | return true; |
544 | } | 612 | } |
@@ -571,6 +639,7 @@ bool tagcache_get_next(struct tagcache_search *tcs) | |||
571 | 639 | ||
572 | tcs->result = buf; | 640 | tcs->result = buf; |
573 | tcs->result_len = entry.tag_length; | 641 | tcs->result_len = entry.tag_length; |
642 | tcs->idx_id = entry.idx_id; | ||
574 | 643 | ||
575 | return true; | 644 | return true; |
576 | } | 645 | } |
@@ -609,7 +678,7 @@ void tagcache_search_finish(struct tagcache_search *tcs) | |||
609 | } | 678 | } |
610 | 679 | ||
611 | #ifdef HAVE_TC_RAMCACHE | 680 | #ifdef HAVE_TC_RAMCACHE |
612 | struct tagfile_entry *get_tag(struct index_entry *entry, int tag) | 681 | static struct tagfile_entry *get_tag(struct index_entry *entry, int tag) |
613 | { | 682 | { |
614 | return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]]; | 683 | return (struct tagfile_entry *)&hdr->tags[tag][entry->tag_seek[tag]]; |
615 | } | 684 | } |
@@ -627,6 +696,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
627 | id3->artist = get_tag(entry, tag_artist)->tag_data; | 696 | id3->artist = get_tag(entry, tag_artist)->tag_data; |
628 | id3->album = get_tag(entry, tag_album)->tag_data; | 697 | id3->album = get_tag(entry, tag_album)->tag_data; |
629 | id3->genre_string = get_tag(entry, tag_genre)->tag_data; | 698 | id3->genre_string = get_tag(entry, tag_genre)->tag_data; |
699 | id3->composer = get_tag(entry, tag_composer)->tag_data; | ||
630 | 700 | ||
631 | return true; | 701 | return true; |
632 | } | 702 | } |
@@ -658,6 +728,7 @@ static void add_tagcache(const char *path) | |||
658 | struct temp_file_entry entry; | 728 | struct temp_file_entry entry; |
659 | bool ret; | 729 | bool ret; |
660 | int fd; | 730 | int fd; |
731 | char tracknumfix[3]; | ||
661 | //uint32_t crcbuf[CRC_BUF_LEN]; | 732 | //uint32_t crcbuf[CRC_BUF_LEN]; |
662 | 733 | ||
663 | if (cachefd < 0) | 734 | if (cachefd < 0) |
@@ -689,6 +760,8 @@ static void add_tagcache(const char *path) | |||
689 | } | 760 | } |
690 | 761 | ||
691 | memset(&track, 0, sizeof(struct track_info)); | 762 | memset(&track, 0, sizeof(struct track_info)); |
763 | memset(&entry, 0, sizeof(struct temp_file_entry)); | ||
764 | memset(&tracknumfix, 0, sizeof(tracknumfix)); | ||
692 | ret = get_metadata(&track, fd, path, false); | 765 | ret = get_metadata(&track, fd, path, false); |
693 | close(fd); | 766 | close(fd); |
694 | 767 | ||
@@ -699,19 +772,51 @@ static void add_tagcache(const char *path) | |||
699 | check_if_empty(&track.id3.artist); | 772 | check_if_empty(&track.id3.artist); |
700 | check_if_empty(&track.id3.album); | 773 | check_if_empty(&track.id3.album); |
701 | check_if_empty(&track.id3.genre_string); | 774 | check_if_empty(&track.id3.genre_string); |
775 | check_if_empty(&track.id3.composer); | ||
702 | 776 | ||
703 | entry.tag_length[tag_filename] = strlen(path) + 1; | 777 | entry.tag_length[tag_filename] = strlen(path) + 1; |
704 | entry.tag_length[tag_title] = strlen(track.id3.title) + 1; | 778 | entry.tag_length[tag_title] = strlen(track.id3.title) + 1; |
705 | entry.tag_length[tag_artist] = strlen(track.id3.artist) + 1; | 779 | entry.tag_length[tag_artist] = strlen(track.id3.artist) + 1; |
706 | entry.tag_length[tag_album] = strlen(track.id3.album) + 1; | 780 | entry.tag_length[tag_album] = strlen(track.id3.album) + 1; |
707 | entry.tag_length[tag_genre] = strlen(track.id3.genre_string) + 1; | 781 | entry.tag_length[tag_genre] = strlen(track.id3.genre_string) + 1; |
782 | entry.tag_length[tag_composer] = strlen(track.id3.composer) + 1; | ||
708 | 783 | ||
709 | entry.tag_offset[tag_filename] = 0; | 784 | entry.tag_offset[tag_filename] = 0; |
710 | entry.tag_offset[tag_title] = entry.tag_offset[tag_filename] + entry.tag_length[tag_filename]; | 785 | entry.tag_offset[tag_title] = entry.tag_offset[tag_filename] + entry.tag_length[tag_filename]; |
711 | entry.tag_offset[tag_artist] = entry.tag_offset[tag_title] + entry.tag_length[tag_title]; | 786 | entry.tag_offset[tag_artist] = entry.tag_offset[tag_title] + entry.tag_length[tag_title]; |
712 | entry.tag_offset[tag_album] = entry.tag_offset[tag_artist] + entry.tag_length[tag_artist]; | 787 | entry.tag_offset[tag_album] = entry.tag_offset[tag_artist] + entry.tag_length[tag_artist]; |
713 | entry.tag_offset[tag_genre] = entry.tag_offset[tag_album] + entry.tag_length[tag_album]; | 788 | entry.tag_offset[tag_genre] = entry.tag_offset[tag_album] + entry.tag_length[tag_album]; |
714 | entry.data_length = entry.tag_offset[tag_genre] + entry.tag_length[tag_genre]; | 789 | entry.tag_offset[tag_composer] = entry.tag_offset[tag_genre] + entry.tag_length[tag_genre]; |
790 | entry.data_length = entry.tag_offset[tag_composer] + entry.tag_length[tag_composer]; | ||
791 | |||
792 | /* Numeric tags */ | ||
793 | entry.tag_offset[tag_year] = track.id3.year; | ||
794 | entry.tag_offset[tag_tracknumber] = track.id3.tracknum; | ||
795 | entry.tag_offset[tag_length] = track.id3.length; | ||
796 | entry.tag_offset[tag_bitrate] = track.id3.bitrate; | ||
797 | |||
798 | if (entry.tag_offset[tag_tracknumber] <= 0) | ||
799 | { | ||
800 | int start, i; | ||
801 | |||
802 | for (start = 0; path[start] != '\0'; start++) | ||
803 | if (isdigit(path[start])) | ||
804 | break ; | ||
805 | |||
806 | for (i = 0; i < (int)sizeof(tracknumfix)-1 | ||
807 | && path[start+i] != '\0'; i++) | ||
808 | { | ||
809 | if (isdigit(path[start+i])) | ||
810 | tracknumfix[i] = path[start+i]; | ||
811 | else | ||
812 | break ; | ||
813 | } | ||
814 | |||
815 | if (tracknumfix[0] != '\0') | ||
816 | entry.tag_offset[tag_tracknumber] = atoi(tracknumfix); | ||
817 | else | ||
818 | entry.tag_offset[tag_tracknumber] = -1; | ||
819 | } | ||
715 | 820 | ||
716 | write(cachefd, &entry, sizeof(struct temp_file_entry)); | 821 | write(cachefd, &entry, sizeof(struct temp_file_entry)); |
717 | write_item(path); | 822 | write_item(path); |
@@ -719,6 +824,7 @@ static void add_tagcache(const char *path) | |||
719 | write_item(track.id3.artist); | 824 | write_item(track.id3.artist); |
720 | write_item(track.id3.album); | 825 | write_item(track.id3.album); |
721 | write_item(track.id3.genre_string); | 826 | write_item(track.id3.genre_string); |
827 | write_item(track.id3.composer); | ||
722 | total_entry_count++; | 828 | total_entry_count++; |
723 | } | 829 | } |
724 | 830 | ||
@@ -730,12 +836,15 @@ static void remove_files(void) | |||
730 | remove(TAGCACHE_FILE_MASTER); | 836 | remove(TAGCACHE_FILE_MASTER); |
731 | for (i = 0; i < TAG_COUNT; i++) | 837 | for (i = 0; i < TAG_COUNT; i++) |
732 | { | 838 | { |
839 | if (is_numeric_tag(i)) | ||
840 | continue; | ||
841 | |||
733 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); | 842 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); |
734 | remove(buf); | 843 | remove(buf); |
735 | } | 844 | } |
736 | } | 845 | } |
737 | 846 | ||
738 | static bool tempbuf_insert(char *str, int id) | 847 | static bool tempbuf_insert(char *str, int id, int idx_id) |
739 | { | 848 | { |
740 | struct tempbuf_searchidx *index = (struct tempbuf_searchidx *)tempbuf; | 849 | struct tempbuf_searchidx *index = (struct tempbuf_searchidx *)tempbuf; |
741 | int len = strlen(str)+1; | 850 | int len = strlen(str)+1; |
@@ -759,6 +868,7 @@ static bool tempbuf_insert(char *str, int id) | |||
759 | #endif | 868 | #endif |
760 | index[tempbufidx].id->id = id; | 869 | index[tempbufidx].id->id = id; |
761 | index[tempbufidx].id->next = NULL; | 870 | index[tempbufidx].id->next = NULL; |
871 | index[tempbufidx].idx_id = idx_id; | ||
762 | tempbuf_pos += sizeof(struct tempbuf_id); | 872 | tempbuf_pos += sizeof(struct tempbuf_id); |
763 | 873 | ||
764 | index[tempbufidx].seek = -1; | 874 | index[tempbufidx].seek = -1; |
@@ -810,7 +920,7 @@ static bool tempbuf_unique_insert(char *str, int id) | |||
810 | } | 920 | } |
811 | } | 921 | } |
812 | 922 | ||
813 | return tempbuf_insert(str, id); | 923 | return tempbuf_insert(str, id, -1); |
814 | } | 924 | } |
815 | 925 | ||
816 | static int compare(const void *p1, const void *p2) | 926 | static int compare(const void *p1, const void *p2) |
@@ -845,6 +955,7 @@ static int tempbuf_sort(int fd) | |||
845 | index[i].seek = lseek(fd, 0, SEEK_CUR); | 955 | index[i].seek = lseek(fd, 0, SEEK_CUR); |
846 | length = strlen(index[i].str) + 1; | 956 | length = strlen(index[i].str) + 1; |
847 | fe.tag_length = length; | 957 | fe.tag_length = length; |
958 | fe.idx_id = index[i].idx_id; | ||
848 | 959 | ||
849 | #ifdef ROCKBOX_STRICT_ALIGN | 960 | #ifdef ROCKBOX_STRICT_ALIGN |
850 | /* Make sure the entry is long aligned. */ | 961 | /* Make sure the entry is long aligned. */ |
@@ -944,6 +1055,102 @@ static bool is_sorted_tag(int type) | |||
944 | return false; | 1055 | return false; |
945 | } | 1056 | } |
946 | 1057 | ||
1058 | static bool build_numeric_index(int index_type, struct tagcache_header *h, int tmpfd) | ||
1059 | { | ||
1060 | struct tagcache_header tch; | ||
1061 | struct index_entry idx; | ||
1062 | int masterfd; | ||
1063 | int masterfd_pos; | ||
1064 | long *databuf = (long *)tempbuf; | ||
1065 | int max_entries; | ||
1066 | int i; | ||
1067 | |||
1068 | max_entries = tempbuf_size / sizeof(long); | ||
1069 | |||
1070 | if (h->entry_count >= max_entries) | ||
1071 | { | ||
1072 | logf("not enough space!"); | ||
1073 | return false; | ||
1074 | } | ||
1075 | |||
1076 | logf("Building numeric index: %d", index_type); | ||
1077 | |||
1078 | /* Walk through the temporary file. */ | ||
1079 | lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); | ||
1080 | for (i = 0; i < h->entry_count; i++) | ||
1081 | { | ||
1082 | struct temp_file_entry entry; | ||
1083 | |||
1084 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | ||
1085 | sizeof(struct temp_file_entry)) | ||
1086 | { | ||
1087 | logf("read fail #1"); | ||
1088 | return false; | ||
1089 | } | ||
1090 | |||
1091 | /* Insert data in buffer. */ | ||
1092 | databuf[i] = (long)entry.tag_offset[index_type]; | ||
1093 | |||
1094 | /* Skip to next. */ | ||
1095 | lseek(tmpfd, entry.data_length, SEEK_CUR); | ||
1096 | } | ||
1097 | |||
1098 | /* Update the entries in index. */ | ||
1099 | masterfd = open(TAGCACHE_FILE_MASTER, O_RDWR); | ||
1100 | |||
1101 | if (masterfd < 0) | ||
1102 | { | ||
1103 | logf("No master file found!"); | ||
1104 | return false; | ||
1105 | } | ||
1106 | |||
1107 | if (read(masterfd, &tch, sizeof(struct tagcache_header)) != | ||
1108 | sizeof(struct tagcache_header) || tch.magic != TAGCACHE_MAGIC) | ||
1109 | { | ||
1110 | logf("header error"); | ||
1111 | close(masterfd); | ||
1112 | return false; | ||
1113 | } | ||
1114 | |||
1115 | masterfd_pos = lseek(masterfd, tch.entry_count * sizeof(struct index_entry), | ||
1116 | SEEK_CUR); | ||
1117 | if (masterfd_pos == filesize(masterfd)) | ||
1118 | { | ||
1119 | logf("we can't append!"); | ||
1120 | close(masterfd); | ||
1121 | return false; | ||
1122 | } | ||
1123 | |||
1124 | for (i = 0; i < h->entry_count; i++) | ||
1125 | { | ||
1126 | int loc = lseek(masterfd, 0, SEEK_CUR); | ||
1127 | |||
1128 | if (read(masterfd, &idx, sizeof(struct index_entry)) != | ||
1129 | sizeof(struct index_entry)) | ||
1130 | { | ||
1131 | logf("read fail #2"); | ||
1132 | close(masterfd); | ||
1133 | return false; | ||
1134 | } | ||
1135 | |||
1136 | idx.tag_seek[index_type] = databuf[i]; | ||
1137 | |||
1138 | /* Write back the updated index. */ | ||
1139 | lseek(masterfd, loc, SEEK_SET); | ||
1140 | if (write(masterfd, &idx, sizeof(struct index_entry)) != | ||
1141 | sizeof(struct index_entry)) | ||
1142 | { | ||
1143 | logf("write fail"); | ||
1144 | close(masterfd); | ||
1145 | return false; | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | close(masterfd); | ||
1150 | |||
1151 | return true; | ||
1152 | } | ||
1153 | |||
947 | static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) | 1154 | static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) |
948 | { | 1155 | { |
949 | int i; | 1156 | int i; |
@@ -1020,7 +1227,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
1020 | * is saved so we can later reindex the master lookup | 1227 | * is saved so we can later reindex the master lookup |
1021 | * table when the index gets resorted. | 1228 | * table when the index gets resorted. |
1022 | */ | 1229 | */ |
1023 | tempbuf_insert(buf, loc + TAGFILE_MAX_ENTRIES); | 1230 | tempbuf_insert(buf, loc + TAGFILE_MAX_ENTRIES, entry.idx_id); |
1024 | } | 1231 | } |
1025 | } | 1232 | } |
1026 | else | 1233 | else |
@@ -1149,7 +1356,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
1149 | if (is_unique_tag(index_type)) | 1356 | if (is_unique_tag(index_type)) |
1150 | error = !tempbuf_unique_insert(buf, i); | 1357 | error = !tempbuf_unique_insert(buf, i); |
1151 | else | 1358 | else |
1152 | error = !tempbuf_insert(buf, i); | 1359 | error = !tempbuf_insert(buf, i, tch.entry_count + i); |
1153 | 1360 | ||
1154 | if (error) | 1361 | if (error) |
1155 | { | 1362 | { |
@@ -1268,6 +1475,7 @@ static bool build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
1268 | /* Write to index file. */ | 1475 | /* Write to index file. */ |
1269 | idx.tag_seek[index_type] = lseek(fd, 0, SEEK_CUR); | 1476 | idx.tag_seek[index_type] = lseek(fd, 0, SEEK_CUR); |
1270 | fe.tag_length = entry.tag_length[index_type]; | 1477 | fe.tag_length = entry.tag_length[index_type]; |
1478 | fe.idx_id = tch.entry_count + i; | ||
1271 | write(fd, &fe, sizeof(struct tagfile_entry)); | 1479 | write(fd, &fe, sizeof(struct tagfile_entry)); |
1272 | write(fd, buf, fe.tag_length); | 1480 | write(fd, buf, fe.tag_length); |
1273 | tempbufidx++; | 1481 | tempbufidx++; |
@@ -1375,7 +1583,12 @@ static bool commit(void) | |||
1375 | /* Now create the index files. */ | 1583 | /* Now create the index files. */ |
1376 | for (i = 0; i < TAG_COUNT; i++) | 1584 | for (i = 0; i < TAG_COUNT; i++) |
1377 | { | 1585 | { |
1378 | if (!build_index(i, &header, tmpfd)) | 1586 | if (is_numeric_tag(i)) |
1587 | { | ||
1588 | build_numeric_index(i, &header, tmpfd); | ||
1589 | } | ||
1590 | |||
1591 | else if (!build_index(i, &header, tmpfd)) | ||
1379 | { | 1592 | { |
1380 | logf("tagcache failed init"); | 1593 | logf("tagcache failed init"); |
1381 | remove_files(); | 1594 | remove_files(); |
@@ -1537,6 +1750,9 @@ static bool load_tagcache(void) | |||
1537 | struct tagfile_entry *fe; | 1750 | struct tagfile_entry *fe; |
1538 | char buf[MAX_PATH]; | 1751 | char buf[MAX_PATH]; |
1539 | 1752 | ||
1753 | if (is_numeric_tag(i)) | ||
1754 | continue ; | ||
1755 | |||
1540 | //p = ((void *)p+1); | 1756 | //p = ((void *)p+1); |
1541 | p = (char *)((long)p & ~0x03) + 0x04; | 1757 | p = (char *)((long)p & ~0x03) + 0x04; |
1542 | hdr->tags[i] = p; | 1758 | hdr->tags[i] = p; |
@@ -1854,7 +2070,7 @@ static void tagcache_thread(void) | |||
1854 | 2070 | ||
1855 | int tagcache_get_progress(void) | 2071 | int tagcache_get_progress(void) |
1856 | { | 2072 | { |
1857 | int total_count = -1; | 2073 | int total_count = processed_dir_count; |
1858 | 2074 | ||
1859 | #ifdef HAVE_DIRCACHE | 2075 | #ifdef HAVE_DIRCACHE |
1860 | if (dircache_is_enabled()) | 2076 | if (dircache_is_enabled()) |