summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-04-03 18:57:34 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-04-03 18:57:34 +0000
commit4c6fd0f4c008946760cab37da5f5c270bf0ef18a (patch)
tree97807d6d3f961db1f547bad15b7149e6bd8dec2a
parenta99bc99b665af9270ae8cada6ae32d4e8705f3d3 (diff)
downloadrockbox-4c6fd0f4c008946760cab37da5f5c270bf0ef18a.tar.gz
rockbox-4c6fd0f4c008946760cab37da5f5c270bf0ef18a.zip
Initial conditional filtering support for the tagcache engine and a
fix while building the lookup list. UI part not yet ready. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9465 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/tagcache.c158
-rw-r--r--apps/tagcache.h21
2 files changed, 145 insertions, 34 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 6567a781f8..25728fa6f1 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -132,7 +132,7 @@ static int total_entry_count = 0;
132static int data_size = 0; 132static int data_size = 0;
133static int processed_dir_count; 133static int processed_dir_count;
134 134
135static bool is_numeric_tag(int type) 135bool tagcache_is_numeric_tag(int type)
136{ 136{
137 int i; 137 int i;
138 138
@@ -326,11 +326,9 @@ static struct index_entry *find_entry_disk(const char *filename, bool retrieve)
326 326
327long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) 327long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
328{ 328{
329 struct tagcache_header tch;
330 struct index_entry idx; 329 struct index_entry idx;
331 int masterfd;
332 330
333 if (!is_numeric_tag(tag)) 331 if (!tagcache_is_numeric_tag(tag))
334 return -1; 332 return -1;
335 333
336#ifdef HAVE_TC_RAMCACHE 334#ifdef HAVE_TC_RAMCACHE
@@ -340,34 +338,48 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
340 } 338 }
341#endif 339#endif
342 340
343 masterfd = open(TAGCACHE_FILE_MASTER, O_RDONLY); 341 lseek(tcs->masterfd, tcs->idx_id * sizeof(struct index_entry), SEEK_CUR);
344 342 if (read(tcs->masterfd, &idx, sizeof(struct index_entry)) !=
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)) 343 sizeof(struct index_entry))
361 { 344 {
362 logf("read error #3"); 345 logf("read error #3");
363 close(masterfd);
364 return -4; 346 return -4;
365 } 347 }
366 close(masterfd);
367 348
368 return idx.tag_seek[tag]; 349 return idx.tag_seek[tag];
369} 350}
370 351
352static bool check_against_clause(long numeric, const char *str,
353 const struct tagcache_search_clause *clause)
354{
355 switch (clause->type)
356 {
357 case clause_is:
358 if (clause->numeric)
359 return numeric == clause->numeric_data;
360 else
361 return !strcasecmp(clause->str, str);
362
363 case clause_gt:
364 return numeric > clause->numeric_data;
365 case clause_gteq:
366 return numeric >= clause->numeric_data;
367 case clause_lt:
368 return numeric < clause->numeric_data;
369 case clause_lteq:
370 return numeric <= clause->numeric_data;
371
372 case clause_contains:
373 return (strcasestr(str, clause->str) != NULL);
374 case clause_begins_with:
375 return (strcasestr(str, clause->str) == str);
376 case clause_ends_with: /* Not supported yet */
377 return false;
378 }
379
380 return false;
381}
382
371static bool build_lookup_list(struct tagcache_search *tcs) 383static bool build_lookup_list(struct tagcache_search *tcs)
372{ 384{
373 struct tagcache_header header; 385 struct tagcache_header header;
@@ -382,7 +394,7 @@ static bool build_lookup_list(struct tagcache_search *tcs)
382 { 394 {
383 int j; 395 int j;
384 396
385 for (i = tcs->seek_pos; i < hdr->h.entry_count - tcs->seek_pos; i++) 397 for (i = tcs->seek_pos; i < hdr->h.entry_count; i++)
386 { 398 {
387 if (tcs->seek_list_count == SEEK_LIST_SIZE) 399 if (tcs->seek_list_count == SEEK_LIST_SIZE)
388 break ; 400 break ;
@@ -397,6 +409,25 @@ static bool build_lookup_list(struct tagcache_search *tcs)
397 if (j < tcs->filter_count) 409 if (j < tcs->filter_count)
398 continue ; 410 continue ;
399 411
412 for (j = 0; j < tcs->clause_count; j++)
413 {
414 int seek = hdr->indices[i].tag_seek[tcs->clause[j]->tag];
415 char *str = NULL;
416 struct tagfile_entry *entry;
417
418 if (!tagcache_is_numeric_tag(tcs->clause[j]->tag))
419 {
420 entry = (struct tagfile_entry *)&hdr->tags[tcs->clause[j]->tag][seek];
421 str = entry->tag_data;
422 }
423
424 if (!check_against_clause(seek, str, tcs->clause[j]))
425 break ;
426 }
427
428 if (j < tcs->clause_count)
429 continue ;
430
400 /* Add to the seek list if not already there. */ 431 /* Add to the seek list if not already there. */
401 for (j = 0; j < tcs->seek_list_count; j++) 432 for (j = 0; j < tcs->seek_list_count; j++)
402 { 433 {
@@ -455,6 +486,26 @@ static bool build_lookup_list(struct tagcache_search *tcs)
455 if (i < tcs->filter_count) 486 if (i < tcs->filter_count)
456 continue ; 487 continue ;
457 488
489 /* Check for conditions. */
490 for (i = 0; i < tcs->clause_count; i++)
491 {
492 int seek = entry.tag_seek[tcs->clause[i]->tag];
493 char str[64];
494
495 memset(str, 0, sizeof str);
496 if (!tagcache_is_numeric_tag(tcs->clause[i]->tag))
497 {
498 /* FIXME: Not yet implemented. */
499 // str = &hdr->tags[tcs->clause[i].tag][seek];
500 }
501
502 if (!check_against_clause(seek, str, tcs->clause[i]))
503 break ;
504 }
505
506 if (i < tcs->clause_count)
507 continue ;
508
458 /* Add to the seek list if not already there. */ 509 /* Add to the seek list if not already there. */
459 for (i = 0; i < tcs->seek_list_count; i++) 510 for (i = 0; i < tcs->seek_list_count; i++)
460 { 511 {
@@ -484,6 +535,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
484 if (tcs->valid) 535 if (tcs->valid)
485 tagcache_search_finish(tcs); 536 tagcache_search_finish(tcs);
486 537
538 memset(tcs, 0, sizeof(struct tagcache_search));
487 tcs->position = sizeof(struct tagcache_header); 539 tcs->position = sizeof(struct tagcache_header);
488 tcs->fd = -1; 540 tcs->fd = -1;
489 tcs->type = tag; 541 tcs->type = tag;
@@ -491,6 +543,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
491 tcs->seek_list_count = 0; 543 tcs->seek_list_count = 0;
492 tcs->filter_count = 0; 544 tcs->filter_count = 0;
493 tcs->valid = true; 545 tcs->valid = true;
546 tcs->masterfd = -1;
494 547
495#ifndef HAVE_TC_RAMCACHE 548#ifndef HAVE_TC_RAMCACHE
496 tcs->ramsearch = false; 549 tcs->ramsearch = false;
@@ -503,7 +556,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
503 else 556 else
504#endif 557#endif
505 { 558 {
506 if (is_numeric_tag(tcs->type)) 559 if (tagcache_is_numeric_tag(tcs->type))
507 return true; 560 return true;
508 561
509 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type); 562 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tcs->type);
@@ -521,6 +574,23 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
521 logf("incorrect header"); 574 logf("incorrect header");
522 return false; 575 return false;
523 } 576 }
577
578 tcs->masterfd = open(TAGCACHE_FILE_MASTER, O_RDONLY);
579
580 if (tcs->masterfd < 0)
581 {
582 logf("open fail");
583 return false;
584 }
585
586 if (read(tcs->masterfd, &h, sizeof(struct tagcache_header)) !=
587 sizeof(struct tagcache_header) || h.magic != TAGCACHE_MAGIC)
588 {
589 logf("header error");
590 close(tcs->masterfd);
591 tcs->masterfd = -1;
592 return false;
593 }
524 } 594 }
525 595
526 return true; 596 return true;
@@ -539,6 +609,21 @@ bool tagcache_search_add_filter(struct tagcache_search *tcs,
539 return true; 609 return true;
540} 610}
541 611
612bool tagcache_search_add_clause(struct tagcache_search *tcs,
613 struct tagcache_search_clause *clause)
614{
615 if (tcs->clause_count >= TAGCACHE_MAX_CLAUSES)
616 {
617 logf("Too many clauses");
618 return false;
619 }
620
621 tcs->clause[tcs->clause_count] = clause;
622 tcs->clause_count++;
623
624 return true;
625}
626
542bool tagcache_get_next(struct tagcache_search *tcs) 627bool tagcache_get_next(struct tagcache_search *tcs)
543{ 628{
544 static char buf[MAX_PATH]; 629 static char buf[MAX_PATH];
@@ -547,7 +632,7 @@ bool tagcache_get_next(struct tagcache_search *tcs)
547 if (!tcs->valid) 632 if (!tcs->valid)
548 return false; 633 return false;
549 634
550 if (tcs->fd < 0 && !is_numeric_tag(tcs->type) 635 if (tcs->fd < 0 && !tagcache_is_numeric_tag(tcs->type)
551#ifdef HAVE_TC_RAMCACHE 636#ifdef HAVE_TC_RAMCACHE
552 && !tcs->ramsearch 637 && !tcs->ramsearch
553#endif 638#endif
@@ -555,11 +640,11 @@ bool tagcache_get_next(struct tagcache_search *tcs)
555 return false; 640 return false;
556 641
557 /* Searching not supported for numeric tags yet. */ 642 /* Searching not supported for numeric tags yet. */
558 if (is_numeric_tag(tcs->type)) 643 if (tagcache_is_numeric_tag(tcs->type))
559 return false; 644 return false;
560 645
561 /* Relative fetch. */ 646 /* Relative fetch. */
562 if (tcs->filter_count > 0) 647 if (tcs->filter_count > 0 || tcs->clause_count > 0)
563 { 648 {
564 /* Check for end of list. */ 649 /* Check for end of list. */
565 if (tcs->seek_list_count == 0) 650 if (tcs->seek_list_count == 0)
@@ -672,9 +757,16 @@ void tagcache_search_finish(struct tagcache_search *tcs)
672 { 757 {
673 close(tcs->fd); 758 close(tcs->fd);
674 tcs->fd = -1; 759 tcs->fd = -1;
675 tcs->ramsearch = false;
676 tcs->valid = false;
677 } 760 }
761
762 if (tcs->masterfd >= 0)
763 {
764 close(tcs->masterfd);
765 tcs->masterfd = -1;
766 }
767
768 tcs->ramsearch = false;
769 tcs->valid = false;
678} 770}
679 771
680#ifdef HAVE_TC_RAMCACHE 772#ifdef HAVE_TC_RAMCACHE
@@ -846,7 +938,7 @@ static void remove_files(void)
846 remove(TAGCACHE_FILE_MASTER); 938 remove(TAGCACHE_FILE_MASTER);
847 for (i = 0; i < TAG_COUNT; i++) 939 for (i = 0; i < TAG_COUNT; i++)
848 { 940 {
849 if (is_numeric_tag(i)) 941 if (tagcache_is_numeric_tag(i))
850 continue; 942 continue;
851 943
852 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); 944 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i);
@@ -1593,7 +1685,7 @@ static bool commit(void)
1593 /* Now create the index files. */ 1685 /* Now create the index files. */
1594 for (i = 0; i < TAG_COUNT; i++) 1686 for (i = 0; i < TAG_COUNT; i++)
1595 { 1687 {
1596 if (is_numeric_tag(i)) 1688 if (tagcache_is_numeric_tag(i))
1597 { 1689 {
1598 build_numeric_index(i, &header, tmpfd); 1690 build_numeric_index(i, &header, tmpfd);
1599 } 1691 }
@@ -1760,7 +1852,7 @@ static bool load_tagcache(void)
1760 struct tagfile_entry *fe; 1852 struct tagfile_entry *fe;
1761 char buf[MAX_PATH]; 1853 char buf[MAX_PATH];
1762 1854
1763 if (is_numeric_tag(i)) 1855 if (tagcache_is_numeric_tag(i))
1764 continue ; 1856 continue ;
1765 1857
1766 //p = ((void *)p+1); 1858 //p = ((void *)p+1);
diff --git a/apps/tagcache.h b/apps/tagcache.h
index ddbb8e1dac..052d71b42b 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -39,14 +39,30 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
39 39
40#define SEEK_LIST_SIZE 50 40#define SEEK_LIST_SIZE 50
41#define TAGCACHE_MAX_FILTERS 3 41#define TAGCACHE_MAX_FILTERS 3
42#define TAGCACHE_MAX_CLAUSES 10
43
44enum clause { clause_none, clause_is, clause_gt, clause_gteq, clause_lt,
45 clause_lteq, clause_contains, clause_begins_with, clause_ends_with };
46enum modifies { clause_mod_none, clause_mod_not };
47
48struct tagcache_search_clause
49{
50 int tag;
51 int type;
52 bool numeric;
53 long numeric_data;
54 char str[32];
55};
42 56
43struct tagcache_search { 57struct tagcache_search {
44 /* For internal use only. */ 58 /* For internal use only. */
45 int fd; 59 int fd, masterfd;
46 long seek_list[SEEK_LIST_SIZE]; 60 long seek_list[SEEK_LIST_SIZE];
47 long filter_tag[TAGCACHE_MAX_FILTERS]; 61 long filter_tag[TAGCACHE_MAX_FILTERS];
48 long filter_seek[TAGCACHE_MAX_FILTERS]; 62 long filter_seek[TAGCACHE_MAX_FILTERS];
49 int filter_count; 63 int filter_count;
64 struct tagcache_search_clause *clause[TAGCACHE_MAX_CLAUSES];
65 int clause_count;
50 int seek_list_count; 66 int seek_list_count;
51 int seek_pos; 67 int seek_pos;
52 int idx_id; 68 int idx_id;
@@ -62,9 +78,12 @@ struct tagcache_search {
62 long result_seek; 78 long result_seek;
63}; 79};
64 80
81bool tagcache_is_numeric_tag(int type);
65bool tagcache_search(struct tagcache_search *tcs, int tag); 82bool tagcache_search(struct tagcache_search *tcs, int tag);
66bool tagcache_search_add_filter(struct tagcache_search *tcs, 83bool tagcache_search_add_filter(struct tagcache_search *tcs,
67 int tag, int seek); 84 int tag, int seek);
85bool tagcache_search_add_clause(struct tagcache_search *tcs,
86 struct tagcache_search_clause *clause);
68bool tagcache_get_next(struct tagcache_search *tcs); 87bool tagcache_get_next(struct tagcache_search *tcs);
69void tagcache_search_finish(struct tagcache_search *tcs); 88void tagcache_search_finish(struct tagcache_search *tcs);
70long tagcache_get_numeric(const struct tagcache_search *tcs, int tag); 89long tagcache_get_numeric(const struct tagcache_search *tcs, int tag);