summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/tagcache.c103
-rw-r--r--apps/tagcache.h2
-rw-r--r--apps/tagtree.c24
3 files changed, 78 insertions, 51 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 75191d678e..7555781cbe 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -984,74 +984,86 @@ static bool check_against_clause(long numeric, const char *str,
984 984
985static bool check_clauses(struct tagcache_search *tcs, 985static bool check_clauses(struct tagcache_search *tcs,
986 struct index_entry *idx, 986 struct index_entry *idx,
987 struct tagcache_search_clause **clause, int count) 987 struct tagcache_search_clause **clauses, int count)
988{ 988{
989 int i; 989 int i;
990 990
991#ifdef HAVE_TC_RAMCACHE 991 /* Go through all conditional clauses. */
992 if (tcs->ramsearch) 992 for (i = 0; i < count; i++)
993 { 993 {
994 /* Go through all conditional clauses. */ 994 int seek;
995 for (i = 0; i < count; i++) 995 char buf[256];
996 char *str;
997 struct tagcache_search_clause *clause = clauses[i];
998
999 if (clause->type == clause_logical_or)
1000 break; /* all conditions before logical-or satisfied --
1001 stop processing clauses */
1002
1003#ifdef HAVE_TC_RAMCACHE
1004 str = NULL;
1005
1006 if (tcs->ramsearch)
996 { 1007 {
997 struct tagfile_entry *tfe; 1008 struct tagfile_entry *tfe;
998 int seek;
999 char buf[256];
1000 char *str = NULL;
1001 1009
1002 seek = check_virtual_tags(clause[i]->tag, tcs->idx_id, idx); 1010 seek = check_virtual_tags(clause->tag, tcs->idx_id, idx);
1003 1011
1004 if (!TAGCACHE_IS_NUMERIC(clause[i]->tag)) 1012 if (!TAGCACHE_IS_NUMERIC(clause->tag))
1005 { 1013 {
1006 if (clause[i]->tag == tag_filename) 1014 if (clause->tag == tag_filename)
1007 { 1015 {
1008 retrieve(tcs, idx, tag_filename, buf, sizeof buf); 1016 retrieve(tcs, idx, tag_filename, buf, sizeof buf);
1009 str = buf; 1017 str = buf;
1010 } 1018 }
1011 else 1019 else
1012 { 1020 {
1013 tfe = (struct tagfile_entry *)&hdr->tags[clause[i]->tag][seek]; 1021 tfe = (struct tagfile_entry *)&hdr->tags[clause->tag][seek];
1014 str = tfe->tag_data; 1022 str = tfe->tag_data;
1015 } 1023 }
1016 } 1024 }
1017
1018 if (!check_against_clause(seek, str, clause[i]))
1019 return false;
1020 } 1025 }
1021 } 1026 else
1022 else
1023#endif 1027#endif
1024 {
1025 /* Check for conditions. */
1026 for (i = 0; i < count; i++)
1027 { 1028 {
1028 struct tagfile_entry tfe; 1029 struct tagfile_entry tfe;
1029 int seek; 1030 str = buf;
1030 char str[256];
1031 1031
1032 seek = check_virtual_tags(clause[i]->tag, tcs->idx_id, idx); 1032 seek = check_virtual_tags(clause->tag, tcs->idx_id, idx);
1033 1033
1034 memset(str, 0, sizeof str); 1034 memset(buf, 0, sizeof buf);
1035 if (!TAGCACHE_IS_NUMERIC(clause[i]->tag)) 1035 if (!TAGCACHE_IS_NUMERIC(clause->tag))
1036 { 1036 {
1037 int fd = tcs->idxfd[clause[i]->tag]; 1037 int fd = tcs->idxfd[clause->tag];
1038 lseek(fd, seek, SEEK_SET); 1038 lseek(fd, seek, SEEK_SET);
1039 ecread_tagfile_entry(fd, &tfe); 1039 ecread_tagfile_entry(fd, &tfe);
1040 if (tfe.tag_length >= (int)sizeof(str)) 1040 if (tfe.tag_length >= (int)sizeof(buf))
1041 { 1041 {
1042 logf("Too long tag read!"); 1042 logf("Too long tag read!");
1043 break ; 1043 return false;
1044 } 1044 }
1045 1045
1046 read(fd, str, tfe.tag_length); 1046 read(fd, str, tfe.tag_length);
1047 1047
1048 /* Check if entry has been deleted. */ 1048 /* Check if entry has been deleted. */
1049 if (str[0] == '\0') 1049 if (str[0] == '\0')
1050 return false;
1051 }
1052 }
1053
1054 if (!check_against_clause(seek, str, clause))
1055 {
1056 /* Clause failed -- try finding a logical-or clause */
1057 while (++i < count)
1058 {
1059 if (clauses[i]->type == clause_logical_or)
1050 break; 1060 break;
1051 } 1061 }
1052 1062
1053 if (!check_against_clause(seek, str, clause[i])) 1063 if (i < count) /* Found logical-or? */
1054 return false; 1064 continue; /* Check clauses after logical-or */
1065
1066 return false;
1055 } 1067 }
1056 } 1068 }
1057 1069
@@ -1369,21 +1381,24 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1369 return false; 1381 return false;
1370 } 1382 }
1371 1383
1372 /* Check if there is already a similar filter in present (filters are 1384 if (clause->type != clause_logical_or)
1373 * much faster than clauses).
1374 */
1375 for (i = 0; i < tcs->filter_count; i++)
1376 {
1377 if (tcs->filter_tag[i] == clause->tag)
1378 return true;
1379 }
1380
1381 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0)
1382 { 1385 {
1383 char buf[MAX_PATH]; 1386 /* Check if there is already a similar filter in present (filters are
1384 1387 * much faster than clauses).
1385 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag); 1388 */
1386 tcs->idxfd[clause->tag] = open(buf, O_RDONLY); 1389 for (i = 0; i < tcs->filter_count; i++)
1390 {
1391 if (tcs->filter_tag[i] == clause->tag)
1392 return true;
1393 }
1394
1395 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0)
1396 {
1397 char buf[MAX_PATH];
1398
1399 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag);
1400 tcs->idxfd[clause->tag] = open(buf, O_RDONLY);
1401 }
1387 } 1402 }
1388 1403
1389 tcs->clause[tcs->clause_count] = clause; 1404 tcs->clause[tcs->clause_count] = clause;
diff --git a/apps/tagcache.h b/apps/tagcache.h
index 59f8b8bc9a..7351998c0a 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -120,7 +120,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
120enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq, 120enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq,
121 clause_lt, clause_lteq, clause_contains, clause_not_contains, 121 clause_lt, clause_lteq, clause_contains, clause_not_contains,
122 clause_begins_with, clause_not_begins_with, clause_ends_with, 122 clause_begins_with, clause_not_begins_with, clause_ends_with,
123 clause_not_ends_with, clause_oneof }; 123 clause_not_ends_with, clause_oneof, clause_logical_or };
124 124
125struct tagcache_stat { 125struct tagcache_stat {
126 bool initialized; /* Is tagcache currently busy? */ 126 bool initialized; /* Is tagcache currently busy? */
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 2a2e2b805b..e7f703154c 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -461,16 +461,18 @@ static int add_format(const char *buf)
461 461
462 while (1) 462 while (1)
463 { 463 {
464 struct tagcache_search_clause *newclause;
465
464 if (clause_count >= TAGCACHE_MAX_CLAUSES) 466 if (clause_count >= TAGCACHE_MAX_CLAUSES)
465 { 467 {
466 logf("too many clauses"); 468 logf("too many clauses");
467 break; 469 break;
468 } 470 }
469 471
470 formats[format_count]->clause[clause_count] = 472 newclause = buffer_alloc(sizeof(struct tagcache_search_clause));
471 buffer_alloc(sizeof(struct tagcache_search_clause));
472 473
473 if (!read_clause(formats[format_count]->clause[clause_count])) 474 formats[format_count]->clause[clause_count] = newclause;
475 if (!read_clause(newclause))
474 break; 476 break;
475 477
476 clause_count++; 478 clause_count++;
@@ -486,6 +488,7 @@ static int add_format(const char *buf)
486 488
487static int get_condition(struct search_instruction *inst) 489static int get_condition(struct search_instruction *inst)
488{ 490{
491 struct tagcache_search_clause *new_clause;
489 int clause_count; 492 int clause_count;
490 char buf[128]; 493 char buf[128];
491 494
@@ -530,10 +533,15 @@ static int get_condition(struct search_instruction *inst)
530 return false; 533 return false;
531 } 534 }
532 535
533 inst->clause[inst->tagorder_count][clause_count] = 536 new_clause = buffer_alloc(sizeof(struct tagcache_search_clause));
534 buffer_alloc(sizeof(struct tagcache_search_clause)); 537 inst->clause[inst->tagorder_count][clause_count] = new_clause;
535 538
536 if (!read_clause(inst->clause[inst->tagorder_count][clause_count])) 539 if (*strp == '|')
540 {
541 strp++;
542 new_clause->type = clause_logical_or;
543 }
544 else if (!read_clause(new_clause))
537 return -1; 545 return -1;
538 546
539 inst->clause_count[inst->tagorder_count]++; 547 inst->clause_count[inst->tagorder_count]++;
@@ -1502,6 +1510,10 @@ int tagtree_enter(struct tree_context* c)
1502 for (j = 0; j < csi->clause_count[i]; j++) 1510 for (j = 0; j < csi->clause_count[i]; j++)
1503 { 1511 {
1504 char* searchstring; 1512 char* searchstring;
1513
1514 if (csi->clause[i][j]->type == clause_logical_or)
1515 continue;
1516
1505 source = csi->clause[i][j]->source; 1517 source = csi->clause[i][j]->source;
1506 1518
1507 if (source == source_constant) 1519 if (source == source_constant)