summaryrefslogtreecommitdiff
path: root/apps/tagcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r--apps/tagcache.c355
1 files changed, 197 insertions, 158 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index ca2421171b..38537b5ceb 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -538,6 +538,96 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx)
538 return true; 538 return true;
539} 539}
540 540
541static bool open_files(struct tagcache_search *tcs, int tag)
542{
543 if (tcs->idxfd[tag] < 0)
544 {
545 char fn[MAX_PATH];
546
547 snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag);
548 tcs->idxfd[tag] = open(fn, O_RDONLY);
549 }
550
551 if (tcs->idxfd[tag] < 0)
552 {
553 logf("File not open!");
554 return false;
555 }
556
557 return true;
558}
559
560static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
561 int tag, char *buf, long size)
562{
563 struct tagfile_entry tfe;
564 long seek;
565
566 *buf = '\0';
567
568 if (tagcache_is_numeric_tag(tag))
569 return false;
570
571 seek = idx->tag_seek[tag];
572 if (seek < 0)
573 {
574 logf("Retrieve failed");
575 return false;
576 }
577
578#ifdef HAVE_TC_RAMCACHE
579 if (tcs->ramsearch)
580 {
581 struct tagfile_entry *ep;
582
583# ifdef HAVE_DIRCACHE
584 if (tag == tag_filename && idx->flag & FLAG_DIRCACHE)
585 {
586 dircache_copy_path((struct dircache_entry *)seek,
587 buf, size);
588 return true;
589 }
590 else
591# endif
592 if (tag != tag_filename)
593 {
594 ep = (struct tagfile_entry *)&hdr->tags[tag][seek];
595 strncpy(buf, ep->tag_data, size-1);
596
597 return true;
598 }
599 }
600#endif
601
602 if (!open_files(tcs, tag))
603 return false;
604
605 lseek(tcs->idxfd[tag], seek, SEEK_SET);
606 if (read(tcs->idxfd[tag], &tfe, sizeof(struct tagfile_entry)) !=
607 sizeof(struct tagfile_entry))
608 {
609 logf("read error #5");
610 return false;
611 }
612
613 if (tfe.tag_length >= size)
614 {
615 logf("too small buffer");
616 return false;
617 }
618
619 if (read(tcs->idxfd[tag], buf, tfe.tag_length) !=
620 tfe.tag_length)
621 {
622 logf("read error #6");
623 return false;
624 }
625
626 buf[tfe.tag_length] = '\0';
627
628 return true;
629}
630
541static long check_virtual_tags(int tag, const struct index_entry *idx) 631static long check_virtual_tags(int tag, const struct index_entry *idx)
542{ 632{
543 long data = 0; 633 long data = 0;
@@ -671,6 +761,96 @@ static bool check_against_clause(long numeric, const char *str,
671 return false; 761 return false;
672} 762}
673 763
764bool check_clauses(struct tagcache_search *tcs,
765 struct index_entry *idx,
766 struct tagcache_search_clause **clause, int count)
767{
768 int i;
769
770#ifdef HAVE_TC_RAMCACHE
771 if (tcs->ramsearch)
772 {
773 /* Go through all conditional clauses. */
774 for (i = 0; i < count; i++)
775 {
776 struct tagfile_entry *tfe;
777 int seek;
778 char buf[256];
779 char *str = NULL;
780
781 seek = check_virtual_tags(clause[i]->tag, idx);
782
783 if (!tagcache_is_numeric_tag(clause[i]->tag))
784 {
785 if (clause[i]->tag == tag_filename)
786 {
787 retrieve(tcs, idx, tag_filename, buf, sizeof buf);
788 str = buf;
789 }
790 else
791 {
792 tfe = (struct tagfile_entry *)&hdr->tags[clause[i]->tag][seek];
793 str = tfe->tag_data;
794 }
795 }
796
797 if (!check_against_clause(seek, str, clause[i]))
798 return false;
799 }
800 }
801 else
802#endif
803 {
804 /* Check for conditions. */
805 for (i = 0; i < count; i++)
806 {
807 struct tagfile_entry tfe;
808 int seek;
809 char str[256];
810
811 seek = check_virtual_tags(clause[i]->tag, idx);
812
813 memset(str, 0, sizeof str);
814 if (!tagcache_is_numeric_tag(clause[i]->tag))
815 {
816 int fd = tcs->idxfd[clause[i]->tag];
817 lseek(fd, seek, SEEK_SET);
818 read(fd, &tfe, sizeof(struct tagfile_entry));
819 if (tfe.tag_length >= (int)sizeof(str))
820 {
821 logf("Too long tag read!");
822 break ;
823 }
824
825 read(fd, str, tfe.tag_length);
826
827 /* Check if entry has been deleted. */
828 if (str[0] == '\0')
829 break;
830 }
831
832 if (!check_against_clause(seek, str, clause[i]))
833 return false;
834 }
835 }
836
837 return true;
838}
839
840bool tagcache_check_clauses(struct tagcache_search *tcs,
841 struct tagcache_search_clause **clause, int count)
842{
843 struct index_entry idx;
844
845 if (count == 0)
846 return true;
847
848 if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true))
849 return false;
850
851 return check_clauses(tcs, &idx, clause, count);
852}
853
674static bool add_uniqbuf(struct tagcache_search *tcs, long id) 854static bool add_uniqbuf(struct tagcache_search *tcs, long id)
675{ 855{
676 int i; 856 int i;
@@ -713,18 +893,18 @@ static bool build_lookup_list(struct tagcache_search *tcs)
713 893
714 for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++) 894 for (i = tcs->seek_pos; i < hdr->h.tch.entry_count; i++)
715 { 895 {
896 struct index_entry *idx = &hdr->indices[i];
716 if (tcs->seek_list_count == SEEK_LIST_SIZE) 897 if (tcs->seek_list_count == SEEK_LIST_SIZE)
717 break ; 898 break ;
718 899
719 /* Skip deleted files. */ 900 /* Skip deleted files. */
720 if (hdr->indices[i].flag & FLAG_DELETED) 901 if (idx->flag & FLAG_DELETED)
721 continue; 902 continue;
722 903
723 /* Go through all filters.. */ 904 /* Go through all filters.. */
724 for (j = 0; j < tcs->filter_count; j++) 905 for (j = 0; j < tcs->filter_count; j++)
725 { 906 {
726 if (hdr->indices[i].tag_seek[tcs->filter_tag[j]] != 907 if (idx->tag_seek[tcs->filter_tag[j]] != tcs->filter_seek[j])
727 tcs->filter_seek[j])
728 { 908 {
729 break ; 909 break ;
730 } 910 }
@@ -733,51 +913,17 @@ static bool build_lookup_list(struct tagcache_search *tcs)
733 if (j < tcs->filter_count) 913 if (j < tcs->filter_count)
734 continue ; 914 continue ;
735 915
736 /* Go through all conditional clauses. */ 916 /* Check for conditions. */
737 for (j = 0; j < tcs->clause_count; j++) 917 if (!check_clauses(tcs, idx, tcs->clause, tcs->clause_count))
738 { 918 continue;
739 struct index_entry *idx = &hdr->indices[i];
740 int seek;
741 char buf[256];
742 char *str = NULL;
743 struct tagfile_entry *entry;
744
745 seek = check_virtual_tags(tcs->clause[j]->tag, idx);
746
747 if (!tagcache_is_numeric_tag(tcs->clause[j]->tag))
748 {
749 if (tcs->clause[j]->tag == tag_filename)
750 {
751 int oldtype = tcs->type;
752 tcs->type = tag_filename;
753 tagcache_retrieve(tcs, i, buf, sizeof buf);
754 tcs->type = oldtype;
755 str = buf;
756 }
757 else
758 {
759 entry = (struct tagfile_entry *)&hdr->tags[tcs->clause[j]->tag][seek];
760 str = entry->tag_data;
761 }
762 }
763
764
765 if (!check_against_clause(seek, str, tcs->clause[j]))
766 break ;
767 }
768
769 if (j < tcs->clause_count)
770 continue ;
771 919
772 /* Add to the seek list if not already in uniq buffer. */ 920 /* Add to the seek list if not already in uniq buffer. */
773 if (!add_uniqbuf(tcs, hdr->indices[i].tag_seek[tcs->type])) 921 if (!add_uniqbuf(tcs, idx->tag_seek[tcs->type]))
774 continue; 922 continue;
775 923
776 /* Lets add it. */ 924 /* Lets add it. */
777 tcs->seek_list[tcs->seek_list_count] = 925 tcs->seek_list[tcs->seek_list_count] = idx->tag_seek[tcs->type];
778 hdr->indices[i].tag_seek[tcs->type]; 926 tcs->seek_flags[tcs->seek_list_count] = idx->flag;
779 tcs->seek_flags[tcs->seek_list_count] =
780 hdr->indices[i].flag;
781 tcs->seek_list_count++; 927 tcs->seek_list_count++;
782 } 928 }
783 929
@@ -813,39 +959,8 @@ static bool build_lookup_list(struct tagcache_search *tcs)
813 continue ; 959 continue ;
814 960
815 /* Check for conditions. */ 961 /* Check for conditions. */
816 for (i = 0; i < tcs->clause_count; i++) 962 if (!check_clauses(tcs, &entry, tcs->clause, tcs->clause_count))
817 { 963 continue;
818 struct tagfile_entry tfe;
819 int seek;
820 char str[256];
821
822 seek = check_virtual_tags(tcs->clause[i]->tag, &entry);
823
824 memset(str, 0, sizeof str);
825 if (!tagcache_is_numeric_tag(tcs->clause[i]->tag))
826 {
827 int fd = tcs->idxfd[tcs->clause[i]->tag];
828 lseek(fd, seek, SEEK_SET);
829 read(fd, &tfe, sizeof(struct tagfile_entry));
830 if (tfe.tag_length >= (int)sizeof(str))
831 {
832 logf("Too long tag read!");
833 break ;
834 }
835
836 read(fd, str, tfe.tag_length);
837
838 /* Check if entry has been deleted. */
839 if (str[0] == '\0')
840 break;
841 }
842
843 if (!check_against_clause(seek, str, tcs->clause[i]))
844 break ;
845 }
846
847 if (i < tcs->clause_count)
848 continue ;
849 964
850 /* Add to the seek list if not already in uniq buffer. */ 965 /* Add to the seek list if not already in uniq buffer. */
851 if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type])) 966 if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type]))
@@ -1025,25 +1140,6 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1025 return true; 1140 return true;
1026} 1141}
1027 1142
1028static bool open_files(struct tagcache_search *tcs)
1029{
1030 if (tcs->idxfd[tcs->type] < 0)
1031 {
1032 char fn[MAX_PATH];
1033
1034 snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tcs->type);
1035 tcs->idxfd[tcs->type] = open(fn, O_RDONLY);
1036 }
1037
1038 if (tcs->idxfd[tcs->type] < 0)
1039 {
1040 logf("File not open!");
1041 return false;
1042 }
1043
1044 return true;
1045}
1046
1047#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \ 1143#define TAG_FILENAME_RAM(tcs) ((tcs->type == tag_filename) \
1048 ? (flag & FLAG_DIRCACHE) : 1) 1144 ? (flag & FLAG_DIRCACHE) : 1)
1049 1145
@@ -1085,7 +1181,7 @@ static bool get_next(struct tagcache_search *tcs)
1085 if ((!tcs->ramsearch || !TAG_FILENAME_RAM(tcs)) 1181 if ((!tcs->ramsearch || !TAG_FILENAME_RAM(tcs))
1086 && !tagcache_is_numeric_tag(tcs->type)) 1182 && !tagcache_is_numeric_tag(tcs->type))
1087 { 1183 {
1088 if (!open_files(tcs)) 1184 if (!open_files(tcs, tcs->type))
1089 return false; 1185 return false;
1090 1186
1091 lseek(tcs->idxfd[tcs->type], tcs->seek_list[tcs->seek_list_count], SEEK_SET); 1187 lseek(tcs->idxfd[tcs->type], tcs->seek_list[tcs->seek_list_count], SEEK_SET);
@@ -1144,7 +1240,7 @@ static bool get_next(struct tagcache_search *tcs)
1144 else 1240 else
1145#endif 1241#endif
1146 { 1242 {
1147 if (!open_files(tcs)) 1243 if (!open_files(tcs, tcs->type))
1148 return false; 1244 return false;
1149 1245
1150 tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR); 1246 tcs->result_seek = lseek(tcs->idxfd[tcs->type], 0, SEEK_CUR);
@@ -1193,72 +1289,13 @@ bool tagcache_get_next(struct tagcache_search *tcs)
1193bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, 1289bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
1194 char *buf, long size) 1290 char *buf, long size)
1195{ 1291{
1196 struct tagfile_entry tfe;
1197 struct index_entry idx; 1292 struct index_entry idx;
1198 long seek;
1199 1293
1200 *buf = '\0'; 1294 *buf = '\0';
1201 if (!get_index(tcs->masterfd, idxid, &idx, true)) 1295 if (!get_index(tcs->masterfd, idxid, &idx, true))
1202 return false; 1296 return false;
1203 1297
1204 seek = idx.tag_seek[tcs->type]; 1298 return retrieve(tcs, &idx, tcs->type, buf, size);
1205 if (seek < 0)
1206 {
1207 logf("Retrieve failed");
1208 return false;
1209 }
1210
1211#ifdef HAVE_TC_RAMCACHE
1212 if (tcs->ramsearch)
1213 {
1214 struct tagfile_entry *ep;
1215
1216# ifdef HAVE_DIRCACHE
1217 if (tcs->type == tag_filename && hdr->indices[idxid].flag & FLAG_DIRCACHE)
1218 {
1219 dircache_copy_path((struct dircache_entry *)seek,
1220 buf, size);
1221 return true;
1222 }
1223 else
1224# endif
1225 if (tcs->type != tag_filename)
1226 {
1227 ep = (struct tagfile_entry *)&hdr->tags[tcs->type][seek];
1228 strncpy(buf, ep->tag_data, size-1);
1229
1230 return true;
1231 }
1232 }
1233#endif
1234
1235 if (!open_files(tcs))
1236 return false;
1237
1238 lseek(tcs->idxfd[tcs->type], seek, SEEK_SET);
1239 if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) !=
1240 sizeof(struct tagfile_entry))
1241 {
1242 logf("read error #5");
1243 return false;
1244 }
1245
1246 if (tfe.tag_length >= size)
1247 {
1248 logf("too small buffer");
1249 return false;
1250 }
1251
1252 if (read(tcs->idxfd[tcs->type], buf, tfe.tag_length) !=
1253 tfe.tag_length)
1254 {
1255 logf("read error #6");
1256 return false;
1257 }
1258
1259 buf[tfe.tag_length] = '\0';
1260
1261 return true;
1262} 1299}
1263 1300
1264#if 0 1301#if 0
@@ -2961,11 +2998,13 @@ static bool delete_entry(long idx_id)
2961 2998
2962 /* Skip the header block */ 2999 /* Skip the header block */
2963 lseek(fd, myidx.tag_seek[tag] + sizeof(struct tagfile_entry), SEEK_SET); 3000 lseek(fd, myidx.tag_seek[tag] + sizeof(struct tagfile_entry), SEEK_SET);
2964 3001
3002 /* Debug, print 10 first characters of the tag
2965 read(fd, buf, 10); 3003 read(fd, buf, 10);
2966 buf[10]='\0'; 3004 buf[10]='\0';
2967 logf("TAG:%s", buf); 3005 logf("TAG:%s", buf);
2968 lseek(fd, -10, SEEK_CUR); 3006 lseek(fd, -10, SEEK_CUR);
3007 */
2969 3008
2970 /* Write first data byte in tag as \0 */ 3009 /* Write first data byte in tag as \0 */
2971 write(fd, "", 1); 3010 write(fd, "", 1);