diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-04-03 18:57:34 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-04-03 18:57:34 +0000 |
commit | 4c6fd0f4c008946760cab37da5f5c270bf0ef18a (patch) | |
tree | 97807d6d3f961db1f547bad15b7149e6bd8dec2a /apps/tagcache.c | |
parent | a99bc99b665af9270ae8cada6ae32d4e8705f3d3 (diff) | |
download | rockbox-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
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 158 |
1 files changed, 125 insertions, 33 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; | |||
132 | static int data_size = 0; | 132 | static int data_size = 0; |
133 | static int processed_dir_count; | 133 | static int processed_dir_count; |
134 | 134 | ||
135 | static bool is_numeric_tag(int type) | 135 | bool 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 | ||
327 | long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) | 327 | long 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 | ||
352 | static 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 | |||
371 | static bool build_lookup_list(struct tagcache_search *tcs) | 383 | static 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 | ||
612 | bool 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 | |||
542 | bool tagcache_get_next(struct tagcache_search *tcs) | 627 | bool 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); |