diff options
-rw-r--r-- | apps/tagcache.c | 1074 |
1 files changed, 537 insertions, 537 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index e6a4e8e3c4..4c09336641 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -21,12 +21,12 @@ | |||
21 | 21 | ||
22 | /* | 22 | /* |
23 | * TagCache API | 23 | * TagCache API |
24 | * | 24 | * |
25 | * ----------x---------x------------------x----- | 25 | * ----------x---------x------------------x----- |
26 | * | | | External | 26 | * | | | External |
27 | * +---------------x-------+ | TagCache | Libraries | 27 | * +---------------x-------+ | TagCache | Libraries |
28 | * | Modification routines | | Core | | 28 | * | Modification routines | | Core | |
29 | * +-x---------x-----------+ | | | 29 | * +-x---------x-----------+ | | |
30 | * | (R/W) | | | | | 30 | * | (R/W) | | | | |
31 | * | +------x-------------x-+ +-------------x-----+ | | 31 | * | +------x-------------x-+ +-------------x-----+ | |
32 | * | | x==x Filters & clauses | | | 32 | * | | x==x Filters & clauses | | |
@@ -50,9 +50,9 @@ | |||
50 | * +-----------------+ \===x | | | 50 | * +-----------------+ \===x | | |
51 | * | | | | (R) | Ram DB Loader x============x DirCache | 51 | * | | | | (R) | Ram DB Loader x============x DirCache |
52 | * +-x----x---x---x---+ /==x | | (optional) | 52 | * +-x----x---x---x---+ /==x | | (optional) |
53 | * | Tagcache Disk DB x==/ +-----------------+ | | 53 | * | Tagcache Disk DB x==/ +-----------------+ | |
54 | * +------------------+ | | 54 | * +------------------+ | |
55 | * | 55 | * |
56 | */ | 56 | */ |
57 | 57 | ||
58 | /*#define LOGF_ENABLE*/ | 58 | /*#define LOGF_ENABLE*/ |
@@ -131,9 +131,9 @@ static int tempbuf_handle; | |||
131 | (1LU << tag_albumartist) | (1LU << tag_grouping)) | 131 | (1LU << tag_albumartist) | (1LU << tag_grouping)) |
132 | 132 | ||
133 | /* String presentation of the tags defined in tagcache.h. Must be in correct order! */ | 133 | /* String presentation of the tags defined in tagcache.h. Must be in correct order! */ |
134 | static const char *tags_str[] = { "artist", "album", "genre", "title", | 134 | static const char *tags_str[] = { "artist", "album", "genre", "title", |
135 | "filename", "composer", "comment", "albumartist", "grouping", "year", | 135 | "filename", "composer", "comment", "albumartist", "grouping", "year", |
136 | "discnumber", "tracknumber", "bitrate", "length", "playcount", "rating", | 136 | "discnumber", "tracknumber", "bitrate", "length", "playcount", "rating", |
137 | "playtime", "lastplayed", "commitid", "mtime", "lastelapsed", "lastoffset" }; | 137 | "playtime", "lastplayed", "commitid", "mtime", "lastelapsed", "lastoffset" }; |
138 | 138 | ||
139 | /* Status information of the tagcache. */ | 139 | /* Status information of the tagcache. */ |
@@ -146,7 +146,7 @@ enum tagcache_queue { | |||
146 | Q_IMPORT_CHANGELOG, | 146 | Q_IMPORT_CHANGELOG, |
147 | Q_UPDATE, | 147 | Q_UPDATE, |
148 | Q_REBUILD, | 148 | Q_REBUILD, |
149 | 149 | ||
150 | /* Internal tagcache command queue. */ | 150 | /* Internal tagcache command queue. */ |
151 | CMD_UPDATE_MASTER_HEADER, | 151 | CMD_UPDATE_MASTER_HEADER, |
152 | CMD_UPDATE_NUMERIC, | 152 | CMD_UPDATE_NUMERIC, |
@@ -263,14 +263,14 @@ static inline void tcrc_buffer_unlock(void) | |||
263 | 263 | ||
264 | #endif /* HAVE_TC_RAMCACHE */ | 264 | #endif /* HAVE_TC_RAMCACHE */ |
265 | 265 | ||
266 | /** | 266 | /** |
267 | * Full tag entries stored in a temporary file waiting | 267 | * Full tag entries stored in a temporary file waiting |
268 | * for commit to the cache. */ | 268 | * for commit to the cache. */ |
269 | struct temp_file_entry { | 269 | struct temp_file_entry { |
270 | long tag_offset[TAG_COUNT]; | 270 | long tag_offset[TAG_COUNT]; |
271 | short tag_length[TAG_COUNT]; | 271 | short tag_length[TAG_COUNT]; |
272 | long flag; | 272 | long flag; |
273 | 273 | ||
274 | long data_length; | 274 | long data_length; |
275 | }; | 275 | }; |
276 | 276 | ||
@@ -364,12 +364,12 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) | |||
364 | int fd; | 364 | int fd; |
365 | char buf[MAX_PATH]; | 365 | char buf[MAX_PATH]; |
366 | int rc; | 366 | int rc; |
367 | 367 | ||
368 | if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT) | 368 | if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT) |
369 | return -1; | 369 | return -1; |
370 | 370 | ||
371 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); | 371 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); |
372 | 372 | ||
373 | fd = open(buf, write ? O_RDWR : O_RDONLY); | 373 | fd = open(buf, write ? O_RDWR : O_RDONLY); |
374 | if (fd < 0) | 374 | if (fd < 0) |
375 | { | 375 | { |
@@ -377,7 +377,7 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) | |||
377 | tc_stat.ready = false; | 377 | tc_stat.ready = false; |
378 | return fd; | 378 | return fd; |
379 | } | 379 | } |
380 | 380 | ||
381 | /* Check the header. */ | 381 | /* Check the header. */ |
382 | rc = ecread(fd, hdr, 1, tagcache_header_ec, tc_stat.econ); | 382 | rc = ecread(fd, hdr, 1, tagcache_header_ec, tc_stat.econ); |
383 | if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header)) | 383 | if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header)) |
@@ -395,7 +395,7 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
395 | { | 395 | { |
396 | int fd; | 396 | int fd; |
397 | int rc; | 397 | int rc; |
398 | 398 | ||
399 | fd = open(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY); | 399 | fd = open(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY); |
400 | if (fd < 0) | 400 | if (fd < 0) |
401 | { | 401 | { |
@@ -403,9 +403,9 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
403 | tc_stat.ready = false; | 403 | tc_stat.ready = false; |
404 | return fd; | 404 | return fd; |
405 | } | 405 | } |
406 | 406 | ||
407 | tc_stat.econ = false; | 407 | tc_stat.econ = false; |
408 | 408 | ||
409 | /* Check the header. */ | 409 | /* Check the header. */ |
410 | rc = read(fd, hdr, sizeof(struct master_header)); | 410 | rc = read(fd, hdr, sizeof(struct master_header)); |
411 | if (hdr->tch.magic == TAGCACHE_MAGIC && rc == sizeof(struct master_header)) | 411 | if (hdr->tch.magic == TAGCACHE_MAGIC && rc == sizeof(struct master_header)) |
@@ -413,10 +413,10 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
413 | /* Success. */ | 413 | /* Success. */ |
414 | return fd; | 414 | return fd; |
415 | } | 415 | } |
416 | 416 | ||
417 | /* Trying to read again, this time with endianess correction enabled. */ | 417 | /* Trying to read again, this time with endianess correction enabled. */ |
418 | lseek(fd, 0, SEEK_SET); | 418 | lseek(fd, 0, SEEK_SET); |
419 | 419 | ||
420 | rc = ecread(fd, hdr, 1, master_header_ec, true); | 420 | rc = ecread(fd, hdr, 1, master_header_ec, true); |
421 | if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) | 421 | if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header)) |
422 | { | 422 | { |
@@ -427,7 +427,7 @@ static int open_master_fd(struct master_header *hdr, bool write) | |||
427 | } | 427 | } |
428 | 428 | ||
429 | tc_stat.econ = true; | 429 | tc_stat.econ = true; |
430 | 430 | ||
431 | return fd; | 431 | return fd; |
432 | } | 432 | } |
433 | 433 | ||
@@ -453,7 +453,7 @@ static long find_entry_ram(const char *filename) | |||
453 | { | 453 | { |
454 | static long last_pos = 0; | 454 | static long last_pos = 0; |
455 | struct dircache_fileref dcfref; | 455 | struct dircache_fileref dcfref; |
456 | 456 | ||
457 | /* Check if tagcache is loaded into ram. */ | 457 | /* Check if tagcache is loaded into ram. */ |
458 | if (!tc_stat.ramcache) | 458 | if (!tc_stat.ramcache) |
459 | return -1; | 459 | return -1; |
@@ -520,7 +520,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
520 | 520 | ||
521 | if (!tc_stat.ready) | 521 | if (!tc_stat.ready) |
522 | return -2; | 522 | return -2; |
523 | 523 | ||
524 | fd = filenametag_fd; | 524 | fd = filenametag_fd; |
525 | if (fd < 0 || localfd) | 525 | if (fd < 0 || localfd) |
526 | { | 526 | { |
@@ -528,9 +528,9 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
528 | if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0) | 528 | if ( (fd = open_tag_fd(&tch, tag_filename, false)) < 0) |
529 | return -1; | 529 | return -1; |
530 | } | 530 | } |
531 | 531 | ||
532 | check_again: | 532 | check_again: |
533 | 533 | ||
534 | if (last_pos > 0) | 534 | if (last_pos > 0) |
535 | lseek(fd, last_pos, SEEK_SET); | 535 | lseek(fd, last_pos, SEEK_SET); |
536 | else | 536 | else |
@@ -543,12 +543,12 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
543 | pos_history[i+1] = pos_history[i]; | 543 | pos_history[i+1] = pos_history[i]; |
544 | pos_history[0] = pos; | 544 | pos_history[0] = pos; |
545 | 545 | ||
546 | if (ecread_tagfile_entry(fd, &tfe) | 546 | if (ecread_tagfile_entry(fd, &tfe) |
547 | != sizeof(struct tagfile_entry)) | 547 | != sizeof(struct tagfile_entry)) |
548 | { | 548 | { |
549 | break ; | 549 | break ; |
550 | } | 550 | } |
551 | 551 | ||
552 | if (tfe.tag_length >= (long)sizeof(buf)) | 552 | if (tfe.tag_length >= (long)sizeof(buf)) |
553 | { | 553 | { |
554 | logf("too long tag #1"); | 554 | logf("too long tag #1"); |
@@ -558,7 +558,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
558 | last_pos = -1; | 558 | last_pos = -1; |
559 | return -2; | 559 | return -2; |
560 | } | 560 | } |
561 | 561 | ||
562 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) | 562 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) |
563 | { | 563 | { |
564 | logf("read error #2"); | 564 | logf("read error #2"); |
@@ -568,18 +568,18 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
568 | last_pos = -1; | 568 | last_pos = -1; |
569 | return -3; | 569 | return -3; |
570 | } | 570 | } |
571 | 571 | ||
572 | if (!strcmp(filename, buf)) | 572 | if (!strcmp(filename, buf)) |
573 | { | 573 | { |
574 | last_pos = pos_history[pos_history_idx]; | 574 | last_pos = pos_history[pos_history_idx]; |
575 | found = true; | 575 | found = true; |
576 | break ; | 576 | break ; |
577 | } | 577 | } |
578 | 578 | ||
579 | if (pos_history_idx < POS_HISTORY_COUNT - 1) | 579 | if (pos_history_idx < POS_HISTORY_COUNT - 1) |
580 | pos_history_idx++; | 580 | pos_history_idx++; |
581 | } | 581 | } |
582 | 582 | ||
583 | /* Not found? */ | 583 | /* Not found? */ |
584 | if (!found) | 584 | if (!found) |
585 | { | 585 | { |
@@ -589,63 +589,63 @@ static long find_entry_disk(const char *filename_raw, bool localfd) | |||
589 | logf("seek again"); | 589 | logf("seek again"); |
590 | goto check_again; | 590 | goto check_again; |
591 | } | 591 | } |
592 | 592 | ||
593 | if (fd != filenametag_fd || localfd) | 593 | if (fd != filenametag_fd || localfd) |
594 | close(fd); | 594 | close(fd); |
595 | return -4; | 595 | return -4; |
596 | } | 596 | } |
597 | 597 | ||
598 | if (fd != filenametag_fd || localfd) | 598 | if (fd != filenametag_fd || localfd) |
599 | close(fd); | 599 | close(fd); |
600 | 600 | ||
601 | return tfe.idx_id; | 601 | return tfe.idx_id; |
602 | } | 602 | } |
603 | 603 | ||
604 | static int find_index(const char *filename) | 604 | static int find_index(const char *filename) |
605 | { | 605 | { |
606 | long idx_id = -1; | 606 | long idx_id = -1; |
607 | 607 | ||
608 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 608 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
609 | idx_id = find_entry_ram(filename); | 609 | idx_id = find_entry_ram(filename); |
610 | #endif | 610 | #endif |
611 | 611 | ||
612 | if (idx_id < 0) | 612 | if (idx_id < 0) |
613 | idx_id = find_entry_disk(filename, true); | 613 | idx_id = find_entry_disk(filename, true); |
614 | 614 | ||
615 | return idx_id; | 615 | return idx_id; |
616 | } | 616 | } |
617 | 617 | ||
618 | bool tagcache_find_index(struct tagcache_search *tcs, const char *filename) | 618 | bool tagcache_find_index(struct tagcache_search *tcs, const char *filename) |
619 | { | 619 | { |
620 | int idx_id; | 620 | int idx_id; |
621 | 621 | ||
622 | if (!tc_stat.ready) | 622 | if (!tc_stat.ready) |
623 | return false; | 623 | return false; |
624 | 624 | ||
625 | idx_id = find_index(filename); | 625 | idx_id = find_index(filename); |
626 | if (idx_id < 0) | 626 | if (idx_id < 0) |
627 | return false; | 627 | return false; |
628 | 628 | ||
629 | if (!tagcache_search(tcs, tag_filename)) | 629 | if (!tagcache_search(tcs, tag_filename)) |
630 | return false; | 630 | return false; |
631 | 631 | ||
632 | tcs->entry_count = 0; | 632 | tcs->entry_count = 0; |
633 | tcs->idx_id = idx_id; | 633 | tcs->idx_id = idx_id; |
634 | 634 | ||
635 | return true; | 635 | return true; |
636 | } | 636 | } |
637 | 637 | ||
638 | static bool get_index(int masterfd, int idxid, | 638 | static bool get_index(int masterfd, int idxid, |
639 | struct index_entry *idx, bool use_ram) | 639 | struct index_entry *idx, bool use_ram) |
640 | { | 640 | { |
641 | bool localfd = false; | 641 | bool localfd = false; |
642 | 642 | ||
643 | if (idxid < 0) | 643 | if (idxid < 0) |
644 | { | 644 | { |
645 | logf("Incorrect idxid: %d", idxid); | 645 | logf("Incorrect idxid: %d", idxid); |
646 | return false; | 646 | return false; |
647 | } | 647 | } |
648 | 648 | ||
649 | #ifdef HAVE_TC_RAMCACHE | 649 | #ifdef HAVE_TC_RAMCACHE |
650 | if (tc_stat.ramcache && use_ram) | 650 | if (tc_stat.ramcache && use_ram) |
651 | { | 651 | { |
@@ -656,35 +656,35 @@ static bool get_index(int masterfd, int idxid, | |||
656 | return true; | 656 | return true; |
657 | } | 657 | } |
658 | #endif /* HAVE_TC_RAMCACHE */ | 658 | #endif /* HAVE_TC_RAMCACHE */ |
659 | 659 | ||
660 | if (masterfd < 0) | 660 | if (masterfd < 0) |
661 | { | 661 | { |
662 | struct master_header tcmh; | 662 | struct master_header tcmh; |
663 | 663 | ||
664 | localfd = true; | 664 | localfd = true; |
665 | masterfd = open_master_fd(&tcmh, false); | 665 | masterfd = open_master_fd(&tcmh, false); |
666 | if (masterfd < 0) | 666 | if (masterfd < 0) |
667 | return false; | 667 | return false; |
668 | } | 668 | } |
669 | 669 | ||
670 | lseek(masterfd, idxid * sizeof(struct index_entry) | 670 | lseek(masterfd, idxid * sizeof(struct index_entry) |
671 | + sizeof(struct master_header), SEEK_SET); | 671 | + sizeof(struct master_header), SEEK_SET); |
672 | if (ecread_index_entry(masterfd, idx) | 672 | if (ecread_index_entry(masterfd, idx) |
673 | != sizeof(struct index_entry)) | 673 | != sizeof(struct index_entry)) |
674 | { | 674 | { |
675 | logf("read error #3"); | 675 | logf("read error #3"); |
676 | if (localfd) | 676 | if (localfd) |
677 | close(masterfd); | 677 | close(masterfd); |
678 | 678 | ||
679 | return false; | 679 | return false; |
680 | } | 680 | } |
681 | 681 | ||
682 | if (localfd) | 682 | if (localfd) |
683 | close(masterfd); | 683 | close(masterfd); |
684 | 684 | ||
685 | if (idx->flag & FLAG_DELETED) | 685 | if (idx->flag & FLAG_DELETED) |
686 | return false; | 686 | return false; |
687 | 687 | ||
688 | return true; | 688 | return true; |
689 | 689 | ||
690 | (void)use_ram; | 690 | (void)use_ram; |
@@ -700,7 +700,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
700 | logf("memory only flags!"); | 700 | logf("memory only flags!"); |
701 | return false; | 701 | return false; |
702 | } | 702 | } |
703 | 703 | ||
704 | #ifdef HAVE_TC_RAMCACHE | 704 | #ifdef HAVE_TC_RAMCACHE |
705 | /* Only update numeric data. Writing the whole index to RAM by memcpy | 705 | /* Only update numeric data. Writing the whole index to RAM by memcpy |
706 | * destroys dircache pointers! | 706 | * destroys dircache pointers! |
@@ -708,7 +708,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
708 | if (tc_stat.ramcache) | 708 | if (tc_stat.ramcache) |
709 | { | 709 | { |
710 | struct index_entry *idx_ram = &tcramcache.hdr->indices[idxid]; | 710 | struct index_entry *idx_ram = &tcramcache.hdr->indices[idxid]; |
711 | 711 | ||
712 | for (int tag = 0; tag < TAG_COUNT; tag++) | 712 | for (int tag = 0; tag < TAG_COUNT; tag++) |
713 | { | 713 | { |
714 | if (TAGCACHE_IS_NUMERIC(tag)) | 714 | if (TAGCACHE_IS_NUMERIC(tag)) |
@@ -716,14 +716,14 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
716 | idx_ram->tag_seek[tag] = idx->tag_seek[tag]; | 716 | idx_ram->tag_seek[tag] = idx->tag_seek[tag]; |
717 | } | 717 | } |
718 | } | 718 | } |
719 | 719 | ||
720 | /* Don't touch the dircache flag or attributes. */ | 720 | /* Don't touch the dircache flag or attributes. */ |
721 | idx_ram->flag = (idx->flag & 0x0000ffff) | 721 | idx_ram->flag = (idx->flag & 0x0000ffff) |
722 | | (idx_ram->flag & (0xffff0000 | FLAG_DIRCACHE)); | 722 | | (idx_ram->flag & (0xffff0000 | FLAG_DIRCACHE)); |
723 | } | 723 | } |
724 | #endif /* HAVE_TC_RAMCACHE */ | 724 | #endif /* HAVE_TC_RAMCACHE */ |
725 | 725 | ||
726 | lseek(masterfd, idxid * sizeof(struct index_entry) | 726 | lseek(masterfd, idxid * sizeof(struct index_entry) |
727 | + sizeof(struct master_header), SEEK_SET); | 727 | + sizeof(struct master_header), SEEK_SET); |
728 | if (ecwrite_index_entry(masterfd, idx) != sizeof(struct index_entry)) | 728 | if (ecwrite_index_entry(masterfd, idx) != sizeof(struct index_entry)) |
729 | { | 729 | { |
@@ -731,7 +731,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
731 | logf("idxid: %d", idxid); | 731 | logf("idxid: %d", idxid); |
732 | return false; | 732 | return false; |
733 | } | 733 | } |
734 | 734 | ||
735 | return true; | 735 | return true; |
736 | } | 736 | } |
737 | 737 | ||
@@ -746,13 +746,13 @@ static bool open_files(struct tagcache_search *tcs, int tag) | |||
746 | snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag); | 746 | snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag); |
747 | tcs->idxfd[tag] = open(fn, O_RDONLY); | 747 | tcs->idxfd[tag] = open(fn, O_RDONLY); |
748 | } | 748 | } |
749 | 749 | ||
750 | if (tcs->idxfd[tag] < 0) | 750 | if (tcs->idxfd[tag] < 0) |
751 | { | 751 | { |
752 | logf("File not open!"); | 752 | logf("File not open!"); |
753 | return false; | 753 | return false; |
754 | } | 754 | } |
755 | 755 | ||
756 | return true; | 756 | return true; |
757 | } | 757 | } |
758 | 758 | ||
@@ -761,19 +761,19 @@ static bool retrieve(struct tagcache_search *tcs, IF_DIRCACHE(int idx_id,) | |||
761 | { | 761 | { |
762 | struct tagfile_entry tfe; | 762 | struct tagfile_entry tfe; |
763 | long seek; | 763 | long seek; |
764 | 764 | ||
765 | *buf = '\0'; | 765 | *buf = '\0'; |
766 | 766 | ||
767 | if (TAGCACHE_IS_NUMERIC(tag)) | 767 | if (TAGCACHE_IS_NUMERIC(tag)) |
768 | return false; | 768 | return false; |
769 | 769 | ||
770 | seek = idx->tag_seek[tag]; | 770 | seek = idx->tag_seek[tag]; |
771 | if (seek < 0) | 771 | if (seek < 0) |
772 | { | 772 | { |
773 | logf("Retrieve failed"); | 773 | logf("Retrieve failed"); |
774 | return false; | 774 | return false; |
775 | } | 775 | } |
776 | 776 | ||
777 | #ifdef HAVE_TC_RAMCACHE | 777 | #ifdef HAVE_TC_RAMCACHE |
778 | if (tcs->ramsearch) | 778 | if (tcs->ramsearch) |
779 | { | 779 | { |
@@ -790,36 +790,36 @@ static bool retrieve(struct tagcache_search *tcs, IF_DIRCACHE(int idx_id,) | |||
790 | struct tagfile_entry *ep = | 790 | struct tagfile_entry *ep = |
791 | (struct tagfile_entry *)&tcramcache.hdr->tags[tag][seek]; | 791 | (struct tagfile_entry *)&tcramcache.hdr->tags[tag][seek]; |
792 | strlcpy(buf, ep->tag_data, size); | 792 | strlcpy(buf, ep->tag_data, size); |
793 | 793 | ||
794 | return true; | 794 | return true; |
795 | } | 795 | } |
796 | } | 796 | } |
797 | #endif /* HAVE_TC_RAMCACHE */ | 797 | #endif /* HAVE_TC_RAMCACHE */ |
798 | 798 | ||
799 | if (!open_files(tcs, tag)) | 799 | if (!open_files(tcs, tag)) |
800 | return false; | 800 | return false; |
801 | 801 | ||
802 | lseek(tcs->idxfd[tag], seek, SEEK_SET); | 802 | lseek(tcs->idxfd[tag], seek, SEEK_SET); |
803 | if (ecread_tagfile_entry(tcs->idxfd[tag], &tfe) | 803 | if (ecread_tagfile_entry(tcs->idxfd[tag], &tfe) |
804 | != sizeof(struct tagfile_entry)) | 804 | != sizeof(struct tagfile_entry)) |
805 | { | 805 | { |
806 | logf("read error #5"); | 806 | logf("read error #5"); |
807 | return false; | 807 | return false; |
808 | } | 808 | } |
809 | 809 | ||
810 | if (tfe.tag_length >= size) | 810 | if (tfe.tag_length >= size) |
811 | { | 811 | { |
812 | logf("too small buffer"); | 812 | logf("too small buffer"); |
813 | return false; | 813 | return false; |
814 | } | 814 | } |
815 | 815 | ||
816 | if (read(tcs->idxfd[tag], buf, tfe.tag_length) != | 816 | if (read(tcs->idxfd[tag], buf, tfe.tag_length) != |
817 | tfe.tag_length) | 817 | tfe.tag_length) |
818 | { | 818 | { |
819 | logf("read error #6"); | 819 | logf("read error #6"); |
820 | return false; | 820 | return false; |
821 | } | 821 | } |
822 | 822 | ||
823 | buf[tfe.tag_length] = '\0'; | 823 | buf[tfe.tag_length] = '\0'; |
824 | 824 | ||
825 | return true; | 825 | return true; |
@@ -844,7 +844,7 @@ static long find_tag(int tag, int idx_id, const struct index_entry *idx) | |||
844 | { | 844 | { |
845 | if (--ridx < 0) | 845 | if (--ridx < 0) |
846 | ridx = TAGCACHE_COMMAND_QUEUE_LENGTH - 1; | 846 | ridx = TAGCACHE_COMMAND_QUEUE_LENGTH - 1; |
847 | 847 | ||
848 | if (command_queue[ridx].command == CMD_UPDATE_NUMERIC | 848 | if (command_queue[ridx].command == CMD_UPDATE_NUMERIC |
849 | && command_queue[ridx].idx_id == idx_id | 849 | && command_queue[ridx].idx_id == idx_id |
850 | && command_queue[ridx].tag == tag) | 850 | && command_queue[ridx].tag == tag) |
@@ -872,31 +872,31 @@ static long find_tag(int tag, int idx_id, const struct index_entry *idx) | |||
872 | } | 872 | } |
873 | 873 | ||
874 | 874 | ||
875 | static long check_virtual_tags(int tag, int idx_id, | 875 | static long check_virtual_tags(int tag, int idx_id, |
876 | const struct index_entry *idx) | 876 | const struct index_entry *idx) |
877 | { | 877 | { |
878 | long data = 0; | 878 | long data = 0; |
879 | 879 | ||
880 | switch (tag) | 880 | switch (tag) |
881 | { | 881 | { |
882 | case tag_virt_length_sec: | 882 | case tag_virt_length_sec: |
883 | data = (find_tag(tag_length, idx_id, idx)/1000) % 60; | 883 | data = (find_tag(tag_length, idx_id, idx)/1000) % 60; |
884 | break; | 884 | break; |
885 | 885 | ||
886 | case tag_virt_length_min: | 886 | case tag_virt_length_min: |
887 | data = (find_tag(tag_length, idx_id, idx)/1000) / 60; | 887 | data = (find_tag(tag_length, idx_id, idx)/1000) / 60; |
888 | break; | 888 | break; |
889 | 889 | ||
890 | case tag_virt_playtime_sec: | 890 | case tag_virt_playtime_sec: |
891 | data = (find_tag(tag_playtime, idx_id, idx)/1000) % 60; | 891 | data = (find_tag(tag_playtime, idx_id, idx)/1000) % 60; |
892 | break; | 892 | break; |
893 | 893 | ||
894 | case tag_virt_playtime_min: | 894 | case tag_virt_playtime_min: |
895 | data = (find_tag(tag_playtime, idx_id, idx)/1000) / 60; | 895 | data = (find_tag(tag_playtime, idx_id, idx)/1000) / 60; |
896 | break; | 896 | break; |
897 | 897 | ||
898 | case tag_virt_autoscore: | 898 | case tag_virt_autoscore: |
899 | if (find_tag(tag_length, idx_id, idx) == 0 | 899 | if (find_tag(tag_length, idx_id, idx) == 0 |
900 | || find_tag(tag_playcount, idx_id, idx) == 0) | 900 | || find_tag(tag_playcount, idx_id, idx) == 0) |
901 | { | 901 | { |
902 | data = 0; | 902 | data = 0; |
@@ -913,21 +913,21 @@ static long check_virtual_tags(int tag, int idx_id, | |||
913 | autoscore = 100 * (alpha / playcout + beta / length / playcount) | 913 | autoscore = 100 * (alpha / playcout + beta / length / playcount) |
914 | Both terms should be small enough to avoid any overflow | 914 | Both terms should be small enough to avoid any overflow |
915 | */ | 915 | */ |
916 | data = 100 * (find_tag(tag_playtime, idx_id, idx) | 916 | data = 100 * (find_tag(tag_playtime, idx_id, idx) |
917 | / find_tag(tag_length, idx_id, idx)) | 917 | / find_tag(tag_length, idx_id, idx)) |
918 | + (100 * (find_tag(tag_playtime, idx_id, idx) | 918 | + (100 * (find_tag(tag_playtime, idx_id, idx) |
919 | % find_tag(tag_length, idx_id, idx))) | 919 | % find_tag(tag_length, idx_id, idx))) |
920 | / find_tag(tag_length, idx_id, idx); | 920 | / find_tag(tag_length, idx_id, idx); |
921 | data /= find_tag(tag_playcount, idx_id, idx); | 921 | data /= find_tag(tag_playcount, idx_id, idx); |
922 | } | 922 | } |
923 | break; | 923 | break; |
924 | 924 | ||
925 | /* How many commits before the file has been added to the DB. */ | 925 | /* How many commits before the file has been added to the DB. */ |
926 | case tag_virt_entryage: | 926 | case tag_virt_entryage: |
927 | data = current_tcmh.commitid | 927 | data = current_tcmh.commitid |
928 | - find_tag(tag_commitid, idx_id, idx) - 1; | 928 | - find_tag(tag_commitid, idx_id, idx) - 1; |
929 | break; | 929 | break; |
930 | 930 | ||
931 | case tag_virt_basename: | 931 | case tag_virt_basename: |
932 | tag = tag_filename; /* return filename; caller handles basename */ | 932 | tag = tag_filename; /* return filename; caller handles basename */ |
933 | /* FALLTHRU */ | 933 | /* FALLTHRU */ |
@@ -935,23 +935,23 @@ static long check_virtual_tags(int tag, int idx_id, | |||
935 | default: | 935 | default: |
936 | data = find_tag(tag, idx_id, idx); | 936 | data = find_tag(tag, idx_id, idx); |
937 | } | 937 | } |
938 | 938 | ||
939 | return data; | 939 | return data; |
940 | } | 940 | } |
941 | 941 | ||
942 | long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) | 942 | long tagcache_get_numeric(const struct tagcache_search *tcs, int tag) |
943 | { | 943 | { |
944 | struct index_entry idx; | 944 | struct index_entry idx; |
945 | 945 | ||
946 | if (!tc_stat.ready) | 946 | if (!tc_stat.ready) |
947 | return false; | 947 | return false; |
948 | 948 | ||
949 | if (!TAGCACHE_IS_NUMERIC(tag)) | 949 | if (!TAGCACHE_IS_NUMERIC(tag)) |
950 | return -1; | 950 | return -1; |
951 | 951 | ||
952 | if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true)) | 952 | if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true)) |
953 | return -2; | 953 | return -2; |
954 | 954 | ||
955 | return check_virtual_tags(tag, tcs->idx_id, &idx); | 955 | return check_virtual_tags(tag, tcs->idx_id, &idx); |
956 | } | 956 | } |
957 | 957 | ||
@@ -959,10 +959,10 @@ inline static bool str_ends_with(const char *str1, const char *str2) | |||
959 | { | 959 | { |
960 | int str_len = strlen(str1); | 960 | int str_len = strlen(str1); |
961 | int clause_len = strlen(str2); | 961 | int clause_len = strlen(str2); |
962 | 962 | ||
963 | if (clause_len > str_len) | 963 | if (clause_len > str_len) |
964 | return false; | 964 | return false; |
965 | 965 | ||
966 | return !strcasecmp(&str1[str_len - clause_len], str2); | 966 | return !strcasecmp(&str1[str_len - clause_len], str2); |
967 | } | 967 | } |
968 | 968 | ||
@@ -970,7 +970,7 @@ inline static bool str_oneof(const char *str, const char *list) | |||
970 | { | 970 | { |
971 | const char *sep; | 971 | const char *sep; |
972 | int l, len = strlen(str); | 972 | int l, len = strlen(str); |
973 | 973 | ||
974 | while (*list) | 974 | while (*list) |
975 | { | 975 | { |
976 | sep = strchr(list, '|'); | 976 | sep = strchr(list, '|'); |
@@ -1001,7 +1001,7 @@ static bool check_against_clause(long numeric, const char *str, | |||
1001 | case clause_lt: | 1001 | case clause_lt: |
1002 | return numeric < clause->numeric_data; | 1002 | return numeric < clause->numeric_data; |
1003 | case clause_lteq: | 1003 | case clause_lteq: |
1004 | return numeric <= clause->numeric_data; | 1004 | return numeric <= clause->numeric_data; |
1005 | default: | 1005 | default: |
1006 | logf("Incorrect numeric tag: %d", clause->type); | 1006 | logf("Incorrect numeric tag: %d", clause->type); |
1007 | } | 1007 | } |
@@ -1036,7 +1036,7 @@ static bool check_against_clause(long numeric, const char *str, | |||
1036 | return !str_ends_with(str, clause->str); | 1036 | return !str_ends_with(str, clause->str); |
1037 | case clause_oneof: | 1037 | case clause_oneof: |
1038 | return str_oneof(str, clause->str); | 1038 | return str_oneof(str, clause->str); |
1039 | 1039 | ||
1040 | default: | 1040 | default: |
1041 | logf("Incorrect tag: %d", clause->type); | 1041 | logf("Incorrect tag: %d", clause->type); |
1042 | } | 1042 | } |
@@ -1050,7 +1050,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1050 | struct tagcache_search_clause **clauses, int count) | 1050 | struct tagcache_search_clause **clauses, int count) |
1051 | { | 1051 | { |
1052 | int i; | 1052 | int i; |
1053 | 1053 | ||
1054 | /* Go through all conditional clauses. */ | 1054 | /* Go through all conditional clauses. */ |
1055 | for (i = 0; i < count; i++) | 1055 | for (i = 0; i < count; i++) |
1056 | { | 1056 | { |
@@ -1058,7 +1058,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1058 | char buf[256]; | 1058 | char buf[256]; |
1059 | char *str = buf; | 1059 | char *str = buf; |
1060 | struct tagcache_search_clause *clause = clauses[i]; | 1060 | struct tagcache_search_clause *clause = clauses[i]; |
1061 | 1061 | ||
1062 | if (clause->type == clause_logical_or) | 1062 | if (clause->type == clause_logical_or) |
1063 | break; /* all conditions before logical-or satisfied -- | 1063 | break; /* all conditions before logical-or satisfied -- |
1064 | stop processing clauses */ | 1064 | stop processing clauses */ |
@@ -1069,7 +1069,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1069 | if (tcs->ramsearch) | 1069 | if (tcs->ramsearch) |
1070 | { | 1070 | { |
1071 | struct tagfile_entry *tfe; | 1071 | struct tagfile_entry *tfe; |
1072 | 1072 | ||
1073 | if (!TAGCACHE_IS_NUMERIC(clause->tag)) | 1073 | if (!TAGCACHE_IS_NUMERIC(clause->tag)) |
1074 | { | 1074 | { |
1075 | if (clause->tag == tag_filename | 1075 | if (clause->tag == tag_filename |
@@ -1092,7 +1092,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1092 | #endif /* HAVE_TC_RAMCACHE */ | 1092 | #endif /* HAVE_TC_RAMCACHE */ |
1093 | { | 1093 | { |
1094 | struct tagfile_entry tfe; | 1094 | struct tagfile_entry tfe; |
1095 | 1095 | ||
1096 | if (!TAGCACHE_IS_NUMERIC(clause->tag)) | 1096 | if (!TAGCACHE_IS_NUMERIC(clause->tag)) |
1097 | { | 1097 | { |
1098 | int tag = clause->tag; | 1098 | int tag = clause->tag; |
@@ -1110,7 +1110,7 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1110 | 1110 | ||
1111 | read(fd, str, tfe.tag_length); | 1111 | read(fd, str, tfe.tag_length); |
1112 | str[tfe.tag_length] = '\0'; | 1112 | str[tfe.tag_length] = '\0'; |
1113 | 1113 | ||
1114 | /* Check if entry has been deleted. */ | 1114 | /* Check if entry has been deleted. */ |
1115 | if (str[0] == '\0') | 1115 | if (str[0] == '\0') |
1116 | return false; | 1116 | return false; |
@@ -1132,14 +1132,14 @@ static bool check_clauses(struct tagcache_search *tcs, | |||
1132 | if (clauses[i]->type == clause_logical_or) | 1132 | if (clauses[i]->type == clause_logical_or) |
1133 | break; | 1133 | break; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | if (i < count) /* Found logical-or? */ | 1136 | if (i < count) /* Found logical-or? */ |
1137 | continue; /* Check clauses after logical-or */ | 1137 | continue; /* Check clauses after logical-or */ |
1138 | 1138 | ||
1139 | return false; | 1139 | return false; |
1140 | } | 1140 | } |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | return true; | 1143 | return true; |
1144 | } | 1144 | } |
1145 | 1145 | ||
@@ -1147,40 +1147,40 @@ bool tagcache_check_clauses(struct tagcache_search *tcs, | |||
1147 | struct tagcache_search_clause **clause, int count) | 1147 | struct tagcache_search_clause **clause, int count) |
1148 | { | 1148 | { |
1149 | struct index_entry idx; | 1149 | struct index_entry idx; |
1150 | 1150 | ||
1151 | if (count == 0) | 1151 | if (count == 0) |
1152 | return true; | 1152 | return true; |
1153 | 1153 | ||
1154 | if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true)) | 1154 | if (!get_index(tcs->masterfd, tcs->idx_id, &idx, true)) |
1155 | return false; | 1155 | return false; |
1156 | 1156 | ||
1157 | return check_clauses(tcs, &idx, clause, count); | 1157 | return check_clauses(tcs, &idx, clause, count); |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) | 1160 | static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) |
1161 | { | 1161 | { |
1162 | int i; | 1162 | int i; |
1163 | 1163 | ||
1164 | /* If uniq buffer is not defined we must return true for search to work. */ | 1164 | /* If uniq buffer is not defined we must return true for search to work. */ |
1165 | if (tcs->unique_list == NULL || (!TAGCACHE_IS_UNIQUE(tcs->type) | 1165 | if (tcs->unique_list == NULL || (!TAGCACHE_IS_UNIQUE(tcs->type) |
1166 | && !TAGCACHE_IS_NUMERIC(tcs->type))) | 1166 | && !TAGCACHE_IS_NUMERIC(tcs->type))) |
1167 | { | 1167 | { |
1168 | return true; | 1168 | return true; |
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | for (i = 0; i < tcs->unique_list_count; i++) | 1171 | for (i = 0; i < tcs->unique_list_count; i++) |
1172 | { | 1172 | { |
1173 | /* Return false if entry is found. */ | 1173 | /* Return false if entry is found. */ |
1174 | if (tcs->unique_list[i] == id) | 1174 | if (tcs->unique_list[i] == id) |
1175 | return false; | 1175 | return false; |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | if (tcs->unique_list_count < tcs->unique_list_capacity) | 1178 | if (tcs->unique_list_count < tcs->unique_list_capacity) |
1179 | { | 1179 | { |
1180 | tcs->unique_list[i] = id; | 1180 | tcs->unique_list[i] = id; |
1181 | tcs->unique_list_count++; | 1181 | tcs->unique_list_count++; |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | return true; | 1184 | return true; |
1185 | } | 1185 | } |
1186 | 1186 | ||
@@ -1188,9 +1188,9 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1188 | { | 1188 | { |
1189 | struct index_entry entry; | 1189 | struct index_entry entry; |
1190 | int i, j; | 1190 | int i, j; |
1191 | 1191 | ||
1192 | tcs->seek_list_count = 0; | 1192 | tcs->seek_list_count = 0; |
1193 | 1193 | ||
1194 | #ifdef HAVE_TC_RAMCACHE | 1194 | #ifdef HAVE_TC_RAMCACHE |
1195 | if (tcs->ramsearch) | 1195 | if (tcs->ramsearch) |
1196 | { | 1196 | { |
@@ -1203,11 +1203,11 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1203 | struct index_entry *idx = &tcramcache.hdr->indices[i]; | 1203 | struct index_entry *idx = &tcramcache.hdr->indices[i]; |
1204 | if (tcs->seek_list_count == SEEK_LIST_SIZE) | 1204 | if (tcs->seek_list_count == SEEK_LIST_SIZE) |
1205 | break ; | 1205 | break ; |
1206 | 1206 | ||
1207 | /* Skip deleted files. */ | 1207 | /* Skip deleted files. */ |
1208 | if (idx->flag & FLAG_DELETED) | 1208 | if (idx->flag & FLAG_DELETED) |
1209 | continue; | 1209 | continue; |
1210 | 1210 | ||
1211 | /* Go through all filters.. */ | 1211 | /* Go through all filters.. */ |
1212 | for (j = 0; j < tcs->filter_count; j++) | 1212 | for (j = 0; j < tcs->filter_count; j++) |
1213 | { | 1213 | { |
@@ -1216,7 +1216,7 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1216 | break ; | 1216 | break ; |
1217 | } | 1217 | } |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | if (j < tcs->filter_count) | 1220 | if (j < tcs->filter_count) |
1221 | continue ; | 1221 | continue ; |
1222 | 1222 | ||
@@ -1226,7 +1226,7 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1226 | /* Add to the seek list if not already in uniq buffer (doesn't yield)*/ | 1226 | /* Add to the seek list if not already in uniq buffer (doesn't yield)*/ |
1227 | if (!add_uniqbuf(tcs, idx->tag_seek[tcs->type])) | 1227 | if (!add_uniqbuf(tcs, idx->tag_seek[tcs->type])) |
1228 | continue; | 1228 | continue; |
1229 | 1229 | ||
1230 | /* Lets add it. */ | 1230 | /* Lets add it. */ |
1231 | seeklist = &tcs->seeklist[tcs->seek_list_count]; | 1231 | seeklist = &tcs->seeklist[tcs->seek_list_count]; |
1232 | seeklist->seek = idx->tag_seek[tcs->type]; | 1232 | seeklist->seek = idx->tag_seek[tcs->type]; |
@@ -1238,72 +1238,72 @@ static bool build_lookup_list(struct tagcache_search *tcs) | |||
1238 | tcrc_buffer_unlock(); | 1238 | tcrc_buffer_unlock(); |
1239 | 1239 | ||
1240 | tcs->seek_pos = i; | 1240 | tcs->seek_pos = i; |
1241 | 1241 | ||
1242 | return tcs->seek_list_count > 0; | 1242 | return tcs->seek_list_count > 0; |
1243 | } | 1243 | } |
1244 | #endif /* HAVE_TC_RAMCACHE */ | 1244 | #endif /* HAVE_TC_RAMCACHE */ |
1245 | 1245 | ||
1246 | if (tcs->masterfd < 0) | 1246 | if (tcs->masterfd < 0) |
1247 | { | 1247 | { |
1248 | struct master_header tcmh; | 1248 | struct master_header tcmh; |
1249 | tcs->masterfd = open_master_fd(&tcmh, false); | 1249 | tcs->masterfd = open_master_fd(&tcmh, false); |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + | 1252 | lseek(tcs->masterfd, tcs->seek_pos * sizeof(struct index_entry) + |
1253 | sizeof(struct master_header), SEEK_SET); | 1253 | sizeof(struct master_header), SEEK_SET); |
1254 | 1254 | ||
1255 | while (ecread_index_entry(tcs->masterfd, &entry) | 1255 | while (ecread_index_entry(tcs->masterfd, &entry) |
1256 | == sizeof(struct index_entry)) | 1256 | == sizeof(struct index_entry)) |
1257 | { | 1257 | { |
1258 | struct tagcache_seeklist_entry *seeklist; | 1258 | struct tagcache_seeklist_entry *seeklist; |
1259 | 1259 | ||
1260 | if (tcs->seek_list_count == SEEK_LIST_SIZE) | 1260 | if (tcs->seek_list_count == SEEK_LIST_SIZE) |
1261 | break ; | 1261 | break ; |
1262 | 1262 | ||
1263 | i = tcs->seek_pos; | 1263 | i = tcs->seek_pos; |
1264 | tcs->seek_pos++; | 1264 | tcs->seek_pos++; |
1265 | 1265 | ||
1266 | /* Check if entry has been deleted. */ | 1266 | /* Check if entry has been deleted. */ |
1267 | if (entry.flag & FLAG_DELETED) | 1267 | if (entry.flag & FLAG_DELETED) |
1268 | continue; | 1268 | continue; |
1269 | 1269 | ||
1270 | /* Go through all filters.. */ | 1270 | /* Go through all filters.. */ |
1271 | for (j = 0; j < tcs->filter_count; j++) | 1271 | for (j = 0; j < tcs->filter_count; j++) |
1272 | { | 1272 | { |
1273 | if (entry.tag_seek[tcs->filter_tag[j]] != tcs->filter_seek[j]) | 1273 | if (entry.tag_seek[tcs->filter_tag[j]] != tcs->filter_seek[j]) |
1274 | break ; | 1274 | break ; |
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | if (j < tcs->filter_count) | 1277 | if (j < tcs->filter_count) |
1278 | continue ; | 1278 | continue ; |
1279 | 1279 | ||
1280 | /* Check for conditions. */ | 1280 | /* Check for conditions. */ |
1281 | if (!check_clauses(tcs, &entry, tcs->clause, tcs->clause_count)) | 1281 | if (!check_clauses(tcs, &entry, tcs->clause, tcs->clause_count)) |
1282 | continue; | 1282 | continue; |
1283 | 1283 | ||
1284 | /* Add to the seek list if not already in uniq buffer. */ | 1284 | /* Add to the seek list if not already in uniq buffer. */ |
1285 | if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type])) | 1285 | if (!add_uniqbuf(tcs, entry.tag_seek[tcs->type])) |
1286 | continue; | 1286 | continue; |
1287 | 1287 | ||
1288 | /* Lets add it. */ | 1288 | /* Lets add it. */ |
1289 | seeklist = &tcs->seeklist[tcs->seek_list_count]; | 1289 | seeklist = &tcs->seeklist[tcs->seek_list_count]; |
1290 | seeklist->seek = entry.tag_seek[tcs->type]; | 1290 | seeklist->seek = entry.tag_seek[tcs->type]; |
1291 | seeklist->flag = entry.flag; | 1291 | seeklist->flag = entry.flag; |
1292 | seeklist->idx_id = i; | 1292 | seeklist->idx_id = i; |
1293 | tcs->seek_list_count++; | 1293 | tcs->seek_list_count++; |
1294 | 1294 | ||
1295 | yield(); | 1295 | yield(); |
1296 | } | 1296 | } |
1297 | 1297 | ||
1298 | return tcs->seek_list_count > 0; | 1298 | return tcs->seek_list_count > 0; |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | 1301 | ||
1302 | static void remove_files(void) | 1302 | static void remove_files(void) |
1303 | { | 1303 | { |
1304 | int i; | 1304 | int i; |
1305 | char buf[MAX_PATH]; | 1305 | char buf[MAX_PATH]; |
1306 | 1306 | ||
1307 | tc_stat.ready = false; | 1307 | tc_stat.ready = false; |
1308 | tc_stat.ramcache = false; | 1308 | tc_stat.ramcache = false; |
1309 | tc_stat.econ = false; | 1309 | tc_stat.econ = false; |
@@ -1312,7 +1312,7 @@ static void remove_files(void) | |||
1312 | { | 1312 | { |
1313 | if (TAGCACHE_IS_NUMERIC(i)) | 1313 | if (TAGCACHE_IS_NUMERIC(i)) |
1314 | continue; | 1314 | continue; |
1315 | 1315 | ||
1316 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); | 1316 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); |
1317 | remove(buf); | 1317 | remove(buf); |
1318 | } | 1318 | } |
@@ -1325,30 +1325,30 @@ static bool check_all_headers(void) | |||
1325 | struct tagcache_header tch; | 1325 | struct tagcache_header tch; |
1326 | int tag; | 1326 | int tag; |
1327 | int fd; | 1327 | int fd; |
1328 | 1328 | ||
1329 | if ( (fd = open_master_fd(&myhdr, false)) < 0) | 1329 | if ( (fd = open_master_fd(&myhdr, false)) < 0) |
1330 | return false; | 1330 | return false; |
1331 | 1331 | ||
1332 | close(fd); | 1332 | close(fd); |
1333 | if (myhdr.dirty) | 1333 | if (myhdr.dirty) |
1334 | { | 1334 | { |
1335 | logf("tagcache is dirty!"); | 1335 | logf("tagcache is dirty!"); |
1336 | return false; | 1336 | return false; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | memcpy(¤t_tcmh, &myhdr, sizeof(struct master_header)); | 1339 | memcpy(¤t_tcmh, &myhdr, sizeof(struct master_header)); |
1340 | 1340 | ||
1341 | for (tag = 0; tag < TAG_COUNT; tag++) | 1341 | for (tag = 0; tag < TAG_COUNT; tag++) |
1342 | { | 1342 | { |
1343 | if (TAGCACHE_IS_NUMERIC(tag)) | 1343 | if (TAGCACHE_IS_NUMERIC(tag)) |
1344 | continue; | 1344 | continue; |
1345 | 1345 | ||
1346 | if ( (fd = open_tag_fd(&tch, tag, false)) < 0) | 1346 | if ( (fd = open_tag_fd(&tch, tag, false)) < 0) |
1347 | return false; | 1347 | return false; |
1348 | 1348 | ||
1349 | close(fd); | 1349 | close(fd); |
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | return true; | 1352 | return true; |
1353 | } | 1353 | } |
1354 | 1354 | ||
@@ -1360,11 +1360,11 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1360 | 1360 | ||
1361 | while (read_lock) | 1361 | while (read_lock) |
1362 | sleep(1); | 1362 | sleep(1); |
1363 | 1363 | ||
1364 | memset(tcs, 0, sizeof(struct tagcache_search)); | 1364 | memset(tcs, 0, sizeof(struct tagcache_search)); |
1365 | if (tc_stat.commit_step > 0 || !tc_stat.ready) | 1365 | if (tc_stat.commit_step > 0 || !tc_stat.ready) |
1366 | return false; | 1366 | return false; |
1367 | 1367 | ||
1368 | tcs->position = sizeof(struct tagcache_header); | 1368 | tcs->position = sizeof(struct tagcache_header); |
1369 | tcs->type = tag; | 1369 | tcs->type = tag; |
1370 | tcs->seek_pos = 0; | 1370 | tcs->seek_pos = 0; |
@@ -1392,13 +1392,13 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1392 | tcs->masterfd = open_master_fd(&master_hdr, true); | 1392 | tcs->masterfd = open_master_fd(&master_hdr, true); |
1393 | if (tcs->masterfd < 0) | 1393 | if (tcs->masterfd < 0) |
1394 | return false; | 1394 | return false; |
1395 | 1395 | ||
1396 | if (!TAGCACHE_IS_NUMERIC(tcs->type)) | 1396 | if (!TAGCACHE_IS_NUMERIC(tcs->type)) |
1397 | { | 1397 | { |
1398 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); | 1398 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); |
1399 | if (tcs->idxfd[tcs->type] < 0) | 1399 | if (tcs->idxfd[tcs->type] < 0) |
1400 | return false; | 1400 | return false; |
1401 | 1401 | ||
1402 | tcs->entry_count = tag_hdr.entry_count; | 1402 | tcs->entry_count = tag_hdr.entry_count; |
1403 | } | 1403 | } |
1404 | else | 1404 | else |
@@ -1410,7 +1410,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
1410 | tcs->valid = true; | 1410 | tcs->valid = true; |
1411 | tcs->initialized = true; | 1411 | tcs->initialized = true; |
1412 | write_lock++; | 1412 | write_lock++; |
1413 | 1413 | ||
1414 | return true; | 1414 | return true; |
1415 | } | 1415 | } |
1416 | 1416 | ||
@@ -1430,7 +1430,7 @@ bool tagcache_search_add_filter(struct tagcache_search *tcs, | |||
1430 | 1430 | ||
1431 | if (TAGCACHE_IS_NUMERIC_OR_NONUNIQUE(tag)) | 1431 | if (TAGCACHE_IS_NUMERIC_OR_NONUNIQUE(tag)) |
1432 | return false; | 1432 | return false; |
1433 | 1433 | ||
1434 | tcs->filter_tag[tcs->filter_count] = tag; | 1434 | tcs->filter_tag[tcs->filter_count] = tag; |
1435 | tcs->filter_seek[tcs->filter_count] = seek; | 1435 | tcs->filter_seek[tcs->filter_count] = seek; |
1436 | tcs->filter_count++; | 1436 | tcs->filter_count++; |
@@ -1442,7 +1442,7 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs, | |||
1442 | struct tagcache_search_clause *clause) | 1442 | struct tagcache_search_clause *clause) |
1443 | { | 1443 | { |
1444 | int i; | 1444 | int i; |
1445 | 1445 | ||
1446 | if (tcs->clause_count >= TAGCACHE_MAX_CLAUSES) | 1446 | if (tcs->clause_count >= TAGCACHE_MAX_CLAUSES) |
1447 | { | 1447 | { |
1448 | logf("Too many clauses"); | 1448 | logf("Too many clauses"); |
@@ -1452,26 +1452,26 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs, | |||
1452 | if (clause->type != clause_logical_or) | 1452 | if (clause->type != clause_logical_or) |
1453 | { | 1453 | { |
1454 | /* Check if there is already a similar filter in present (filters are | 1454 | /* Check if there is already a similar filter in present (filters are |
1455 | * much faster than clauses). | 1455 | * much faster than clauses). |
1456 | */ | 1456 | */ |
1457 | for (i = 0; i < tcs->filter_count; i++) | 1457 | for (i = 0; i < tcs->filter_count; i++) |
1458 | { | 1458 | { |
1459 | if (tcs->filter_tag[i] == clause->tag) | 1459 | if (tcs->filter_tag[i] == clause->tag) |
1460 | return true; | 1460 | return true; |
1461 | } | 1461 | } |
1462 | 1462 | ||
1463 | if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0) | 1463 | if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0) |
1464 | { | 1464 | { |
1465 | char buf[MAX_PATH]; | 1465 | char buf[MAX_PATH]; |
1466 | 1466 | ||
1467 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag); | 1467 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag); |
1468 | tcs->idxfd[clause->tag] = open(buf, O_RDONLY); | 1468 | tcs->idxfd[clause->tag] = open(buf, O_RDONLY); |
1469 | } | 1469 | } |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | tcs->clause[tcs->clause_count] = clause; | 1472 | tcs->clause[tcs->clause_count] = clause; |
1473 | tcs->clause_count++; | 1473 | tcs->clause_count++; |
1474 | 1474 | ||
1475 | return true; | 1475 | return true; |
1476 | } | 1476 | } |
1477 | 1477 | ||
@@ -1485,14 +1485,14 @@ static bool get_next(struct tagcache_search *tcs) | |||
1485 | 1485 | ||
1486 | if (!tcs->valid || !tc_stat.ready) | 1486 | if (!tcs->valid || !tc_stat.ready) |
1487 | return false; | 1487 | return false; |
1488 | 1488 | ||
1489 | if (tcs->idxfd[tcs->type] < 0 && !TAGCACHE_IS_NUMERIC(tcs->type) | 1489 | if (tcs->idxfd[tcs->type] < 0 && !TAGCACHE_IS_NUMERIC(tcs->type) |
1490 | #ifdef HAVE_TC_RAMCACHE | 1490 | #ifdef HAVE_TC_RAMCACHE |
1491 | && !tcs->ramsearch | 1491 | && !tcs->ramsearch |
1492 | #endif | 1492 | #endif |
1493 | ) | 1493 | ) |
1494 | return false; | 1494 | return false; |
1495 | 1495 | ||
1496 | /* Relative fetch. */ | 1496 | /* Relative fetch. */ |
1497 | if (tcs->filter_count > 0 || tcs->clause_count > 0 | 1497 | if (tcs->filter_count > 0 || tcs->clause_count > 0 |
1498 | || TAGCACHE_IS_NUMERIC(tcs->type) | 1498 | || TAGCACHE_IS_NUMERIC(tcs->type) |
@@ -1503,12 +1503,12 @@ static bool get_next(struct tagcache_search *tcs) | |||
1503 | ) | 1503 | ) |
1504 | { | 1504 | { |
1505 | struct tagcache_seeklist_entry *seeklist; | 1505 | struct tagcache_seeklist_entry *seeklist; |
1506 | 1506 | ||
1507 | /* Check for end of list. */ | 1507 | /* Check for end of list. */ |
1508 | if (tcs->list_position == tcs->seek_list_count) | 1508 | if (tcs->list_position == tcs->seek_list_count) |
1509 | { | 1509 | { |
1510 | tcs->list_position = 0; | 1510 | tcs->list_position = 0; |
1511 | 1511 | ||
1512 | /* Try to fetch more. */ | 1512 | /* Try to fetch more. */ |
1513 | if (!build_lookup_list(tcs)) | 1513 | if (!build_lookup_list(tcs)) |
1514 | { | 1514 | { |
@@ -1516,7 +1516,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
1516 | return false; | 1516 | return false; |
1517 | } | 1517 | } |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | seeklist = &tcs->seeklist[tcs->list_position]; | 1520 | seeklist = &tcs->seeklist[tcs->list_position]; |
1521 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1521 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1522 | flag = seeklist->flag; | 1522 | flag = seeklist->flag; |
@@ -1532,12 +1532,12 @@ static bool get_next(struct tagcache_search *tcs) | |||
1532 | tcs->valid = false; | 1532 | tcs->valid = false; |
1533 | return false; | 1533 | return false; |
1534 | } | 1534 | } |
1535 | 1535 | ||
1536 | tcs->entry_count--; | 1536 | tcs->entry_count--; |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | tcs->result_seek = tcs->position; | 1539 | tcs->result_seek = tcs->position; |
1540 | 1540 | ||
1541 | if (TAGCACHE_IS_NUMERIC(tcs->type)) | 1541 | if (TAGCACHE_IS_NUMERIC(tcs->type)) |
1542 | { | 1542 | { |
1543 | snprintf(buf, sizeof(buf), "%ld", tcs->position); | 1543 | snprintf(buf, sizeof(buf), "%ld", tcs->position); |
@@ -1545,7 +1545,7 @@ static bool get_next(struct tagcache_search *tcs) | |||
1545 | tcs->result_len = strlen(buf) + 1; | 1545 | tcs->result_len = strlen(buf) + 1; |
1546 | return true; | 1546 | return true; |
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | /* Direct fetch. */ | 1549 | /* Direct fetch. */ |
1550 | #ifdef HAVE_TC_RAMCACHE | 1550 | #ifdef HAVE_TC_RAMCACHE |
1551 | if (tcs->ramsearch) | 1551 | if (tcs->ramsearch) |
@@ -1569,38 +1569,38 @@ static bool get_next(struct tagcache_search *tcs) | |||
1569 | if (tcs->type != tag_filename) | 1569 | if (tcs->type != tag_filename) |
1570 | { | 1570 | { |
1571 | struct tagfile_entry *ep; | 1571 | struct tagfile_entry *ep; |
1572 | 1572 | ||
1573 | ep = (struct tagfile_entry *)&tcramcache.hdr->tags[tcs->type][tcs->position]; | 1573 | ep = (struct tagfile_entry *)&tcramcache.hdr->tags[tcs->type][tcs->position]; |
1574 | /* don't return ep->tag_data directly as it may move */ | 1574 | /* don't return ep->tag_data directly as it may move */ |
1575 | tcs->result_len = strlcpy(buf, ep->tag_data, sizeof(buf)) + 1; | 1575 | tcs->result_len = strlcpy(buf, ep->tag_data, sizeof(buf)) + 1; |
1576 | tcs->result = buf; | 1576 | tcs->result = buf; |
1577 | tcs->idx_id = ep->idx_id; | 1577 | tcs->idx_id = ep->idx_id; |
1578 | tcs->ramresult = false; /* was true before we copied to buf too */ | 1578 | tcs->ramresult = false; /* was true before we copied to buf too */ |
1579 | 1579 | ||
1580 | /* Increase position for the next run. This may get overwritten. */ | 1580 | /* Increase position for the next run. This may get overwritten. */ |
1581 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; | 1581 | tcs->position += sizeof(struct tagfile_entry) + ep->tag_length; |
1582 | 1582 | ||
1583 | return true; | 1583 | return true; |
1584 | } | 1584 | } |
1585 | } | 1585 | } |
1586 | #endif /* HAVE_TC_RAMCACHE */ | 1586 | #endif /* HAVE_TC_RAMCACHE */ |
1587 | 1587 | ||
1588 | if (!open_files(tcs, tcs->type)) | 1588 | if (!open_files(tcs, tcs->type)) |
1589 | { | 1589 | { |
1590 | tcs->valid = false; | 1590 | tcs->valid = false; |
1591 | return false; | 1591 | return false; |
1592 | } | 1592 | } |
1593 | 1593 | ||
1594 | /* Seek stream to the correct position and continue to direct fetch. */ | 1594 | /* Seek stream to the correct position and continue to direct fetch. */ |
1595 | lseek(tcs->idxfd[tcs->type], tcs->position, SEEK_SET); | 1595 | lseek(tcs->idxfd[tcs->type], tcs->position, SEEK_SET); |
1596 | 1596 | ||
1597 | if (ecread_tagfile_entry(tcs->idxfd[tcs->type], &entry) != sizeof(struct tagfile_entry)) | 1597 | if (ecread_tagfile_entry(tcs->idxfd[tcs->type], &entry) != sizeof(struct tagfile_entry)) |
1598 | { | 1598 | { |
1599 | logf("read error #5"); | 1599 | logf("read error #5"); |
1600 | tcs->valid = false; | 1600 | tcs->valid = false; |
1601 | return false; | 1601 | return false; |
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | if (entry.tag_length > (long)sizeof(buf)) | 1604 | if (entry.tag_length > (long)sizeof(buf)) |
1605 | { | 1605 | { |
1606 | tcs->valid = false; | 1606 | tcs->valid = false; |
@@ -1608,14 +1608,14 @@ static bool get_next(struct tagcache_search *tcs) | |||
1608 | logf("P:%lX/%lX", tcs->position, entry.tag_length); | 1608 | logf("P:%lX/%lX", tcs->position, entry.tag_length); |
1609 | return false; | 1609 | return false; |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | if (read(tcs->idxfd[tcs->type], buf, entry.tag_length) != entry.tag_length) | 1612 | if (read(tcs->idxfd[tcs->type], buf, entry.tag_length) != entry.tag_length) |
1613 | { | 1613 | { |
1614 | tcs->valid = false; | 1614 | tcs->valid = false; |
1615 | logf("read error #4"); | 1615 | logf("read error #4"); |
1616 | return false; | 1616 | return false; |
1617 | } | 1617 | } |
1618 | 1618 | ||
1619 | /** | 1619 | /** |
1620 | Update the position for the next read (this may be overridden | 1620 | Update the position for the next read (this may be overridden |
1621 | if filters or clauses are being used). | 1621 | if filters or clauses are being used). |
@@ -1636,19 +1636,19 @@ bool tagcache_get_next(struct tagcache_search *tcs) | |||
1636 | if (tcs->result_len > 1) | 1636 | if (tcs->result_len > 1) |
1637 | return true; | 1637 | return true; |
1638 | } | 1638 | } |
1639 | 1639 | ||
1640 | return false; | 1640 | return false; |
1641 | } | 1641 | } |
1642 | 1642 | ||
1643 | bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, | 1643 | bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, |
1644 | int tag, char *buf, long size) | 1644 | int tag, char *buf, long size) |
1645 | { | 1645 | { |
1646 | struct index_entry idx; | 1646 | struct index_entry idx; |
1647 | 1647 | ||
1648 | *buf = '\0'; | 1648 | *buf = '\0'; |
1649 | if (!get_index(tcs->masterfd, idxid, &idx, true)) | 1649 | if (!get_index(tcs->masterfd, idxid, &idx, true)) |
1650 | return false; | 1650 | return false; |
1651 | 1651 | ||
1652 | return retrieve(tcs, IF_DIRCACHE(idxid,) &idx, tag, buf, size); | 1652 | return retrieve(tcs, IF_DIRCACHE(idxid,) &idx, tag, buf, size); |
1653 | } | 1653 | } |
1654 | 1654 | ||
@@ -1656,32 +1656,32 @@ static bool update_master_header(void) | |||
1656 | { | 1656 | { |
1657 | struct master_header myhdr; | 1657 | struct master_header myhdr; |
1658 | int fd; | 1658 | int fd; |
1659 | 1659 | ||
1660 | if (!tc_stat.ready) | 1660 | if (!tc_stat.ready) |
1661 | return false; | 1661 | return false; |
1662 | 1662 | ||
1663 | if ( (fd = open_master_fd(&myhdr, true)) < 0) | 1663 | if ( (fd = open_master_fd(&myhdr, true)) < 0) |
1664 | return false; | 1664 | return false; |
1665 | 1665 | ||
1666 | myhdr.serial = current_tcmh.serial; | 1666 | myhdr.serial = current_tcmh.serial; |
1667 | myhdr.commitid = current_tcmh.commitid; | 1667 | myhdr.commitid = current_tcmh.commitid; |
1668 | myhdr.dirty = current_tcmh.dirty; | 1668 | myhdr.dirty = current_tcmh.dirty; |
1669 | 1669 | ||
1670 | /* Write it back */ | 1670 | /* Write it back */ |
1671 | lseek(fd, 0, SEEK_SET); | 1671 | lseek(fd, 0, SEEK_SET); |
1672 | ecwrite(fd, &myhdr, 1, master_header_ec, tc_stat.econ); | 1672 | ecwrite(fd, &myhdr, 1, master_header_ec, tc_stat.econ); |
1673 | close(fd); | 1673 | close(fd); |
1674 | 1674 | ||
1675 | return true; | 1675 | return true; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | void tagcache_search_finish(struct tagcache_search *tcs) | 1678 | void tagcache_search_finish(struct tagcache_search *tcs) |
1679 | { | 1679 | { |
1680 | int i; | 1680 | int i; |
1681 | 1681 | ||
1682 | if (!tcs->initialized) | 1682 | if (!tcs->initialized) |
1683 | return; | 1683 | return; |
1684 | 1684 | ||
1685 | if (tcs->masterfd >= 0) | 1685 | if (tcs->masterfd >= 0) |
1686 | { | 1686 | { |
1687 | close(tcs->masterfd); | 1687 | close(tcs->masterfd); |
@@ -1696,7 +1696,7 @@ void tagcache_search_finish(struct tagcache_search *tcs) | |||
1696 | tcs->idxfd[i] = -1; | 1696 | tcs->idxfd[i] = -1; |
1697 | } | 1697 | } |
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | tcs->ramsearch = false; | 1700 | tcs->ramsearch = false; |
1701 | tcs->valid = false; | 1701 | tcs->valid = false; |
1702 | tcs->initialized = 0; | 1702 | tcs->initialized = 0; |
@@ -1725,17 +1725,17 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1725 | { | 1725 | { |
1726 | struct index_entry *entry; | 1726 | struct index_entry *entry; |
1727 | int idx_id; | 1727 | int idx_id; |
1728 | 1728 | ||
1729 | if (!tc_stat.ready || !tc_stat.ramcache) | 1729 | if (!tc_stat.ready || !tc_stat.ramcache) |
1730 | return false; | 1730 | return false; |
1731 | 1731 | ||
1732 | /* Find the corresponding entry in tagcache. */ | 1732 | /* Find the corresponding entry in tagcache. */ |
1733 | idx_id = find_entry_ram(filename); | 1733 | idx_id = find_entry_ram(filename); |
1734 | if (idx_id < 0) | 1734 | if (idx_id < 0) |
1735 | return false; | 1735 | return false; |
1736 | 1736 | ||
1737 | entry = &tcramcache.hdr->indices[idx_id]; | 1737 | entry = &tcramcache.hdr->indices[idx_id]; |
1738 | 1738 | ||
1739 | memset(id3, 0, sizeof(struct mp3entry)); | 1739 | memset(id3, 0, sizeof(struct mp3entry)); |
1740 | char* buf = id3->id3v2buf; | 1740 | char* buf = id3->id3v2buf; |
1741 | ssize_t remaining = sizeof(id3->id3v2buf); | 1741 | ssize_t remaining = sizeof(id3->id3v2buf); |
@@ -1755,8 +1755,8 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1755 | } \ | 1755 | } \ |
1756 | } \ | 1756 | } \ |
1757 | } while(0) | 1757 | } while(0) |
1758 | 1758 | ||
1759 | 1759 | ||
1760 | SET(id3->title, tag_title); | 1760 | SET(id3->title, tag_title); |
1761 | SET(id3->artist, tag_artist); | 1761 | SET(id3->artist, tag_artist); |
1762 | SET(id3->album, tag_album); | 1762 | SET(id3->album, tag_album); |
@@ -1786,7 +1786,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename) | |||
1786 | id3->title, id3->elapsed); | 1786 | id3->title, id3->elapsed); |
1787 | 1787 | ||
1788 | id3->offset = get_tag_numeric(entry, tag_lastoffset, idx_id); | 1788 | id3->offset = get_tag_numeric(entry, tag_lastoffset, idx_id); |
1789 | logf("tagcache_fill_tags: Set offset for %s to %lX\n", | 1789 | logf("tagcache_fill_tags: Set offset for %s to %lX\n", |
1790 | id3->title, id3->offset); | 1790 | id3->title, id3->offset); |
1791 | } | 1791 | } |
1792 | 1792 | ||
@@ -1868,11 +1868,11 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1868 | logf("Too long path: %s", path); | 1868 | logf("Too long path: %s", path); |
1869 | return ; | 1869 | return ; |
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | /* Check if the file is supported. */ | 1872 | /* Check if the file is supported. */ |
1873 | if (probe_file_format(path) == AFMT_UNKNOWN) | 1873 | if (probe_file_format(path) == AFMT_UNKNOWN) |
1874 | return ; | 1874 | return ; |
1875 | 1875 | ||
1876 | /* Check if the file is already cached. */ | 1876 | /* Check if the file is already cached. */ |
1877 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1877 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1878 | idx_id = find_entry_ram(path); | 1878 | idx_id = find_entry_ram(path); |
@@ -1881,27 +1881,27 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1881 | /* Be sure the entry doesn't exist. */ | 1881 | /* Be sure the entry doesn't exist. */ |
1882 | if (filenametag_fd >= 0 && idx_id < 0) | 1882 | if (filenametag_fd >= 0 && idx_id < 0) |
1883 | idx_id = find_entry_disk(path, false); | 1883 | idx_id = find_entry_disk(path, false); |
1884 | 1884 | ||
1885 | /* Check if file has been modified. */ | 1885 | /* Check if file has been modified. */ |
1886 | if (idx_id >= 0) | 1886 | if (idx_id >= 0) |
1887 | { | 1887 | { |
1888 | struct index_entry idx; | 1888 | struct index_entry idx; |
1889 | 1889 | ||
1890 | /* TODO: Mark that the index exists (for fast reverse scan) */ | 1890 | /* TODO: Mark that the index exists (for fast reverse scan) */ |
1891 | //found_idx[idx_id/8] |= idx_id%8; | 1891 | //found_idx[idx_id/8] |= idx_id%8; |
1892 | 1892 | ||
1893 | if (!get_index(-1, idx_id, &idx, true)) | 1893 | if (!get_index(-1, idx_id, &idx, true)) |
1894 | { | 1894 | { |
1895 | logf("failed to retrieve index entry"); | 1895 | logf("failed to retrieve index entry"); |
1896 | return ; | 1896 | return ; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | if ((unsigned long)idx.tag_seek[tag_mtime] == mtime) | 1899 | if ((unsigned long)idx.tag_seek[tag_mtime] == mtime) |
1900 | { | 1900 | { |
1901 | /* No changes to file. */ | 1901 | /* No changes to file. */ |
1902 | return ; | 1902 | return ; |
1903 | } | 1903 | } |
1904 | 1904 | ||
1905 | /* Metadata might have been changed. Delete the entry. */ | 1905 | /* Metadata might have been changed. Delete the entry. */ |
1906 | logf("Re-adding: %s", path); | 1906 | logf("Re-adding: %s", path); |
1907 | if (!delete_entry(idx_id)) | 1907 | if (!delete_entry(idx_id)) |
@@ -1910,7 +1910,7 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1910 | return ; | 1910 | return ; |
1911 | } | 1911 | } |
1912 | } | 1912 | } |
1913 | 1913 | ||
1914 | fd = open(path, O_RDONLY); | 1914 | fd = open(path, O_RDONLY); |
1915 | if (fd < 0) | 1915 | if (fd < 0) |
1916 | { | 1916 | { |
@@ -1928,12 +1928,12 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1928 | return ; | 1928 | return ; |
1929 | 1929 | ||
1930 | logf("-> %s", path); | 1930 | logf("-> %s", path); |
1931 | 1931 | ||
1932 | if (id3.tracknum <= 0) /* Track number missing? */ | 1932 | if (id3.tracknum <= 0) /* Track number missing? */ |
1933 | { | 1933 | { |
1934 | id3.tracknum = -1; | 1934 | id3.tracknum = -1; |
1935 | } | 1935 | } |
1936 | 1936 | ||
1937 | /* Numeric tags */ | 1937 | /* Numeric tags */ |
1938 | entry.tag_offset[tag_year] = id3.year; | 1938 | entry.tag_offset[tag_year] = id3.year; |
1939 | entry.tag_offset[tag_discnumber] = id3.discnum; | 1939 | entry.tag_offset[tag_discnumber] = id3.discnum; |
@@ -1941,7 +1941,7 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1941 | entry.tag_offset[tag_length] = id3.length; | 1941 | entry.tag_offset[tag_length] = id3.length; |
1942 | entry.tag_offset[tag_bitrate] = id3.bitrate; | 1942 | entry.tag_offset[tag_bitrate] = id3.bitrate; |
1943 | entry.tag_offset[tag_mtime] = mtime; | 1943 | entry.tag_offset[tag_mtime] = mtime; |
1944 | 1944 | ||
1945 | /* String tags. */ | 1945 | /* String tags. */ |
1946 | has_albumartist = id3.albumartist != NULL | 1946 | has_albumartist = id3.albumartist != NULL |
1947 | && strlen(id3.albumartist) > 0; | 1947 | && strlen(id3.albumartist) > 0; |
@@ -1972,10 +1972,10 @@ static void NO_INLINE add_tagcache(char *path, unsigned long mtime) | |||
1972 | ADD_TAG(entry, tag_grouping, &id3.title); | 1972 | ADD_TAG(entry, tag_grouping, &id3.title); |
1973 | } | 1973 | } |
1974 | entry.data_length = offset; | 1974 | entry.data_length = offset; |
1975 | 1975 | ||
1976 | /* Write the header */ | 1976 | /* Write the header */ |
1977 | write(cachefd, &entry, sizeof(struct temp_file_entry)); | 1977 | write(cachefd, &entry, sizeof(struct temp_file_entry)); |
1978 | 1978 | ||
1979 | /* And tags also... Correct order is critical */ | 1979 | /* And tags also... Correct order is critical */ |
1980 | write_item(path); | 1980 | write_item(path); |
1981 | write_item(id3.title); | 1981 | write_item(id3.title); |
@@ -2014,13 +2014,13 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | |||
2014 | unsigned crc32; | 2014 | unsigned crc32; |
2015 | unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4]; | 2015 | unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4]; |
2016 | char buf[TAG_MAXLEN+32]; | 2016 | char buf[TAG_MAXLEN+32]; |
2017 | 2017 | ||
2018 | for (i = 0; str[i] != '\0' && i < (int)sizeof(buf)-1; i++) | 2018 | for (i = 0; str[i] != '\0' && i < (int)sizeof(buf)-1; i++) |
2019 | buf[i] = tolower(str[i]); | 2019 | buf[i] = tolower(str[i]); |
2020 | buf[i] = '\0'; | 2020 | buf[i] = '\0'; |
2021 | 2021 | ||
2022 | crc32 = crc_32(buf, i, 0xffffffff); | 2022 | crc32 = crc_32(buf, i, 0xffffffff); |
2023 | 2023 | ||
2024 | if (unique) | 2024 | if (unique) |
2025 | { | 2025 | { |
2026 | /* Check if the crc does not exist -> entry does not exist for sure. */ | 2026 | /* Check if the crc does not exist -> entry does not exist for sure. */ |
@@ -2028,7 +2028,7 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | |||
2028 | { | 2028 | { |
2029 | if (crcbuf[-i] != crc32) | 2029 | if (crcbuf[-i] != crc32) |
2030 | continue; | 2030 | continue; |
2031 | 2031 | ||
2032 | if (!strcasecmp(str, index[i].str)) | 2032 | if (!strcasecmp(str, index[i].str)) |
2033 | { | 2033 | { |
2034 | if (id < 0 || id >= lookup_buffer_depth) | 2034 | if (id < 0 || id >= lookup_buffer_depth) |
@@ -2036,22 +2036,22 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | |||
2036 | logf("lookup buf overf.: %d", id); | 2036 | logf("lookup buf overf.: %d", id); |
2037 | return false; | 2037 | return false; |
2038 | } | 2038 | } |
2039 | 2039 | ||
2040 | lookup[id] = &index[i]; | 2040 | lookup[id] = &index[i]; |
2041 | return true; | 2041 | return true; |
2042 | } | 2042 | } |
2043 | } | 2043 | } |
2044 | } | 2044 | } |
2045 | 2045 | ||
2046 | /* Insert to CRC buffer. */ | 2046 | /* Insert to CRC buffer. */ |
2047 | crcbuf[-tempbufidx] = crc32; | 2047 | crcbuf[-tempbufidx] = crc32; |
2048 | tempbuf_left -= 4; | 2048 | tempbuf_left -= 4; |
2049 | 2049 | ||
2050 | /* Insert it to the buffer. */ | 2050 | /* Insert it to the buffer. */ |
2051 | tempbuf_left -= len; | 2051 | tempbuf_left -= len; |
2052 | if (tempbuf_left - 4 < 0 || tempbufidx >= commit_entry_count-1) | 2052 | if (tempbuf_left - 4 < 0 || tempbufidx >= commit_entry_count-1) |
2053 | return false; | 2053 | return false; |
2054 | 2054 | ||
2055 | if (id >= lookup_buffer_depth) | 2055 | if (id >= lookup_buffer_depth) |
2056 | { | 2056 | { |
2057 | logf("lookup buf overf. #2: %d", id); | 2057 | logf("lookup buf overf. #2: %d", id); |
@@ -2065,7 +2065,7 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | |||
2065 | } | 2065 | } |
2066 | else | 2066 | else |
2067 | index[tempbufidx].idlist.id = -1; | 2067 | index[tempbufidx].idlist.id = -1; |
2068 | 2068 | ||
2069 | index[tempbufidx].idlist.next = NULL; | 2069 | index[tempbufidx].idlist.next = NULL; |
2070 | index[tempbufidx].idx_id = idx_id; | 2070 | index[tempbufidx].idx_id = idx_id; |
2071 | index[tempbufidx].seek = -1; | 2071 | index[tempbufidx].seek = -1; |
@@ -2073,7 +2073,7 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique) | |||
2073 | memcpy(index[tempbufidx].str, str, len); | 2073 | memcpy(index[tempbufidx].str, str, len); |
2074 | tempbuf_pos += len; | 2074 | tempbuf_pos += len; |
2075 | tempbufidx++; | 2075 | tempbufidx++; |
2076 | 2076 | ||
2077 | return true; | 2077 | return true; |
2078 | } | 2078 | } |
2079 | 2079 | ||
@@ -2083,7 +2083,7 @@ static int compare(const void *p1, const void *p2) | |||
2083 | 2083 | ||
2084 | struct tempbuf_searchidx *e1 = (struct tempbuf_searchidx *)p1; | 2084 | struct tempbuf_searchidx *e1 = (struct tempbuf_searchidx *)p1; |
2085 | struct tempbuf_searchidx *e2 = (struct tempbuf_searchidx *)p2; | 2085 | struct tempbuf_searchidx *e2 = (struct tempbuf_searchidx *)p2; |
2086 | 2086 | ||
2087 | if (strcmp(e1->str, UNTAGGED) == 0) | 2087 | if (strcmp(e1->str, UNTAGGED) == 0) |
2088 | { | 2088 | { |
2089 | if (strcmp(e2->str, UNTAGGED) == 0) | 2089 | if (strcmp(e2->str, UNTAGGED) == 0) |
@@ -2092,7 +2092,7 @@ static int compare(const void *p1, const void *p2) | |||
2092 | } | 2092 | } |
2093 | else if (strcmp(e2->str, UNTAGGED) == 0) | 2093 | else if (strcmp(e2->str, UNTAGGED) == 0) |
2094 | return 1; | 2094 | return 1; |
2095 | 2095 | ||
2096 | return strncasecmp(e1->str, e2->str, TAG_MAXLEN); | 2096 | return strncasecmp(e1->str, e2->str, TAG_MAXLEN); |
2097 | } | 2097 | } |
2098 | 2098 | ||
@@ -2102,26 +2102,26 @@ static int tempbuf_sort(int fd) | |||
2102 | struct tagfile_entry fe; | 2102 | struct tagfile_entry fe; |
2103 | int i; | 2103 | int i; |
2104 | int length; | 2104 | int length; |
2105 | 2105 | ||
2106 | /* Generate reverse lookup entries. */ | 2106 | /* Generate reverse lookup entries. */ |
2107 | for (i = 0; i < lookup_buffer_depth; i++) | 2107 | for (i = 0; i < lookup_buffer_depth; i++) |
2108 | { | 2108 | { |
2109 | struct tempbuf_id_list *idlist; | 2109 | struct tempbuf_id_list *idlist; |
2110 | 2110 | ||
2111 | if (!lookup[i]) | 2111 | if (!lookup[i]) |
2112 | continue; | 2112 | continue; |
2113 | 2113 | ||
2114 | if (lookup[i]->idlist.id == i) | 2114 | if (lookup[i]->idlist.id == i) |
2115 | continue; | 2115 | continue; |
2116 | 2116 | ||
2117 | idlist = &lookup[i]->idlist; | 2117 | idlist = &lookup[i]->idlist; |
2118 | while (idlist->next != NULL) | 2118 | while (idlist->next != NULL) |
2119 | idlist = idlist->next; | 2119 | idlist = idlist->next; |
2120 | 2120 | ||
2121 | tempbuf_left -= sizeof(struct tempbuf_id_list); | 2121 | tempbuf_left -= sizeof(struct tempbuf_id_list); |
2122 | if (tempbuf_left - 4 < 0) | 2122 | if (tempbuf_left - 4 < 0) |
2123 | return -1; | 2123 | return -1; |
2124 | 2124 | ||
2125 | idlist->next = (struct tempbuf_id_list *)&tempbuf[tempbuf_pos]; | 2125 | idlist->next = (struct tempbuf_id_list *)&tempbuf[tempbuf_pos]; |
2126 | if (tempbuf_pos & 0x03) | 2126 | if (tempbuf_pos & 0x03) |
2127 | { | 2127 | { |
@@ -2130,21 +2130,21 @@ static int tempbuf_sort(int fd) | |||
2130 | idlist->next = (struct tempbuf_id_list *)&tempbuf[tempbuf_pos]; | 2130 | idlist->next = (struct tempbuf_id_list *)&tempbuf[tempbuf_pos]; |
2131 | } | 2131 | } |
2132 | tempbuf_pos += sizeof(struct tempbuf_id_list); | 2132 | tempbuf_pos += sizeof(struct tempbuf_id_list); |
2133 | 2133 | ||
2134 | idlist = idlist->next; | 2134 | idlist = idlist->next; |
2135 | idlist->id = i; | 2135 | idlist->id = i; |
2136 | idlist->next = NULL; | 2136 | idlist->next = NULL; |
2137 | 2137 | ||
2138 | do_timed_yield(); | 2138 | do_timed_yield(); |
2139 | } | 2139 | } |
2140 | 2140 | ||
2141 | qsort(index, tempbufidx, sizeof(struct tempbuf_searchidx), compare); | 2141 | qsort(index, tempbufidx, sizeof(struct tempbuf_searchidx), compare); |
2142 | memset(lookup, 0, lookup_buffer_depth * sizeof(struct tempbuf_searchidx **)); | 2142 | memset(lookup, 0, lookup_buffer_depth * sizeof(struct tempbuf_searchidx **)); |
2143 | 2143 | ||
2144 | for (i = 0; i < tempbufidx; i++) | 2144 | for (i = 0; i < tempbufidx; i++) |
2145 | { | 2145 | { |
2146 | struct tempbuf_id_list *idlist = &index[i].idlist; | 2146 | struct tempbuf_id_list *idlist = &index[i].idlist; |
2147 | 2147 | ||
2148 | /* Fix the lookup list. */ | 2148 | /* Fix the lookup list. */ |
2149 | while (idlist != NULL) | 2149 | while (idlist != NULL) |
2150 | { | 2150 | { |
@@ -2152,21 +2152,21 @@ static int tempbuf_sort(int fd) | |||
2152 | lookup[idlist->id] = &index[i]; | 2152 | lookup[idlist->id] = &index[i]; |
2153 | idlist = idlist->next; | 2153 | idlist = idlist->next; |
2154 | } | 2154 | } |
2155 | 2155 | ||
2156 | index[i].seek = lseek(fd, 0, SEEK_CUR); | 2156 | index[i].seek = lseek(fd, 0, SEEK_CUR); |
2157 | length = strlen(index[i].str) + 1; | 2157 | length = strlen(index[i].str) + 1; |
2158 | fe.tag_length = length; | 2158 | fe.tag_length = length; |
2159 | fe.idx_id = index[i].idx_id; | 2159 | fe.idx_id = index[i].idx_id; |
2160 | 2160 | ||
2161 | /* Check the chunk alignment. */ | 2161 | /* Check the chunk alignment. */ |
2162 | if ((fe.tag_length + sizeof(struct tagfile_entry)) | 2162 | if ((fe.tag_length + sizeof(struct tagfile_entry)) |
2163 | % TAGFILE_ENTRY_CHUNK_LENGTH) | 2163 | % TAGFILE_ENTRY_CHUNK_LENGTH) |
2164 | { | 2164 | { |
2165 | fe.tag_length += TAGFILE_ENTRY_CHUNK_LENGTH - | 2165 | fe.tag_length += TAGFILE_ENTRY_CHUNK_LENGTH - |
2166 | ((fe.tag_length + sizeof(struct tagfile_entry)) | 2166 | ((fe.tag_length + sizeof(struct tagfile_entry)) |
2167 | % TAGFILE_ENTRY_CHUNK_LENGTH); | 2167 | % TAGFILE_ENTRY_CHUNK_LENGTH); |
2168 | } | 2168 | } |
2169 | 2169 | ||
2170 | #ifdef TAGCACHE_STRICT_ALIGN | 2170 | #ifdef TAGCACHE_STRICT_ALIGN |
2171 | /* Make sure the entry is long aligned. */ | 2171 | /* Make sure the entry is long aligned. */ |
2172 | if (index[i].seek & 0x03) | 2172 | if (index[i].seek & 0x03) |
@@ -2175,20 +2175,20 @@ static int tempbuf_sort(int fd) | |||
2175 | return -3; | 2175 | return -3; |
2176 | } | 2176 | } |
2177 | #endif | 2177 | #endif |
2178 | 2178 | ||
2179 | if (ecwrite(fd, &fe, 1, tagfile_entry_ec, tc_stat.econ) != | 2179 | if (ecwrite(fd, &fe, 1, tagfile_entry_ec, tc_stat.econ) != |
2180 | sizeof(struct tagfile_entry)) | 2180 | sizeof(struct tagfile_entry)) |
2181 | { | 2181 | { |
2182 | logf("tempbuf_sort: write error #1"); | 2182 | logf("tempbuf_sort: write error #1"); |
2183 | return -1; | 2183 | return -1; |
2184 | } | 2184 | } |
2185 | 2185 | ||
2186 | if (write(fd, index[i].str, length) != length) | 2186 | if (write(fd, index[i].str, length) != length) |
2187 | { | 2187 | { |
2188 | logf("tempbuf_sort: write error #2"); | 2188 | logf("tempbuf_sort: write error #2"); |
2189 | return -2; | 2189 | return -2; |
2190 | } | 2190 | } |
2191 | 2191 | ||
2192 | /* Write some padding. */ | 2192 | /* Write some padding. */ |
2193 | if (fe.tag_length - length > 0) | 2193 | if (fe.tag_length - length > 0) |
2194 | write(fd, "XXXXXXXX", fe.tag_length - length); | 2194 | write(fd, "XXXXXXXX", fe.tag_length - length); |
@@ -2196,12 +2196,12 @@ static int tempbuf_sort(int fd) | |||
2196 | 2196 | ||
2197 | return i; | 2197 | return i; |
2198 | } | 2198 | } |
2199 | 2199 | ||
2200 | inline static struct tempbuf_searchidx* tempbuf_locate(int id) | 2200 | inline static struct tempbuf_searchidx* tempbuf_locate(int id) |
2201 | { | 2201 | { |
2202 | if (id < 0 || id >= lookup_buffer_depth) | 2202 | if (id < 0 || id >= lookup_buffer_depth) |
2203 | return NULL; | 2203 | return NULL; |
2204 | 2204 | ||
2205 | return lookup[id]; | 2205 | return lookup[id]; |
2206 | } | 2206 | } |
2207 | 2207 | ||
@@ -2228,15 +2228,15 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2228 | int entries_processed = 0; | 2228 | int entries_processed = 0; |
2229 | int i, j; | 2229 | int i, j; |
2230 | char buf[TAG_MAXLEN]; | 2230 | char buf[TAG_MAXLEN]; |
2231 | 2231 | ||
2232 | max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1; | 2232 | max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1; |
2233 | 2233 | ||
2234 | logf("Building numeric indices..."); | 2234 | logf("Building numeric indices..."); |
2235 | lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); | 2235 | lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); |
2236 | 2236 | ||
2237 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) | 2237 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) |
2238 | return false; | 2238 | return false; |
2239 | 2239 | ||
2240 | masterfd_pos = lseek(masterfd, tcmh.tch.entry_count * sizeof(struct index_entry), | 2240 | masterfd_pos = lseek(masterfd, tcmh.tch.entry_count * sizeof(struct index_entry), |
2241 | SEEK_CUR); | 2241 | SEEK_CUR); |
2242 | if (masterfd_pos < 0) | 2242 | if (masterfd_pos < 0) |
@@ -2249,13 +2249,13 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2249 | while (entries_processed < h->entry_count) | 2249 | while (entries_processed < h->entry_count) |
2250 | { | 2250 | { |
2251 | int count = MIN(h->entry_count - entries_processed, max_entries); | 2251 | int count = MIN(h->entry_count - entries_processed, max_entries); |
2252 | 2252 | ||
2253 | /* Read in as many entries as possible. */ | 2253 | /* Read in as many entries as possible. */ |
2254 | for (i = 0; i < count; i++) | 2254 | for (i = 0; i < count; i++) |
2255 | { | 2255 | { |
2256 | struct temp_file_entry *tfe = &entrybuf[i]; | 2256 | struct temp_file_entry *tfe = &entrybuf[i]; |
2257 | int datastart; | 2257 | int datastart; |
2258 | 2258 | ||
2259 | /* Read in numeric data. */ | 2259 | /* Read in numeric data. */ |
2260 | if (read(tmpfd, tfe, sizeof(struct temp_file_entry)) != | 2260 | if (read(tmpfd, tfe, sizeof(struct temp_file_entry)) != |
2261 | sizeof(struct temp_file_entry)) | 2261 | sizeof(struct temp_file_entry)) |
@@ -2266,14 +2266,14 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2266 | } | 2266 | } |
2267 | 2267 | ||
2268 | datastart = lseek(tmpfd, 0, SEEK_CUR); | 2268 | datastart = lseek(tmpfd, 0, SEEK_CUR); |
2269 | 2269 | ||
2270 | /** | 2270 | /** |
2271 | * Read string data from the following tags: | 2271 | * Read string data from the following tags: |
2272 | * - tag_filename | 2272 | * - tag_filename |
2273 | * - tag_artist | 2273 | * - tag_artist |
2274 | * - tag_album | 2274 | * - tag_album |
2275 | * - tag_title | 2275 | * - tag_title |
2276 | * | 2276 | * |
2277 | * A crc32 hash is calculated from the read data | 2277 | * A crc32 hash is calculated from the read data |
2278 | * and stored back to the data offset field kept in memory. | 2278 | * and stored back to the data offset field kept in memory. |
2279 | */ | 2279 | */ |
@@ -2296,85 +2296,85 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2296 | \ | 2296 | \ |
2297 | tfe->tag_offset[tag] = crc_32(buf, strlen(buf), 0xffffffff); \ | 2297 | tfe->tag_offset[tag] = crc_32(buf, strlen(buf), 0xffffffff); \ |
2298 | lseek(tmpfd, datastart, SEEK_SET) | 2298 | lseek(tmpfd, datastart, SEEK_SET) |
2299 | 2299 | ||
2300 | tmpdb_read_string_tag(tag_filename); | 2300 | tmpdb_read_string_tag(tag_filename); |
2301 | tmpdb_read_string_tag(tag_artist); | 2301 | tmpdb_read_string_tag(tag_artist); |
2302 | tmpdb_read_string_tag(tag_album); | 2302 | tmpdb_read_string_tag(tag_album); |
2303 | tmpdb_read_string_tag(tag_title); | 2303 | tmpdb_read_string_tag(tag_title); |
2304 | 2304 | ||
2305 | /* Seek to the end of the string data. */ | 2305 | /* Seek to the end of the string data. */ |
2306 | lseek(tmpfd, tfe->data_length, SEEK_CUR); | 2306 | lseek(tmpfd, tfe->data_length, SEEK_CUR); |
2307 | } | 2307 | } |
2308 | 2308 | ||
2309 | /* Backup the master index position. */ | 2309 | /* Backup the master index position. */ |
2310 | masterfd_pos = lseek(masterfd, 0, SEEK_CUR); | 2310 | masterfd_pos = lseek(masterfd, 0, SEEK_CUR); |
2311 | lseek(masterfd, sizeof(struct master_header), SEEK_SET); | 2311 | lseek(masterfd, sizeof(struct master_header), SEEK_SET); |
2312 | 2312 | ||
2313 | /* Check if we can resurrect some deleted runtime statistics data. */ | 2313 | /* Check if we can resurrect some deleted runtime statistics data. */ |
2314 | for (i = 0; i < tcmh.tch.entry_count; i++) | 2314 | for (i = 0; i < tcmh.tch.entry_count; i++) |
2315 | { | 2315 | { |
2316 | /* Read the index entry. */ | 2316 | /* Read the index entry. */ |
2317 | if (ecread_index_entry(masterfd, &idx) | 2317 | if (ecread_index_entry(masterfd, &idx) |
2318 | != sizeof(struct index_entry)) | 2318 | != sizeof(struct index_entry)) |
2319 | { | 2319 | { |
2320 | logf("read fail #3"); | 2320 | logf("read fail #3"); |
2321 | close(masterfd); | 2321 | close(masterfd); |
2322 | return false; | 2322 | return false; |
2323 | } | 2323 | } |
2324 | 2324 | ||
2325 | /** | 2325 | /** |
2326 | * Skip unless the entry is marked as being deleted | 2326 | * Skip unless the entry is marked as being deleted |
2327 | * or the data has already been resurrected. | 2327 | * or the data has already been resurrected. |
2328 | */ | 2328 | */ |
2329 | if (!(idx.flag & FLAG_DELETED) || (idx.flag & FLAG_RESURRECTED)) | 2329 | if (!(idx.flag & FLAG_DELETED) || (idx.flag & FLAG_RESURRECTED)) |
2330 | continue; | 2330 | continue; |
2331 | 2331 | ||
2332 | /* Now try to match the entry. */ | 2332 | /* Now try to match the entry. */ |
2333 | /** | 2333 | /** |
2334 | * To succesfully match a song, the following conditions | 2334 | * To succesfully match a song, the following conditions |
2335 | * must apply: | 2335 | * must apply: |
2336 | * | 2336 | * |
2337 | * For numeric fields: tag_length | 2337 | * For numeric fields: tag_length |
2338 | * - Full identical match is required | 2338 | * - Full identical match is required |
2339 | * | 2339 | * |
2340 | * If tag_filename matches, no further checking necessary. | 2340 | * If tag_filename matches, no further checking necessary. |
2341 | * | 2341 | * |
2342 | * For string hashes: tag_artist, tag_album, tag_title | 2342 | * For string hashes: tag_artist, tag_album, tag_title |
2343 | * - All three of these must match | 2343 | * - All three of these must match |
2344 | */ | 2344 | */ |
2345 | for (j = 0; j < count; j++) | 2345 | for (j = 0; j < count; j++) |
2346 | { | 2346 | { |
2347 | struct temp_file_entry *tfe = &entrybuf[j]; | 2347 | struct temp_file_entry *tfe = &entrybuf[j]; |
2348 | 2348 | ||
2349 | /* Try to match numeric fields first. */ | 2349 | /* Try to match numeric fields first. */ |
2350 | if (tfe->tag_offset[tag_length] != idx.tag_seek[tag_length]) | 2350 | if (tfe->tag_offset[tag_length] != idx.tag_seek[tag_length]) |
2351 | continue; | 2351 | continue; |
2352 | 2352 | ||
2353 | /* Now it's time to do the hash matching. */ | 2353 | /* Now it's time to do the hash matching. */ |
2354 | if (tfe->tag_offset[tag_filename] != idx.tag_seek[tag_filename]) | 2354 | if (tfe->tag_offset[tag_filename] != idx.tag_seek[tag_filename]) |
2355 | { | 2355 | { |
2356 | int match_count = 0; | 2356 | int match_count = 0; |
2357 | 2357 | ||
2358 | /* No filename match, check if we can match two other tags. */ | 2358 | /* No filename match, check if we can match two other tags. */ |
2359 | #define tmpdb_match(tag) \ | 2359 | #define tmpdb_match(tag) \ |
2360 | if (tfe->tag_offset[tag] == idx.tag_seek[tag]) \ | 2360 | if (tfe->tag_offset[tag] == idx.tag_seek[tag]) \ |
2361 | match_count++ | 2361 | match_count++ |
2362 | 2362 | ||
2363 | tmpdb_match(tag_artist); | 2363 | tmpdb_match(tag_artist); |
2364 | tmpdb_match(tag_album); | 2364 | tmpdb_match(tag_album); |
2365 | tmpdb_match(tag_title); | 2365 | tmpdb_match(tag_title); |
2366 | 2366 | ||
2367 | if (match_count < 3) | 2367 | if (match_count < 3) |
2368 | { | 2368 | { |
2369 | /* Still no match found, give up. */ | 2369 | /* Still no match found, give up. */ |
2370 | continue; | 2370 | continue; |
2371 | } | 2371 | } |
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | /* A match found, now copy & resurrect the statistical data. */ | 2374 | /* A match found, now copy & resurrect the statistical data. */ |
2375 | #define tmpdb_copy_tag(tag) \ | 2375 | #define tmpdb_copy_tag(tag) \ |
2376 | tfe->tag_offset[tag] = idx.tag_seek[tag] | 2376 | tfe->tag_offset[tag] = idx.tag_seek[tag] |
2377 | 2377 | ||
2378 | tmpdb_copy_tag(tag_playcount); | 2378 | tmpdb_copy_tag(tag_playcount); |
2379 | tmpdb_copy_tag(tag_rating); | 2379 | tmpdb_copy_tag(tag_rating); |
2380 | tmpdb_copy_tag(tag_playtime); | 2380 | tmpdb_copy_tag(tag_playtime); |
@@ -2382,10 +2382,10 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2382 | tmpdb_copy_tag(tag_commitid); | 2382 | tmpdb_copy_tag(tag_commitid); |
2383 | tmpdb_copy_tag(tag_lastelapsed); | 2383 | tmpdb_copy_tag(tag_lastelapsed); |
2384 | tmpdb_copy_tag(tag_lastoffset); | 2384 | tmpdb_copy_tag(tag_lastoffset); |
2385 | 2385 | ||
2386 | /* Avoid processing this entry again. */ | 2386 | /* Avoid processing this entry again. */ |
2387 | idx.flag |= FLAG_RESURRECTED; | 2387 | idx.flag |= FLAG_RESURRECTED; |
2388 | 2388 | ||
2389 | lseek(masterfd, -(off_t)sizeof(struct index_entry), SEEK_CUR); | 2389 | lseek(masterfd, -(off_t)sizeof(struct index_entry), SEEK_CUR); |
2390 | if (ecwrite_index_entry(masterfd, &idx) != sizeof(struct index_entry)) | 2390 | if (ecwrite_index_entry(masterfd, &idx) != sizeof(struct index_entry)) |
2391 | { | 2391 | { |
@@ -2393,36 +2393,36 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2393 | close(masterfd); | 2393 | close(masterfd); |
2394 | return false; | 2394 | return false; |
2395 | } | 2395 | } |
2396 | 2396 | ||
2397 | logf("Entry resurrected"); | 2397 | logf("Entry resurrected"); |
2398 | } | 2398 | } |
2399 | } | 2399 | } |
2400 | 2400 | ||
2401 | 2401 | ||
2402 | /* Restore the master index position. */ | 2402 | /* Restore the master index position. */ |
2403 | lseek(masterfd, masterfd_pos, SEEK_SET); | 2403 | lseek(masterfd, masterfd_pos, SEEK_SET); |
2404 | 2404 | ||
2405 | /* Commit the data to the index. */ | 2405 | /* Commit the data to the index. */ |
2406 | for (i = 0; i < count; i++) | 2406 | for (i = 0; i < count; i++) |
2407 | { | 2407 | { |
2408 | int loc = lseek(masterfd, 0, SEEK_CUR); | 2408 | int loc = lseek(masterfd, 0, SEEK_CUR); |
2409 | 2409 | ||
2410 | if (ecread_index_entry(masterfd, &idx) != sizeof(struct index_entry)) | 2410 | if (ecread_index_entry(masterfd, &idx) != sizeof(struct index_entry)) |
2411 | { | 2411 | { |
2412 | logf("read fail #3"); | 2412 | logf("read fail #3"); |
2413 | close(masterfd); | 2413 | close(masterfd); |
2414 | return false; | 2414 | return false; |
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | for (j = 0; j < TAG_COUNT; j++) | 2417 | for (j = 0; j < TAG_COUNT; j++) |
2418 | { | 2418 | { |
2419 | if (!TAGCACHE_IS_NUMERIC(j)) | 2419 | if (!TAGCACHE_IS_NUMERIC(j)) |
2420 | continue; | 2420 | continue; |
2421 | 2421 | ||
2422 | idx.tag_seek[j] = entrybuf[i].tag_offset[j]; | 2422 | idx.tag_seek[j] = entrybuf[i].tag_offset[j]; |
2423 | } | 2423 | } |
2424 | idx.flag = entrybuf[i].flag; | 2424 | idx.flag = entrybuf[i].flag; |
2425 | 2425 | ||
2426 | if (idx.tag_seek[tag_commitid]) | 2426 | if (idx.tag_seek[tag_commitid]) |
2427 | { | 2427 | { |
2428 | /* Data has been resurrected. */ | 2428 | /* Data has been resurrected. */ |
@@ -2433,7 +2433,7 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2433 | idx.tag_seek[tag_commitid] = current_tcmh.commitid; | 2433 | idx.tag_seek[tag_commitid] = current_tcmh.commitid; |
2434 | idx.flag |= FLAG_DIRTYNUM; | 2434 | idx.flag |= FLAG_DIRTYNUM; |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | /* Write back the updated index. */ | 2437 | /* Write back the updated index. */ |
2438 | lseek(masterfd, loc, SEEK_SET); | 2438 | lseek(masterfd, loc, SEEK_SET); |
2439 | if (ecwrite_index_entry(masterfd, &idx) != sizeof(struct index_entry)) | 2439 | if (ecwrite_index_entry(masterfd, &idx) != sizeof(struct index_entry)) |
@@ -2443,13 +2443,13 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) | |||
2443 | return false; | 2443 | return false; |
2444 | } | 2444 | } |
2445 | } | 2445 | } |
2446 | 2446 | ||
2447 | entries_processed += count; | 2447 | entries_processed += count; |
2448 | logf("%d/%ld entries processed", entries_processed, h->entry_count); | 2448 | logf("%d/%ld entries processed", entries_processed, h->entry_count); |
2449 | } | 2449 | } |
2450 | 2450 | ||
2451 | close(masterfd); | 2451 | close(masterfd); |
2452 | 2452 | ||
2453 | return true; | 2453 | return true; |
2454 | } | 2454 | } |
2455 | 2455 | ||
@@ -2471,12 +2471,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2471 | bool error = false; | 2471 | bool error = false; |
2472 | int init; | 2472 | int init; |
2473 | int masterfd_pos; | 2473 | int masterfd_pos; |
2474 | 2474 | ||
2475 | logf("Building index: %d", index_type); | 2475 | logf("Building index: %d", index_type); |
2476 | 2476 | ||
2477 | /* Check the number of entries we need to allocate ram for. */ | 2477 | /* Check the number of entries we need to allocate ram for. */ |
2478 | commit_entry_count = h->entry_count + 1; | 2478 | commit_entry_count = h->entry_count + 1; |
2479 | 2479 | ||
2480 | masterfd = open_master_fd(&tcmh, false); | 2480 | masterfd = open_master_fd(&tcmh, false); |
2481 | if (masterfd >= 0) | 2481 | if (masterfd >= 0) |
2482 | { | 2482 | { |
@@ -2501,10 +2501,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2501 | /* First part */ commit_entry_count + | 2501 | /* First part */ commit_entry_count + |
2502 | /* Second part */ 0; | 2502 | /* Second part */ 0; |
2503 | } | 2503 | } |
2504 | 2504 | ||
2505 | logf("lookup_buffer_depth=%ld", lookup_buffer_depth); | 2505 | logf("lookup_buffer_depth=%ld", lookup_buffer_depth); |
2506 | logf("commit_entry_count=%ld", commit_entry_count); | 2506 | logf("commit_entry_count=%ld", commit_entry_count); |
2507 | 2507 | ||
2508 | /* Allocate buffer for all index entries from both old and new | 2508 | /* Allocate buffer for all index entries from both old and new |
2509 | * tag files. */ | 2509 | * tag files. */ |
2510 | tempbufidx = 0; | 2510 | tempbufidx = 0; |
@@ -2513,21 +2513,21 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2513 | /* Allocate lookup buffer. The first portion of commit_entry_count | 2513 | /* Allocate lookup buffer. The first portion of commit_entry_count |
2514 | * contains the new tags in the temporary file and the second | 2514 | * contains the new tags in the temporary file and the second |
2515 | * part for locating entries already in the db. | 2515 | * part for locating entries already in the db. |
2516 | * | 2516 | * |
2517 | * New tags Old tags | 2517 | * New tags Old tags |
2518 | * +---------+---------------------------+ | 2518 | * +---------+---------------------------+ |
2519 | * | index | position/ENTRY_CHUNK_SIZE | lookup buffer | 2519 | * | index | position/ENTRY_CHUNK_SIZE | lookup buffer |
2520 | * +---------+---------------------------+ | 2520 | * +---------+---------------------------+ |
2521 | * | 2521 | * |
2522 | * Old tags are inserted to a temporary buffer with position: | 2522 | * Old tags are inserted to a temporary buffer with position: |
2523 | * tempbuf_insert(position/ENTRY_CHUNK_SIZE, ...); | 2523 | * tempbuf_insert(position/ENTRY_CHUNK_SIZE, ...); |
2524 | * And new tags with index: | 2524 | * And new tags with index: |
2525 | * tempbuf_insert(idx, ...); | 2525 | * tempbuf_insert(idx, ...); |
2526 | * | 2526 | * |
2527 | * The buffer is sorted and written into tag file: | 2527 | * The buffer is sorted and written into tag file: |
2528 | * tempbuf_sort(...); | 2528 | * tempbuf_sort(...); |
2529 | * leaving master index locations messed up. | 2529 | * leaving master index locations messed up. |
2530 | * | 2530 | * |
2531 | * That is fixed using the lookup buffer for old tags: | 2531 | * That is fixed using the lookup buffer for old tags: |
2532 | * new_seek = tempbuf_find_location(old_seek, ...); | 2532 | * new_seek = tempbuf_find_location(old_seek, ...); |
2533 | * and for new tags: | 2533 | * and for new tags: |
@@ -2536,7 +2536,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2536 | lookup = (struct tempbuf_searchidx **)&tempbuf[tempbuf_pos]; | 2536 | lookup = (struct tempbuf_searchidx **)&tempbuf[tempbuf_pos]; |
2537 | tempbuf_pos += lookup_buffer_depth * sizeof(void **); | 2537 | tempbuf_pos += lookup_buffer_depth * sizeof(void **); |
2538 | memset(lookup, 0, lookup_buffer_depth * sizeof(void **)); | 2538 | memset(lookup, 0, lookup_buffer_depth * sizeof(void **)); |
2539 | 2539 | ||
2540 | /* And calculate the remaining data space used mainly for storing | 2540 | /* And calculate the remaining data space used mainly for storing |
2541 | * tag data (strings). */ | 2541 | * tag data (strings). */ |
2542 | tempbuf_left = tempbuf_size - tempbuf_pos - 8; | 2542 | tempbuf_left = tempbuf_size - tempbuf_pos - 8; |
@@ -2561,21 +2561,21 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2561 | struct tagfile_entry entry; | 2561 | struct tagfile_entry entry; |
2562 | int loc = lseek(fd, 0, SEEK_CUR); | 2562 | int loc = lseek(fd, 0, SEEK_CUR); |
2563 | bool ret; | 2563 | bool ret; |
2564 | 2564 | ||
2565 | if (ecread_tagfile_entry(fd, &entry) != sizeof(struct tagfile_entry)) | 2565 | if (ecread_tagfile_entry(fd, &entry) != sizeof(struct tagfile_entry)) |
2566 | { | 2566 | { |
2567 | logf("read error #7"); | 2567 | logf("read error #7"); |
2568 | close(fd); | 2568 | close(fd); |
2569 | return -2; | 2569 | return -2; |
2570 | } | 2570 | } |
2571 | 2571 | ||
2572 | if (entry.tag_length >= (int)sizeof(buf)) | 2572 | if (entry.tag_length >= (int)sizeof(buf)) |
2573 | { | 2573 | { |
2574 | logf("too long tag #3"); | 2574 | logf("too long tag #3"); |
2575 | close(fd); | 2575 | close(fd); |
2576 | return -2; | 2576 | return -2; |
2577 | } | 2577 | } |
2578 | 2578 | ||
2579 | if (read(fd, buf, entry.tag_length) != entry.tag_length) | 2579 | if (read(fd, buf, entry.tag_length) != entry.tag_length) |
2580 | { | 2580 | { |
2581 | logf("read error #8"); | 2581 | logf("read error #8"); |
@@ -2586,13 +2586,13 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2586 | /* Skip deleted entries. */ | 2586 | /* Skip deleted entries. */ |
2587 | if (buf[0] == '\0') | 2587 | if (buf[0] == '\0') |
2588 | continue; | 2588 | continue; |
2589 | 2589 | ||
2590 | /** | 2590 | /** |
2591 | * Save the tag and tag id in the memory buffer. Tag id | 2591 | * Save the tag and tag id in the memory buffer. Tag id |
2592 | * is saved so we can later reindex the master lookup | 2592 | * is saved so we can later reindex the master lookup |
2593 | * table when the index gets resorted. | 2593 | * table when the index gets resorted. |
2594 | */ | 2594 | */ |
2595 | ret = tempbuf_insert(buf, loc/TAGFILE_ENTRY_CHUNK_LENGTH | 2595 | ret = tempbuf_insert(buf, loc/TAGFILE_ENTRY_CHUNK_LENGTH |
2596 | + commit_entry_count, entry.idx_id, | 2596 | + commit_entry_count, entry.idx_id, |
2597 | TAGCACHE_IS_UNIQUE(index_type)); | 2597 | TAGCACHE_IS_UNIQUE(index_type)); |
2598 | if (!ret) | 2598 | if (!ret) |
@@ -2620,12 +2620,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2620 | logf("%s open fail", buf); | 2620 | logf("%s open fail", buf); |
2621 | return -2; | 2621 | return -2; |
2622 | } | 2622 | } |
2623 | 2623 | ||
2624 | tch.magic = TAGCACHE_MAGIC; | 2624 | tch.magic = TAGCACHE_MAGIC; |
2625 | tch.entry_count = 0; | 2625 | tch.entry_count = 0; |
2626 | tch.datasize = 0; | 2626 | tch.datasize = 0; |
2627 | 2627 | ||
2628 | if (ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ) | 2628 | if (ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ) |
2629 | != sizeof(struct tagcache_header)) | 2629 | != sizeof(struct tagcache_header)) |
2630 | { | 2630 | { |
2631 | logf("header write failed"); | 2631 | logf("header write failed"); |
@@ -2705,7 +2705,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2705 | for (i = 0; i < h->entry_count; i++) | 2705 | for (i = 0; i < h->entry_count; i++) |
2706 | { | 2706 | { |
2707 | struct temp_file_entry entry; | 2707 | struct temp_file_entry entry; |
2708 | 2708 | ||
2709 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | 2709 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != |
2710 | sizeof(struct temp_file_entry)) | 2710 | sizeof(struct temp_file_entry)) |
2711 | { | 2711 | { |
@@ -2730,18 +2730,18 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2730 | error = true; | 2730 | error = true; |
2731 | goto error_exit; | 2731 | goto error_exit; |
2732 | } | 2732 | } |
2733 | 2733 | ||
2734 | if (TAGCACHE_IS_UNIQUE(index_type)) | 2734 | if (TAGCACHE_IS_UNIQUE(index_type)) |
2735 | error = !tempbuf_insert(buf, i, -1, true); | 2735 | error = !tempbuf_insert(buf, i, -1, true); |
2736 | else | 2736 | else |
2737 | error = !tempbuf_insert(buf, i, tcmh.tch.entry_count + i, false); | 2737 | error = !tempbuf_insert(buf, i, tcmh.tch.entry_count + i, false); |
2738 | 2738 | ||
2739 | if (error) | 2739 | if (error) |
2740 | { | 2740 | { |
2741 | logf("insert error"); | 2741 | logf("insert error"); |
2742 | goto error_exit; | 2742 | goto error_exit; |
2743 | } | 2743 | } |
2744 | 2744 | ||
2745 | /* Skip to next. */ | 2745 | /* Skip to next. */ |
2746 | lseek(tmpfd, entry.data_length - entry.tag_offset[index_type] - | 2746 | lseek(tmpfd, entry.data_length - entry.tag_offset[index_type] - |
2747 | entry.tag_length[index_type], SEEK_CUR); | 2747 | entry.tag_length[index_type], SEEK_CUR); |
@@ -2757,12 +2757,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2757 | * entry_count and don't crash with that). | 2757 | * entry_count and don't crash with that). |
2758 | */ | 2758 | */ |
2759 | ftruncate(fd, lseek(fd, 0, SEEK_CUR)); | 2759 | ftruncate(fd, lseek(fd, 0, SEEK_CUR)); |
2760 | 2760 | ||
2761 | i = tempbuf_sort(fd); | 2761 | i = tempbuf_sort(fd); |
2762 | if (i < 0) | 2762 | if (i < 0) |
2763 | goto error_exit; | 2763 | goto error_exit; |
2764 | logf("sorted %d tags", i); | 2764 | logf("sorted %d tags", i); |
2765 | 2765 | ||
2766 | /** | 2766 | /** |
2767 | * Now update all indexes in the master lookup file. | 2767 | * Now update all indexes in the master lookup file. |
2768 | */ | 2768 | */ |
@@ -2772,10 +2772,10 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2772 | { | 2772 | { |
2773 | int j; | 2773 | int j; |
2774 | int loc = lseek(masterfd, 0, SEEK_CUR); | 2774 | int loc = lseek(masterfd, 0, SEEK_CUR); |
2775 | 2775 | ||
2776 | idxbuf_pos = MIN(tcmh.tch.entry_count - i, IDX_BUF_DEPTH); | 2776 | idxbuf_pos = MIN(tcmh.tch.entry_count - i, IDX_BUF_DEPTH); |
2777 | 2777 | ||
2778 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) | 2778 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) |
2779 | != (int)sizeof(struct index_entry)*idxbuf_pos) | 2779 | != (int)sizeof(struct index_entry)*idxbuf_pos) |
2780 | { | 2780 | { |
2781 | logf("read fail #5"); | 2781 | logf("read fail #5"); |
@@ -2783,7 +2783,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2783 | goto error_exit ; | 2783 | goto error_exit ; |
2784 | } | 2784 | } |
2785 | lseek(masterfd, loc, SEEK_SET); | 2785 | lseek(masterfd, loc, SEEK_SET); |
2786 | 2786 | ||
2787 | for (j = 0; j < idxbuf_pos; j++) | 2787 | for (j = 0; j < idxbuf_pos; j++) |
2788 | { | 2788 | { |
2789 | if (idxbuf[j].flag & FLAG_DELETED) | 2789 | if (idxbuf[j].flag & FLAG_DELETED) |
@@ -2792,22 +2792,22 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2792 | // idxbuf[j].tag_seek[index_type] = 0; | 2792 | // idxbuf[j].tag_seek[index_type] = 0; |
2793 | continue; | 2793 | continue; |
2794 | } | 2794 | } |
2795 | 2795 | ||
2796 | idxbuf[j].tag_seek[index_type] = tempbuf_find_location( | 2796 | idxbuf[j].tag_seek[index_type] = tempbuf_find_location( |
2797 | idxbuf[j].tag_seek[index_type]/TAGFILE_ENTRY_CHUNK_LENGTH | 2797 | idxbuf[j].tag_seek[index_type]/TAGFILE_ENTRY_CHUNK_LENGTH |
2798 | + commit_entry_count); | 2798 | + commit_entry_count); |
2799 | 2799 | ||
2800 | if (idxbuf[j].tag_seek[index_type] < 0) | 2800 | if (idxbuf[j].tag_seek[index_type] < 0) |
2801 | { | 2801 | { |
2802 | logf("update error: %ld/%d/%ld", | 2802 | logf("update error: %ld/%d/%ld", |
2803 | idxbuf[j].flag, i+j, tcmh.tch.entry_count); | 2803 | idxbuf[j].flag, i+j, tcmh.tch.entry_count); |
2804 | error = true; | 2804 | error = true; |
2805 | goto error_exit; | 2805 | goto error_exit; |
2806 | } | 2806 | } |
2807 | 2807 | ||
2808 | do_timed_yield(); | 2808 | do_timed_yield(); |
2809 | } | 2809 | } |
2810 | 2810 | ||
2811 | /* Write back the updated index. */ | 2811 | /* Write back the updated index. */ |
2812 | if (ecwrite(masterfd, idxbuf, idxbuf_pos, | 2812 | if (ecwrite(masterfd, idxbuf, idxbuf_pos, |
2813 | index_entry_ec, tc_stat.econ) != | 2813 | index_entry_ec, tc_stat.econ) != |
@@ -2832,7 +2832,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2832 | for (i = 0; i < h->entry_count; i += idxbuf_pos) | 2832 | for (i = 0; i < h->entry_count; i += idxbuf_pos) |
2833 | { | 2833 | { |
2834 | int j; | 2834 | int j; |
2835 | 2835 | ||
2836 | idxbuf_pos = MIN(h->entry_count - i, IDX_BUF_DEPTH); | 2836 | idxbuf_pos = MIN(h->entry_count - i, IDX_BUF_DEPTH); |
2837 | if (init) | 2837 | if (init) |
2838 | { | 2838 | { |
@@ -2841,8 +2841,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2841 | else | 2841 | else |
2842 | { | 2842 | { |
2843 | int loc = lseek(masterfd, 0, SEEK_CUR); | 2843 | int loc = lseek(masterfd, 0, SEEK_CUR); |
2844 | 2844 | ||
2845 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) | 2845 | if (ecread(masterfd, idxbuf, idxbuf_pos, index_entry_ec, tc_stat.econ) |
2846 | != (int)sizeof(struct index_entry)*idxbuf_pos) | 2846 | != (int)sizeof(struct index_entry)*idxbuf_pos) |
2847 | { | 2847 | { |
2848 | logf("read fail #6"); | 2848 | logf("read fail #6"); |
@@ -2859,7 +2859,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2859 | { | 2859 | { |
2860 | struct temp_file_entry entry; | 2860 | struct temp_file_entry entry; |
2861 | struct tagfile_entry fe; | 2861 | struct tagfile_entry fe; |
2862 | 2862 | ||
2863 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | 2863 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != |
2864 | sizeof(struct temp_file_entry)) | 2864 | sizeof(struct temp_file_entry)) |
2865 | { | 2865 | { |
@@ -2867,7 +2867,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2867 | error = true; | 2867 | error = true; |
2868 | break ; | 2868 | break ; |
2869 | } | 2869 | } |
2870 | 2870 | ||
2871 | /* Read data. */ | 2871 | /* Read data. */ |
2872 | if (entry.tag_length[index_type] >= (int)sizeof(buf)) | 2872 | if (entry.tag_length[index_type] >= (int)sizeof(buf)) |
2873 | { | 2873 | { |
@@ -2877,7 +2877,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2877 | error = true; | 2877 | error = true; |
2878 | break ; | 2878 | break ; |
2879 | } | 2879 | } |
2880 | 2880 | ||
2881 | lseek(tmpfd, entry.tag_offset[index_type], SEEK_CUR); | 2881 | lseek(tmpfd, entry.tag_offset[index_type], SEEK_CUR); |
2882 | if (read(tmpfd, buf, entry.tag_length[index_type]) != | 2882 | if (read(tmpfd, buf, entry.tag_length[index_type]) != |
2883 | entry.tag_length[index_type]) | 2883 | entry.tag_length[index_type]) |
@@ -2923,29 +2923,29 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd) | |||
2923 | error = true; | 2923 | error = true; |
2924 | break ; | 2924 | break ; |
2925 | } | 2925 | } |
2926 | 2926 | ||
2927 | do_timed_yield(); | 2927 | do_timed_yield(); |
2928 | } | 2928 | } |
2929 | logf("done"); | 2929 | logf("done"); |
2930 | 2930 | ||
2931 | /* Finally write the header. */ | 2931 | /* Finally write the header. */ |
2932 | tch.magic = TAGCACHE_MAGIC; | 2932 | tch.magic = TAGCACHE_MAGIC; |
2933 | tch.entry_count = tempbufidx; | 2933 | tch.entry_count = tempbufidx; |
2934 | tch.datasize = lseek(fd, 0, SEEK_END) - sizeof(struct tagcache_header); | 2934 | tch.datasize = lseek(fd, 0, SEEK_END) - sizeof(struct tagcache_header); |
2935 | lseek(fd, 0, SEEK_SET); | 2935 | lseek(fd, 0, SEEK_SET); |
2936 | ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ); | 2936 | ecwrite(fd, &tch, 1, tagcache_header_ec, tc_stat.econ); |
2937 | 2937 | ||
2938 | if (index_type != tag_filename) | 2938 | if (index_type != tag_filename) |
2939 | h->datasize += tch.datasize; | 2939 | h->datasize += tch.datasize; |
2940 | logf("s:%d/%ld/%ld", index_type, tch.datasize, h->datasize); | 2940 | logf("s:%d/%ld/%ld", index_type, tch.datasize, h->datasize); |
2941 | error_exit: | 2941 | error_exit: |
2942 | 2942 | ||
2943 | close(fd); | 2943 | close(fd); |
2944 | close(masterfd); | 2944 | close(masterfd); |
2945 | 2945 | ||
2946 | if (error) | 2946 | if (error) |
2947 | return -2; | 2947 | return -2; |
2948 | 2948 | ||
2949 | return 1; | 2949 | return 1; |
2950 | } | 2950 | } |
2951 | 2951 | ||
@@ -2963,7 +2963,7 @@ static bool commit(void) | |||
2963 | bool ramcache_buffer_stolen = false; | 2963 | bool ramcache_buffer_stolen = false; |
2964 | #endif | 2964 | #endif |
2965 | logf("committing tagcache"); | 2965 | logf("committing tagcache"); |
2966 | 2966 | ||
2967 | while (write_lock) | 2967 | while (write_lock) |
2968 | sleep(1); | 2968 | sleep(1); |
2969 | 2969 | ||
@@ -2973,12 +2973,12 @@ static bool commit(void) | |||
2973 | logf("nothing to commit"); | 2973 | logf("nothing to commit"); |
2974 | return true; | 2974 | return true; |
2975 | } | 2975 | } |
2976 | 2976 | ||
2977 | 2977 | ||
2978 | /* Load the header. */ | 2978 | /* Load the header. */ |
2979 | len = sizeof(struct tagcache_header); | 2979 | len = sizeof(struct tagcache_header); |
2980 | rc = read(tmpfd, &tch, len); | 2980 | rc = read(tmpfd, &tch, len); |
2981 | 2981 | ||
2982 | if (tch.magic != TAGCACHE_MAGIC || rc != len) | 2982 | if (tch.magic != TAGCACHE_MAGIC || rc != len) |
2983 | { | 2983 | { |
2984 | logf("incorrect tmpheader"); | 2984 | logf("incorrect tmpheader"); |
@@ -2992,11 +2992,11 @@ static bool commit(void) | |||
2992 | 2992 | ||
2993 | /* Fully initialize existing headers (if any) before going further. */ | 2993 | /* Fully initialize existing headers (if any) before going further. */ |
2994 | tc_stat.ready = check_all_headers(); | 2994 | tc_stat.ready = check_all_headers(); |
2995 | 2995 | ||
2996 | #ifdef HAVE_EEPROM_SETTINGS | 2996 | #ifdef HAVE_EEPROM_SETTINGS |
2997 | remove(TAGCACHE_STATEFILE); | 2997 | remove(TAGCACHE_STATEFILE); |
2998 | #endif | 2998 | #endif |
2999 | 2999 | ||
3000 | /* At first be sure to unload the ramcache! */ | 3000 | /* At first be sure to unload the ramcache! */ |
3001 | #ifdef HAVE_TC_RAMCACHE | 3001 | #ifdef HAVE_TC_RAMCACHE |
3002 | tc_stat.ramcache = false; | 3002 | tc_stat.ramcache = false; |
@@ -3005,7 +3005,7 @@ static bool commit(void) | |||
3005 | /* Beyond here, jump to commit_error to undo locks and restore dircache */ | 3005 | /* Beyond here, jump to commit_error to undo locks and restore dircache */ |
3006 | rc = false; | 3006 | rc = false; |
3007 | read_lock++; | 3007 | read_lock++; |
3008 | 3008 | ||
3009 | /* Try to steal every buffer we can :) */ | 3009 | /* Try to steal every buffer we can :) */ |
3010 | #ifdef HAVE_DIRCACHE | 3010 | #ifdef HAVE_DIRCACHE |
3011 | if (tempbuf_size == 0) | 3011 | if (tempbuf_size == 0) |
@@ -3017,7 +3017,7 @@ static bool commit(void) | |||
3017 | allocate_tempbuf(); | 3017 | allocate_tempbuf(); |
3018 | } | 3018 | } |
3019 | #endif /* HAVE_DIRCACHE */ | 3019 | #endif /* HAVE_DIRCACHE */ |
3020 | 3020 | ||
3021 | #ifdef HAVE_TC_RAMCACHE | 3021 | #ifdef HAVE_TC_RAMCACHE |
3022 | if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) | 3022 | if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0) |
3023 | { | 3023 | { |
@@ -3028,7 +3028,7 @@ static bool commit(void) | |||
3028 | ramcache_buffer_stolen = true; | 3028 | ramcache_buffer_stolen = true; |
3029 | } | 3029 | } |
3030 | #endif /* HAVE_TC_RAMCACHE */ | 3030 | #endif /* HAVE_TC_RAMCACHE */ |
3031 | 3031 | ||
3032 | /* And finally fail if there are no buffers available. */ | 3032 | /* And finally fail if there are no buffers available. */ |
3033 | if (tempbuf_size == 0) | 3033 | if (tempbuf_size == 0) |
3034 | { | 3034 | { |
@@ -3037,25 +3037,25 @@ static bool commit(void) | |||
3037 | close(tmpfd); | 3037 | close(tmpfd); |
3038 | goto commit_error; | 3038 | goto commit_error; |
3039 | } | 3039 | } |
3040 | 3040 | ||
3041 | logf("commit %ld entries...", tch.entry_count); | 3041 | logf("commit %ld entries...", tch.entry_count); |
3042 | 3042 | ||
3043 | /* Mark DB dirty so it will stay disabled if commit fails. */ | 3043 | /* Mark DB dirty so it will stay disabled if commit fails. */ |
3044 | current_tcmh.dirty = true; | 3044 | current_tcmh.dirty = true; |
3045 | update_master_header(); | 3045 | update_master_header(); |
3046 | 3046 | ||
3047 | /* Now create the index files. */ | 3047 | /* Now create the index files. */ |
3048 | tc_stat.commit_step = 0; | 3048 | tc_stat.commit_step = 0; |
3049 | tch.datasize = 0; | 3049 | tch.datasize = 0; |
3050 | tc_stat.commit_delayed = false; | 3050 | tc_stat.commit_delayed = false; |
3051 | 3051 | ||
3052 | for (i = 0; i < TAG_COUNT; i++) | 3052 | for (i = 0; i < TAG_COUNT; i++) |
3053 | { | 3053 | { |
3054 | int ret; | 3054 | int ret; |
3055 | 3055 | ||
3056 | if (TAGCACHE_IS_NUMERIC(i)) | 3056 | if (TAGCACHE_IS_NUMERIC(i)) |
3057 | continue; | 3057 | continue; |
3058 | 3058 | ||
3059 | tc_stat.commit_step++; | 3059 | tc_stat.commit_step++; |
3060 | ret = build_index(i, &tch, tmpfd); | 3060 | ret = build_index(i, &tch, tmpfd); |
3061 | if (ret <= 0) | 3061 | if (ret <= 0) |
@@ -3064,12 +3064,12 @@ static bool commit(void) | |||
3064 | logf("tagcache failed init"); | 3064 | logf("tagcache failed init"); |
3065 | if (ret == 0) | 3065 | if (ret == 0) |
3066 | tc_stat.commit_delayed = true; | 3066 | tc_stat.commit_delayed = true; |
3067 | 3067 | ||
3068 | tc_stat.commit_step = 0; | 3068 | tc_stat.commit_step = 0; |
3069 | goto commit_error; | 3069 | goto commit_error; |
3070 | } | 3070 | } |
3071 | } | 3071 | } |
3072 | 3072 | ||
3073 | if (!build_numeric_indices(&tch, tmpfd)) | 3073 | if (!build_numeric_indices(&tch, tmpfd)) |
3074 | { | 3074 | { |
3075 | logf("Failure to commit numeric indices"); | 3075 | logf("Failure to commit numeric indices"); |
@@ -3077,19 +3077,19 @@ static bool commit(void) | |||
3077 | tc_stat.commit_step = 0; | 3077 | tc_stat.commit_step = 0; |
3078 | goto commit_error; | 3078 | goto commit_error; |
3079 | } | 3079 | } |
3080 | 3080 | ||
3081 | close(tmpfd); | 3081 | close(tmpfd); |
3082 | 3082 | ||
3083 | tc_stat.commit_step = 0; | 3083 | tc_stat.commit_step = 0; |
3084 | 3084 | ||
3085 | /* Update the master index headers. */ | 3085 | /* Update the master index headers. */ |
3086 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) | 3086 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) |
3087 | goto commit_error; | 3087 | goto commit_error; |
3088 | 3088 | ||
3089 | remove(TAGCACHE_FILE_TEMP); | 3089 | remove(TAGCACHE_FILE_TEMP); |
3090 | 3090 | ||
3091 | tcmh.tch.entry_count += tch.entry_count; | 3091 | tcmh.tch.entry_count += tch.entry_count; |
3092 | tcmh.tch.datasize = sizeof(struct master_header) | 3092 | tcmh.tch.datasize = sizeof(struct master_header) |
3093 | + sizeof(struct index_entry) * tcmh.tch.entry_count | 3093 | + sizeof(struct index_entry) * tcmh.tch.entry_count |
3094 | + tch.datasize; | 3094 | + tch.datasize; |
3095 | tcmh.dirty = false; | 3095 | tcmh.dirty = false; |
@@ -3098,11 +3098,11 @@ static bool commit(void) | |||
3098 | lseek(masterfd, 0, SEEK_SET); | 3098 | lseek(masterfd, 0, SEEK_SET); |
3099 | ecwrite(masterfd, &tcmh, 1, master_header_ec, tc_stat.econ); | 3099 | ecwrite(masterfd, &tcmh, 1, master_header_ec, tc_stat.econ); |
3100 | close(masterfd); | 3100 | close(masterfd); |
3101 | 3101 | ||
3102 | logf("tagcache committed"); | 3102 | logf("tagcache committed"); |
3103 | tc_stat.ready = check_all_headers(); | 3103 | tc_stat.ready = check_all_headers(); |
3104 | tc_stat.readyvalid = true; | 3104 | tc_stat.readyvalid = true; |
3105 | 3105 | ||
3106 | #ifdef HAVE_TC_RAMCACHE | 3106 | #ifdef HAVE_TC_RAMCACHE |
3107 | if (ramcache_buffer_stolen) | 3107 | if (ramcache_buffer_stolen) |
3108 | { | 3108 | { |
@@ -3116,7 +3116,7 @@ static bool commit(void) | |||
3116 | if (tc_stat.ramcache_allocated > 0) | 3116 | if (tc_stat.ramcache_allocated > 0) |
3117 | tagcache_start_scan(); | 3117 | tagcache_start_scan(); |
3118 | #endif /* HAVE_TC_RAMCACHE */ | 3118 | #endif /* HAVE_TC_RAMCACHE */ |
3119 | 3119 | ||
3120 | rc = true; | 3120 | rc = true; |
3121 | 3121 | ||
3122 | commit_error: | 3122 | commit_error: |
@@ -3139,7 +3139,7 @@ commit_error: | |||
3139 | dircache_resume(); | 3139 | dircache_resume(); |
3140 | } | 3140 | } |
3141 | #endif /* HAVE_DIRCACHE */ | 3141 | #endif /* HAVE_DIRCACHE */ |
3142 | 3142 | ||
3143 | return rc; | 3143 | return rc; |
3144 | } | 3144 | } |
3145 | 3145 | ||
@@ -3148,34 +3148,34 @@ commit_error: | |||
3148 | static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) | 3148 | static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data) |
3149 | { | 3149 | { |
3150 | struct index_entry idx; | 3150 | struct index_entry idx; |
3151 | 3151 | ||
3152 | if (!tc_stat.ready) | 3152 | if (!tc_stat.ready) |
3153 | return false; | 3153 | return false; |
3154 | 3154 | ||
3155 | if (!TAGCACHE_IS_NUMERIC(tag)) | 3155 | if (!TAGCACHE_IS_NUMERIC(tag)) |
3156 | return false; | 3156 | return false; |
3157 | 3157 | ||
3158 | if (!get_index(masterfd, idx_id, &idx, false)) | 3158 | if (!get_index(masterfd, idx_id, &idx, false)) |
3159 | return false; | 3159 | return false; |
3160 | 3160 | ||
3161 | idx.tag_seek[tag] = data; | 3161 | idx.tag_seek[tag] = data; |
3162 | idx.flag |= FLAG_DIRTYNUM; | 3162 | idx.flag |= FLAG_DIRTYNUM; |
3163 | 3163 | ||
3164 | return write_index(masterfd, idx_id, &idx); | 3164 | return write_index(masterfd, idx_id, &idx); |
3165 | } | 3165 | } |
3166 | 3166 | ||
3167 | #if 0 | 3167 | #if 0 |
3168 | bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, | 3168 | bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, |
3169 | int tag, long data) | 3169 | int tag, long data) |
3170 | { | 3170 | { |
3171 | struct master_header myhdr; | 3171 | struct master_header myhdr; |
3172 | 3172 | ||
3173 | if (tcs->masterfd < 0) | 3173 | if (tcs->masterfd < 0) |
3174 | { | 3174 | { |
3175 | if ( (tcs->masterfd = open_master_fd(&myhdr, true)) < 0) | 3175 | if ( (tcs->masterfd = open_master_fd(&myhdr, true)) < 0) |
3176 | return false; | 3176 | return false; |
3177 | } | 3177 | } |
3178 | 3178 | ||
3179 | return modify_numeric_entry(tcs->masterfd, tcs->idx_id, tag, data); | 3179 | return modify_numeric_entry(tcs->masterfd, tcs->idx_id, tag, data); |
3180 | } | 3180 | } |
3181 | #endif | 3181 | #endif |
@@ -3183,11 +3183,11 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, | |||
3183 | static bool command_queue_is_full(void) | 3183 | static bool command_queue_is_full(void) |
3184 | { | 3184 | { |
3185 | int next; | 3185 | int next; |
3186 | 3186 | ||
3187 | next = command_queue_widx + 1; | 3187 | next = command_queue_widx + 1; |
3188 | if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH) | 3188 | if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH) |
3189 | next = 0; | 3189 | next = 0; |
3190 | 3190 | ||
3191 | return (next == command_queue_ridx); | 3191 | return (next == command_queue_ridx); |
3192 | } | 3192 | } |
3193 | 3193 | ||
@@ -3195,27 +3195,27 @@ static void command_queue_sync_callback(void) | |||
3195 | { | 3195 | { |
3196 | struct master_header myhdr; | 3196 | struct master_header myhdr; |
3197 | int masterfd; | 3197 | int masterfd; |
3198 | 3198 | ||
3199 | mutex_lock(&command_queue_mutex); | 3199 | mutex_lock(&command_queue_mutex); |
3200 | 3200 | ||
3201 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) | 3201 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) |
3202 | return; | 3202 | return; |
3203 | 3203 | ||
3204 | while (command_queue_ridx != command_queue_widx) | 3204 | while (command_queue_ridx != command_queue_widx) |
3205 | { | 3205 | { |
3206 | struct tagcache_command_entry *ce = &command_queue[command_queue_ridx]; | 3206 | struct tagcache_command_entry *ce = &command_queue[command_queue_ridx]; |
3207 | 3207 | ||
3208 | switch (ce->command) | 3208 | switch (ce->command) |
3209 | { | 3209 | { |
3210 | case CMD_UPDATE_MASTER_HEADER: | 3210 | case CMD_UPDATE_MASTER_HEADER: |
3211 | { | 3211 | { |
3212 | close(masterfd); | 3212 | close(masterfd); |
3213 | update_master_header(); | 3213 | update_master_header(); |
3214 | 3214 | ||
3215 | /* Re-open the masterfd. */ | 3215 | /* Re-open the masterfd. */ |
3216 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) | 3216 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) |
3217 | return; | 3217 | return; |
3218 | 3218 | ||
3219 | break; | 3219 | break; |
3220 | } | 3220 | } |
3221 | case CMD_UPDATE_NUMERIC: | 3221 | case CMD_UPDATE_NUMERIC: |
@@ -3224,13 +3224,13 @@ static void command_queue_sync_callback(void) | |||
3224 | break; | 3224 | break; |
3225 | } | 3225 | } |
3226 | } | 3226 | } |
3227 | 3227 | ||
3228 | if (++command_queue_ridx >= TAGCACHE_COMMAND_QUEUE_LENGTH) | 3228 | if (++command_queue_ridx >= TAGCACHE_COMMAND_QUEUE_LENGTH) |
3229 | command_queue_ridx = 0; | 3229 | command_queue_ridx = 0; |
3230 | } | 3230 | } |
3231 | 3231 | ||
3232 | close(masterfd); | 3232 | close(masterfd); |
3233 | 3233 | ||
3234 | tc_stat.queue_length = 0; | 3234 | tc_stat.queue_length = 0; |
3235 | mutex_unlock(&command_queue_mutex); | 3235 | mutex_unlock(&command_queue_mutex); |
3236 | } | 3236 | } |
@@ -3239,7 +3239,7 @@ static void run_command_queue(bool force) | |||
3239 | { | 3239 | { |
3240 | if (COMMAND_QUEUE_IS_EMPTY) | 3240 | if (COMMAND_QUEUE_IS_EMPTY) |
3241 | return; | 3241 | return; |
3242 | 3242 | ||
3243 | if (force || command_queue_is_full()) | 3243 | if (force || command_queue_is_full()) |
3244 | command_queue_sync_callback(); | 3244 | command_queue_sync_callback(); |
3245 | else | 3245 | else |
@@ -3251,30 +3251,30 @@ static void queue_command(int cmd, long idx_id, int tag, long data) | |||
3251 | while (1) | 3251 | while (1) |
3252 | { | 3252 | { |
3253 | int next; | 3253 | int next; |
3254 | 3254 | ||
3255 | mutex_lock(&command_queue_mutex); | 3255 | mutex_lock(&command_queue_mutex); |
3256 | next = command_queue_widx + 1; | 3256 | next = command_queue_widx + 1; |
3257 | if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH) | 3257 | if (next >= TAGCACHE_COMMAND_QUEUE_LENGTH) |
3258 | next = 0; | 3258 | next = 0; |
3259 | 3259 | ||
3260 | /* Make sure queue is not full. */ | 3260 | /* Make sure queue is not full. */ |
3261 | if (next != command_queue_ridx) | 3261 | if (next != command_queue_ridx) |
3262 | { | 3262 | { |
3263 | struct tagcache_command_entry *ce = &command_queue[command_queue_widx]; | 3263 | struct tagcache_command_entry *ce = &command_queue[command_queue_widx]; |
3264 | 3264 | ||
3265 | ce->command = cmd; | 3265 | ce->command = cmd; |
3266 | ce->idx_id = idx_id; | 3266 | ce->idx_id = idx_id; |
3267 | ce->tag = tag; | 3267 | ce->tag = tag; |
3268 | ce->data = data; | 3268 | ce->data = data; |
3269 | 3269 | ||
3270 | command_queue_widx = next; | 3270 | command_queue_widx = next; |
3271 | 3271 | ||
3272 | tc_stat.queue_length++; | 3272 | tc_stat.queue_length++; |
3273 | 3273 | ||
3274 | mutex_unlock(&command_queue_mutex); | 3274 | mutex_unlock(&command_queue_mutex); |
3275 | break; | 3275 | break; |
3276 | } | 3276 | } |
3277 | 3277 | ||
3278 | /* Queue is full, try again later... */ | 3278 | /* Queue is full, try again later... */ |
3279 | mutex_unlock(&command_queue_mutex); | 3279 | mutex_unlock(&command_queue_mutex); |
3280 | sleep(1); | 3280 | sleep(1); |
@@ -3284,16 +3284,16 @@ static void queue_command(int cmd, long idx_id, int tag, long data) | |||
3284 | long tagcache_increase_serial(void) | 3284 | long tagcache_increase_serial(void) |
3285 | { | 3285 | { |
3286 | long old; | 3286 | long old; |
3287 | 3287 | ||
3288 | if (!tc_stat.ready) | 3288 | if (!tc_stat.ready) |
3289 | return -2; | 3289 | return -2; |
3290 | 3290 | ||
3291 | while (read_lock) | 3291 | while (read_lock) |
3292 | sleep(1); | 3292 | sleep(1); |
3293 | 3293 | ||
3294 | old = current_tcmh.serial++; | 3294 | old = current_tcmh.serial++; |
3295 | queue_command(CMD_UPDATE_MASTER_HEADER, 0, 0, 0); | 3295 | queue_command(CMD_UPDATE_MASTER_HEADER, 0, 0, 0); |
3296 | 3296 | ||
3297 | return old; | 3297 | return old; |
3298 | } | 3298 | } |
3299 | 3299 | ||
@@ -3307,50 +3307,50 @@ static bool write_tag(int fd, const char *tagstr, const char *datastr) | |||
3307 | { | 3307 | { |
3308 | char buf[512]; | 3308 | char buf[512]; |
3309 | int i; | 3309 | int i; |
3310 | 3310 | ||
3311 | snprintf(buf, sizeof buf, "%s=\"", tagstr); | 3311 | snprintf(buf, sizeof buf, "%s=\"", tagstr); |
3312 | for (i = strlen(buf); i < (long)sizeof(buf)-4; i++) | 3312 | for (i = strlen(buf); i < (long)sizeof(buf)-4; i++) |
3313 | { | 3313 | { |
3314 | if (*datastr == '\0') | 3314 | if (*datastr == '\0') |
3315 | break; | 3315 | break; |
3316 | 3316 | ||
3317 | if (*datastr == '"' || *datastr == '\\') | 3317 | if (*datastr == '"' || *datastr == '\\') |
3318 | buf[i++] = '\\'; | 3318 | buf[i++] = '\\'; |
3319 | 3319 | ||
3320 | else if (*datastr == '\n') | 3320 | else if (*datastr == '\n') |
3321 | { | 3321 | { |
3322 | buf[i++] = '\\'; | 3322 | buf[i++] = '\\'; |
3323 | buf[i] = 'n'; | 3323 | buf[i] = 'n'; |
3324 | continue; | 3324 | continue; |
3325 | } | 3325 | } |
3326 | 3326 | ||
3327 | buf[i] = *(datastr++); | 3327 | buf[i] = *(datastr++); |
3328 | } | 3328 | } |
3329 | 3329 | ||
3330 | strcpy(&buf[i], "\" "); | 3330 | strcpy(&buf[i], "\" "); |
3331 | 3331 | ||
3332 | write(fd, buf, i + 2); | 3332 | write(fd, buf, i + 2); |
3333 | 3333 | ||
3334 | return true; | 3334 | return true; |
3335 | } | 3335 | } |
3336 | 3336 | ||
3337 | #ifndef __PCTOOL__ | 3337 | #ifndef __PCTOOL__ |
3338 | 3338 | ||
3339 | static bool read_tag(char *dest, long size, | 3339 | static bool read_tag(char *dest, long size, |
3340 | const char *src, const char *tagstr) | 3340 | const char *src, const char *tagstr) |
3341 | { | 3341 | { |
3342 | int pos; | 3342 | int pos; |
3343 | char current_tag[32]; | 3343 | char current_tag[32]; |
3344 | 3344 | ||
3345 | while (*src != '\0') | 3345 | while (*src != '\0') |
3346 | { | 3346 | { |
3347 | /* Skip all whitespace */ | 3347 | /* Skip all whitespace */ |
3348 | while (*src == ' ') | 3348 | while (*src == ' ') |
3349 | src++; | 3349 | src++; |
3350 | 3350 | ||
3351 | if (*src == '\0') | 3351 | if (*src == '\0') |
3352 | break; | 3352 | break; |
3353 | 3353 | ||
3354 | pos = 0; | 3354 | pos = 0; |
3355 | /* Read in tag name */ | 3355 | /* Read in tag name */ |
3356 | while (*src != '=' && *src != ' ') | 3356 | while (*src != '=' && *src != ' ') |
@@ -3358,27 +3358,27 @@ static bool read_tag(char *dest, long size, | |||
3358 | current_tag[pos] = *src; | 3358 | current_tag[pos] = *src; |
3359 | src++; | 3359 | src++; |
3360 | pos++; | 3360 | pos++; |
3361 | 3361 | ||
3362 | if (*src == '\0' || pos >= (long)sizeof(current_tag)) | 3362 | if (*src == '\0' || pos >= (long)sizeof(current_tag)) |
3363 | return false; | 3363 | return false; |
3364 | } | 3364 | } |
3365 | current_tag[pos] = '\0'; | 3365 | current_tag[pos] = '\0'; |
3366 | 3366 | ||
3367 | /* Read in tag data */ | 3367 | /* Read in tag data */ |
3368 | 3368 | ||
3369 | /* Find the start. */ | 3369 | /* Find the start. */ |
3370 | while (*src != '"' && *src != '\0') | 3370 | while (*src != '"' && *src != '\0') |
3371 | src++; | 3371 | src++; |
3372 | 3372 | ||
3373 | if (*src == '\0' || *(++src) == '\0') | 3373 | if (*src == '\0' || *(++src) == '\0') |
3374 | return false; | 3374 | return false; |
3375 | 3375 | ||
3376 | /* Read the data. */ | 3376 | /* Read the data. */ |
3377 | for (pos = 0; pos < size; pos++) | 3377 | for (pos = 0; pos < size; pos++) |
3378 | { | 3378 | { |
3379 | if (*src == '\0') | 3379 | if (*src == '\0') |
3380 | break; | 3380 | break; |
3381 | 3381 | ||
3382 | if (*src == '\\') | 3382 | if (*src == '\\') |
3383 | { | 3383 | { |
3384 | src++; | 3384 | src++; |
@@ -3386,29 +3386,29 @@ static bool read_tag(char *dest, long size, | |||
3386 | dest[pos] = '\n'; | 3386 | dest[pos] = '\n'; |
3387 | else | 3387 | else |
3388 | dest[pos] = *src; | 3388 | dest[pos] = *src; |
3389 | 3389 | ||
3390 | src++; | 3390 | src++; |
3391 | continue; | 3391 | continue; |
3392 | } | 3392 | } |
3393 | 3393 | ||
3394 | if (*src == '\0') | 3394 | if (*src == '\0') |
3395 | break; | 3395 | break; |
3396 | 3396 | ||
3397 | if (*src == '"') | 3397 | if (*src == '"') |
3398 | { | 3398 | { |
3399 | src++; | 3399 | src++; |
3400 | break; | 3400 | break; |
3401 | } | 3401 | } |
3402 | 3402 | ||
3403 | dest[pos] = *(src++); | 3403 | dest[pos] = *(src++); |
3404 | } | 3404 | } |
3405 | 3405 | ||
3406 | dest[pos] = '\0'; | 3406 | dest[pos] = '\0'; |
3407 | 3407 | ||
3408 | if (!strcasecmp(tagstr, current_tag)) | 3408 | if (!strcasecmp(tagstr, current_tag)) |
3409 | return true; | 3409 | return true; |
3410 | } | 3410 | } |
3411 | 3411 | ||
3412 | return false; | 3412 | return false; |
3413 | } | 3413 | } |
3414 | 3414 | ||
@@ -3423,10 +3423,10 @@ static int parse_changelog_line(int line_n, char *buf, void *parameters) | |||
3423 | tag_lastoffset }; | 3423 | tag_lastoffset }; |
3424 | int i; | 3424 | int i; |
3425 | (void)line_n; | 3425 | (void)line_n; |
3426 | 3426 | ||
3427 | if (*buf == '#') | 3427 | if (*buf == '#') |
3428 | return 0; | 3428 | return 0; |
3429 | 3429 | ||
3430 | /* logf("%d/%s", line_n, buf); */ | 3430 | /* logf("%d/%s", line_n, buf); */ |
3431 | if (!read_tag(tag_data, sizeof tag_data, buf, "filename")) | 3431 | if (!read_tag(tag_data, sizeof tag_data, buf, "filename")) |
3432 | { | 3432 | { |
@@ -3434,49 +3434,49 @@ static int parse_changelog_line(int line_n, char *buf, void *parameters) | |||
3434 | logf("-> %s", buf); | 3434 | logf("-> %s", buf); |
3435 | return 0; | 3435 | return 0; |
3436 | } | 3436 | } |
3437 | 3437 | ||
3438 | idx_id = find_index(tag_data); | 3438 | idx_id = find_index(tag_data); |
3439 | if (idx_id < 0) | 3439 | if (idx_id < 0) |
3440 | { | 3440 | { |
3441 | logf("%d/entry not found", line_n); | 3441 | logf("%d/entry not found", line_n); |
3442 | return 0; | 3442 | return 0; |
3443 | } | 3443 | } |
3444 | 3444 | ||
3445 | if (!get_index(masterfd, idx_id, &idx, false)) | 3445 | if (!get_index(masterfd, idx_id, &idx, false)) |
3446 | { | 3446 | { |
3447 | logf("%d/failed to retrieve index entry", line_n); | 3447 | logf("%d/failed to retrieve index entry", line_n); |
3448 | return 0; | 3448 | return 0; |
3449 | } | 3449 | } |
3450 | 3450 | ||
3451 | /* Stop if tag has already been modified. */ | 3451 | /* Stop if tag has already been modified. */ |
3452 | if (idx.flag & FLAG_DIRTYNUM) | 3452 | if (idx.flag & FLAG_DIRTYNUM) |
3453 | return 0; | 3453 | return 0; |
3454 | 3454 | ||
3455 | logf("%d/import: %s", line_n, tag_data); | 3455 | logf("%d/import: %s", line_n, tag_data); |
3456 | 3456 | ||
3457 | idx.flag |= FLAG_DIRTYNUM; | 3457 | idx.flag |= FLAG_DIRTYNUM; |
3458 | for (i = 0; i < (long)(sizeof(import_tags)/sizeof(import_tags[0])); i++) | 3458 | for (i = 0; i < (long)(sizeof(import_tags)/sizeof(import_tags[0])); i++) |
3459 | { | 3459 | { |
3460 | int data; | 3460 | int data; |
3461 | 3461 | ||
3462 | if (!read_tag(tag_data, sizeof tag_data, buf, | 3462 | if (!read_tag(tag_data, sizeof tag_data, buf, |
3463 | tagcache_tag_to_str(import_tags[i]))) | 3463 | tagcache_tag_to_str(import_tags[i]))) |
3464 | { | 3464 | { |
3465 | continue; | 3465 | continue; |
3466 | } | 3466 | } |
3467 | 3467 | ||
3468 | data = atoi(tag_data); | 3468 | data = atoi(tag_data); |
3469 | if (data < 0) | 3469 | if (data < 0) |
3470 | continue; | 3470 | continue; |
3471 | 3471 | ||
3472 | idx.tag_seek[import_tags[i]] = data; | 3472 | idx.tag_seek[import_tags[i]] = data; |
3473 | 3473 | ||
3474 | if (import_tags[i] == tag_lastplayed && data >= current_tcmh.serial) | 3474 | if (import_tags[i] == tag_lastplayed && data >= current_tcmh.serial) |
3475 | current_tcmh.serial = data + 1; | 3475 | current_tcmh.serial = data + 1; |
3476 | else if (import_tags[i] == tag_commitid && data >= current_tcmh.commitid) | 3476 | else if (import_tags[i] == tag_commitid && data >= current_tcmh.commitid) |
3477 | current_tcmh.commitid = data + 1; | 3477 | current_tcmh.commitid = data + 1; |
3478 | } | 3478 | } |
3479 | 3479 | ||
3480 | return write_index(masterfd, idx_id, &idx) ? 0 : -5; | 3480 | return write_index(masterfd, idx_id, &idx) ? 0 : -5; |
3481 | } | 3481 | } |
3482 | 3482 | ||
@@ -3487,46 +3487,46 @@ bool tagcache_import_changelog(void) | |||
3487 | int clfd; | 3487 | int clfd; |
3488 | long masterfd; | 3488 | long masterfd; |
3489 | char buf[2048]; | 3489 | char buf[2048]; |
3490 | 3490 | ||
3491 | if (!tc_stat.ready) | 3491 | if (!tc_stat.ready) |
3492 | return false; | 3492 | return false; |
3493 | 3493 | ||
3494 | while (read_lock) | 3494 | while (read_lock) |
3495 | sleep(1); | 3495 | sleep(1); |
3496 | 3496 | ||
3497 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); | 3497 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); |
3498 | if (clfd < 0) | 3498 | if (clfd < 0) |
3499 | { | 3499 | { |
3500 | logf("failure to open changelog"); | 3500 | logf("failure to open changelog"); |
3501 | return false; | 3501 | return false; |
3502 | } | 3502 | } |
3503 | 3503 | ||
3504 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) | 3504 | if ( (masterfd = open_master_fd(&myhdr, true)) < 0) |
3505 | { | 3505 | { |
3506 | close(clfd); | 3506 | close(clfd); |
3507 | return false; | 3507 | return false; |
3508 | } | 3508 | } |
3509 | 3509 | ||
3510 | write_lock++; | 3510 | write_lock++; |
3511 | 3511 | ||
3512 | filenametag_fd = open_tag_fd(&tch, tag_filename, false); | 3512 | filenametag_fd = open_tag_fd(&tch, tag_filename, false); |
3513 | 3513 | ||
3514 | fast_readline(clfd, buf, sizeof buf, (void *)(intptr_t)masterfd, | 3514 | fast_readline(clfd, buf, sizeof buf, (void *)(intptr_t)masterfd, |
3515 | parse_changelog_line); | 3515 | parse_changelog_line); |
3516 | 3516 | ||
3517 | close(clfd); | 3517 | close(clfd); |
3518 | close(masterfd); | 3518 | close(masterfd); |
3519 | 3519 | ||
3520 | if (filenametag_fd >= 0) | 3520 | if (filenametag_fd >= 0) |
3521 | { | 3521 | { |
3522 | close(filenametag_fd); | 3522 | close(filenametag_fd); |
3523 | filenametag_fd = -1; | 3523 | filenametag_fd = -1; |
3524 | } | 3524 | } |
3525 | 3525 | ||
3526 | write_lock--; | 3526 | write_lock--; |
3527 | 3527 | ||
3528 | update_master_header(); | 3528 | update_master_header(); |
3529 | 3529 | ||
3530 | return true; | 3530 | return true; |
3531 | } | 3531 | } |
3532 | 3532 | ||
@@ -3540,13 +3540,13 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
3540 | char temp[32]; | 3540 | char temp[32]; |
3541 | int clfd; | 3541 | int clfd; |
3542 | int i, j; | 3542 | int i, j; |
3543 | 3543 | ||
3544 | if (!tc_stat.ready) | 3544 | if (!tc_stat.ready) |
3545 | return false; | 3545 | return false; |
3546 | 3546 | ||
3547 | if (!tagcache_search(tcs, tag_filename)) | 3547 | if (!tagcache_search(tcs, tag_filename)) |
3548 | return false; | 3548 | return false; |
3549 | 3549 | ||
3550 | /* Initialize the changelog */ | 3550 | /* Initialize the changelog */ |
3551 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC, 0666); | 3551 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
3552 | if (clfd < 0) | 3552 | if (clfd < 0) |
@@ -3554,7 +3554,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
3554 | logf("failure to open changelog"); | 3554 | logf("failure to open changelog"); |
3555 | return false; | 3555 | return false; |
3556 | } | 3556 | } |
3557 | 3557 | ||
3558 | if (tcs->masterfd < 0) | 3558 | if (tcs->masterfd < 0) |
3559 | { | 3559 | { |
3560 | if ( (tcs->masterfd = open_master_fd(&myhdr, false)) < 0) | 3560 | if ( (tcs->masterfd = open_master_fd(&myhdr, false)) < 0) |
@@ -3568,9 +3568,9 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
3568 | lseek(tcs->masterfd, 0, SEEK_SET); | 3568 | lseek(tcs->masterfd, 0, SEEK_SET); |
3569 | ecread(tcs->masterfd, &myhdr, 1, master_header_ec, tc_stat.econ); | 3569 | ecread(tcs->masterfd, &myhdr, 1, master_header_ec, tc_stat.econ); |
3570 | } | 3570 | } |
3571 | 3571 | ||
3572 | write(clfd, "## Changelog version 1\n", 23); | 3572 | write(clfd, "## Changelog version 1\n", 23); |
3573 | 3573 | ||
3574 | for (i = 0; i < myhdr.tch.entry_count; i++) | 3574 | for (i = 0; i < myhdr.tch.entry_count; i++) |
3575 | { | 3575 | { |
3576 | if (ecread_index_entry(tcs->masterfd, &idx) != sizeof(struct index_entry)) | 3576 | if (ecread_index_entry(tcs->masterfd, &idx) != sizeof(struct index_entry)) |
@@ -3580,15 +3580,15 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
3580 | close(clfd); | 3580 | close(clfd); |
3581 | return false; | 3581 | return false; |
3582 | } | 3582 | } |
3583 | 3583 | ||
3584 | /* Skip until the entry found has been modified. */ | 3584 | /* Skip until the entry found has been modified. */ |
3585 | if (! (idx.flag & FLAG_DIRTYNUM) ) | 3585 | if (! (idx.flag & FLAG_DIRTYNUM) ) |
3586 | continue; | 3586 | continue; |
3587 | 3587 | ||
3588 | /* Skip deleted entries too. */ | 3588 | /* Skip deleted entries too. */ |
3589 | if (idx.flag & FLAG_DELETED) | 3589 | if (idx.flag & FLAG_DELETED) |
3590 | continue; | 3590 | continue; |
3591 | 3591 | ||
3592 | /* Now retrieve all tags. */ | 3592 | /* Now retrieve all tags. */ |
3593 | for (j = 0; j < TAG_COUNT; j++) | 3593 | for (j = 0; j < TAG_COUNT; j++) |
3594 | { | 3594 | { |
@@ -3598,20 +3598,20 @@ bool tagcache_create_changelog(struct tagcache_search *tcs) | |||
3598 | write_tag(clfd, tagcache_tag_to_str(j), temp); | 3598 | write_tag(clfd, tagcache_tag_to_str(j), temp); |
3599 | continue; | 3599 | continue; |
3600 | } | 3600 | } |
3601 | 3601 | ||
3602 | tcs->type = j; | 3602 | tcs->type = j; |
3603 | tagcache_retrieve(tcs, i, tcs->type, buf, sizeof buf); | 3603 | tagcache_retrieve(tcs, i, tcs->type, buf, sizeof buf); |
3604 | write_tag(clfd, tagcache_tag_to_str(j), buf); | 3604 | write_tag(clfd, tagcache_tag_to_str(j), buf); |
3605 | } | 3605 | } |
3606 | 3606 | ||
3607 | write(clfd, "\n", 1); | 3607 | write(clfd, "\n", 1); |
3608 | do_timed_yield(); | 3608 | do_timed_yield(); |
3609 | } | 3609 | } |
3610 | 3610 | ||
3611 | close(clfd); | 3611 | close(clfd); |
3612 | 3612 | ||
3613 | tagcache_search_finish(tcs); | 3613 | tagcache_search_finish(tcs); |
3614 | 3614 | ||
3615 | return true; | 3615 | return true; |
3616 | } | 3616 | } |
3617 | 3617 | ||
@@ -3624,31 +3624,31 @@ static bool delete_entry(long idx_id) | |||
3624 | struct master_header myhdr; | 3624 | struct master_header myhdr; |
3625 | char buf[TAG_MAXLEN+32]; | 3625 | char buf[TAG_MAXLEN+32]; |
3626 | int in_use[TAG_COUNT]; | 3626 | int in_use[TAG_COUNT]; |
3627 | 3627 | ||
3628 | logf("delete_entry(): %ld", idx_id); | 3628 | logf("delete_entry(): %ld", idx_id); |
3629 | 3629 | ||
3630 | #ifdef HAVE_TC_RAMCACHE | 3630 | #ifdef HAVE_TC_RAMCACHE |
3631 | /* At first mark the entry removed from ram cache. */ | 3631 | /* At first mark the entry removed from ram cache. */ |
3632 | if (tc_stat.ramcache) | 3632 | if (tc_stat.ramcache) |
3633 | tcramcache.hdr->indices[idx_id].flag |= FLAG_DELETED; | 3633 | tcramcache.hdr->indices[idx_id].flag |= FLAG_DELETED; |
3634 | #endif | 3634 | #endif |
3635 | 3635 | ||
3636 | if ( (masterfd = open_master_fd(&myhdr, true) ) < 0) | 3636 | if ( (masterfd = open_master_fd(&myhdr, true) ) < 0) |
3637 | return false; | 3637 | return false; |
3638 | 3638 | ||
3639 | lseek(masterfd, idx_id * sizeof(struct index_entry), SEEK_CUR); | 3639 | lseek(masterfd, idx_id * sizeof(struct index_entry), SEEK_CUR); |
3640 | if (ecread_index_entry(masterfd, &myidx) != sizeof(struct index_entry)) | 3640 | if (ecread_index_entry(masterfd, &myidx) != sizeof(struct index_entry)) |
3641 | { | 3641 | { |
3642 | logf("delete_entry(): read error"); | 3642 | logf("delete_entry(): read error"); |
3643 | goto cleanup; | 3643 | goto cleanup; |
3644 | } | 3644 | } |
3645 | 3645 | ||
3646 | if (myidx.flag & FLAG_DELETED) | 3646 | if (myidx.flag & FLAG_DELETED) |
3647 | { | 3647 | { |
3648 | logf("delete_entry(): already deleted!"); | 3648 | logf("delete_entry(): already deleted!"); |
3649 | goto cleanup; | 3649 | goto cleanup; |
3650 | } | 3650 | } |
3651 | 3651 | ||
3652 | myidx.flag |= FLAG_DELETED; | 3652 | myidx.flag |= FLAG_DELETED; |
3653 | lseek(masterfd, -(off_t)sizeof(struct index_entry), SEEK_CUR); | 3653 | lseek(masterfd, -(off_t)sizeof(struct index_entry), SEEK_CUR); |
3654 | if (ecwrite_index_entry(masterfd, &myidx) != sizeof(struct index_entry)) | 3654 | if (ecwrite_index_entry(masterfd, &myidx) != sizeof(struct index_entry)) |
@@ -3660,12 +3660,12 @@ static bool delete_entry(long idx_id) | |||
3660 | /* Now check which tags are no longer in use (if any) */ | 3660 | /* Now check which tags are no longer in use (if any) */ |
3661 | for (tag = 0; tag < TAG_COUNT; tag++) | 3661 | for (tag = 0; tag < TAG_COUNT; tag++) |
3662 | in_use[tag] = 0; | 3662 | in_use[tag] = 0; |
3663 | 3663 | ||
3664 | lseek(masterfd, sizeof(struct master_header), SEEK_SET); | 3664 | lseek(masterfd, sizeof(struct master_header), SEEK_SET); |
3665 | for (i = 0; i < myhdr.tch.entry_count; i++) | 3665 | for (i = 0; i < myhdr.tch.entry_count; i++) |
3666 | { | 3666 | { |
3667 | struct index_entry *idxp; | 3667 | struct index_entry *idxp; |
3668 | 3668 | ||
3669 | #ifdef HAVE_TC_RAMCACHE | 3669 | #ifdef HAVE_TC_RAMCACHE |
3670 | /* Use RAM DB if available for greater speed */ | 3670 | /* Use RAM DB if available for greater speed */ |
3671 | if (tc_stat.ramcache) | 3671 | if (tc_stat.ramcache) |
@@ -3680,30 +3680,30 @@ static bool delete_entry(long idx_id) | |||
3680 | } | 3680 | } |
3681 | idxp = &idx; | 3681 | idxp = &idx; |
3682 | } | 3682 | } |
3683 | 3683 | ||
3684 | if (idxp->flag & FLAG_DELETED) | 3684 | if (idxp->flag & FLAG_DELETED) |
3685 | continue; | 3685 | continue; |
3686 | 3686 | ||
3687 | for (tag = 0; tag < TAG_COUNT; tag++) | 3687 | for (tag = 0; tag < TAG_COUNT; tag++) |
3688 | { | 3688 | { |
3689 | if (TAGCACHE_IS_NUMERIC(tag)) | 3689 | if (TAGCACHE_IS_NUMERIC(tag)) |
3690 | continue; | 3690 | continue; |
3691 | 3691 | ||
3692 | if (idxp->tag_seek[tag] == myidx.tag_seek[tag]) | 3692 | if (idxp->tag_seek[tag] == myidx.tag_seek[tag]) |
3693 | in_use[tag]++; | 3693 | in_use[tag]++; |
3694 | } | 3694 | } |
3695 | } | 3695 | } |
3696 | 3696 | ||
3697 | /* Now delete all tags no longer in use. */ | 3697 | /* Now delete all tags no longer in use. */ |
3698 | for (tag = 0; tag < TAG_COUNT; tag++) | 3698 | for (tag = 0; tag < TAG_COUNT; tag++) |
3699 | { | 3699 | { |
3700 | struct tagcache_header tch; | 3700 | struct tagcache_header tch; |
3701 | int oldseek = myidx.tag_seek[tag]; | 3701 | int oldseek = myidx.tag_seek[tag]; |
3702 | 3702 | ||
3703 | if (TAGCACHE_IS_NUMERIC(tag)) | 3703 | if (TAGCACHE_IS_NUMERIC(tag)) |
3704 | continue; | 3704 | continue; |
3705 | 3705 | ||
3706 | /** | 3706 | /** |
3707 | * Replace tag seek with a hash value of the field string data. | 3707 | * Replace tag seek with a hash value of the field string data. |
3708 | * That way runtime statistics of moved or altered files can be | 3708 | * That way runtime statistics of moved or altered files can be |
3709 | * resurrected. | 3709 | * resurrected. |
@@ -3724,11 +3724,11 @@ static bool delete_entry(long idx_id) | |||
3724 | #endif /* HAVE_TC_RAMCACHE */ | 3724 | #endif /* HAVE_TC_RAMCACHE */ |
3725 | { | 3725 | { |
3726 | struct tagfile_entry tfe; | 3726 | struct tagfile_entry tfe; |
3727 | 3727 | ||
3728 | /* Open the index file, which contains the tag names. */ | 3728 | /* Open the index file, which contains the tag names. */ |
3729 | if ((fd = open_tag_fd(&tch, tag, true)) < 0) | 3729 | if ((fd = open_tag_fd(&tch, tag, true)) < 0) |
3730 | goto cleanup; | 3730 | goto cleanup; |
3731 | 3731 | ||
3732 | /* Skip the header block */ | 3732 | /* Skip the header block */ |
3733 | lseek(fd, myidx.tag_seek[tag], SEEK_SET); | 3733 | lseek(fd, myidx.tag_seek[tag], SEEK_SET); |
3734 | if (ecread_tagfile_entry(fd, &tfe) != sizeof(struct tagfile_entry)) | 3734 | if (ecread_tagfile_entry(fd, &tfe) != sizeof(struct tagfile_entry)) |
@@ -3736,16 +3736,16 @@ static bool delete_entry(long idx_id) | |||
3736 | logf("delete_entry(): read error #3"); | 3736 | logf("delete_entry(): read error #3"); |
3737 | goto cleanup; | 3737 | goto cleanup; |
3738 | } | 3738 | } |
3739 | 3739 | ||
3740 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) | 3740 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) |
3741 | { | 3741 | { |
3742 | logf("delete_entry(): read error #4"); | 3742 | logf("delete_entry(): read error #4"); |
3743 | goto cleanup; | 3743 | goto cleanup; |
3744 | } | 3744 | } |
3745 | 3745 | ||
3746 | myidx.tag_seek[tag] = crc_32(buf, strlen(buf), 0xffffffff); | 3746 | myidx.tag_seek[tag] = crc_32(buf, strlen(buf), 0xffffffff); |
3747 | } | 3747 | } |
3748 | 3748 | ||
3749 | if (in_use[tag]) | 3749 | if (in_use[tag]) |
3750 | { | 3750 | { |
3751 | logf("in use: %d/%d", tag, in_use[tag]); | 3751 | logf("in use: %d/%d", tag, in_use[tag]); |
@@ -3756,7 +3756,7 @@ static bool delete_entry(long idx_id) | |||
3756 | } | 3756 | } |
3757 | continue; | 3757 | continue; |
3758 | } | 3758 | } |
3759 | 3759 | ||
3760 | #ifdef HAVE_TC_RAMCACHE | 3760 | #ifdef HAVE_TC_RAMCACHE |
3761 | /* Delete from ram. */ | 3761 | /* Delete from ram. */ |
3762 | if (tc_stat.ramcache && tag != tag_filename) | 3762 | if (tc_stat.ramcache && tag != tag_filename) |
@@ -3766,32 +3766,32 @@ static bool delete_entry(long idx_id) | |||
3766 | tagentry->tag_data[0] = '\0'; | 3766 | tagentry->tag_data[0] = '\0'; |
3767 | } | 3767 | } |
3768 | #endif /* HAVE_TC_RAMCACHE */ | 3768 | #endif /* HAVE_TC_RAMCACHE */ |
3769 | 3769 | ||
3770 | /* Open the index file, which contains the tag names. */ | 3770 | /* Open the index file, which contains the tag names. */ |
3771 | if (fd < 0) | 3771 | if (fd < 0) |
3772 | { | 3772 | { |
3773 | if ((fd = open_tag_fd(&tch, tag, true)) < 0) | 3773 | if ((fd = open_tag_fd(&tch, tag, true)) < 0) |
3774 | goto cleanup; | 3774 | goto cleanup; |
3775 | } | 3775 | } |
3776 | 3776 | ||
3777 | /* Skip the header block */ | 3777 | /* Skip the header block */ |
3778 | lseek(fd, oldseek + sizeof(struct tagfile_entry), SEEK_SET); | 3778 | lseek(fd, oldseek + sizeof(struct tagfile_entry), SEEK_SET); |
3779 | 3779 | ||
3780 | /* Debug, print 10 first characters of the tag | 3780 | /* Debug, print 10 first characters of the tag |
3781 | read(fd, buf, 10); | 3781 | read(fd, buf, 10); |
3782 | buf[10]='\0'; | 3782 | buf[10]='\0'; |
3783 | logf("TAG:%s", buf); | 3783 | logf("TAG:%s", buf); |
3784 | lseek(fd, -10, SEEK_CUR); | 3784 | lseek(fd, -10, SEEK_CUR); |
3785 | */ | 3785 | */ |
3786 | 3786 | ||
3787 | /* Write first data byte in tag as \0 */ | 3787 | /* Write first data byte in tag as \0 */ |
3788 | write(fd, "", 1); | 3788 | write(fd, "", 1); |
3789 | 3789 | ||
3790 | /* Now tag data has been removed */ | 3790 | /* Now tag data has been removed */ |
3791 | close(fd); | 3791 | close(fd); |
3792 | fd = -1; | 3792 | fd = -1; |
3793 | } | 3793 | } |
3794 | 3794 | ||
3795 | /* Write index entry back into master index. */ | 3795 | /* Write index entry back into master index. */ |
3796 | lseek(masterfd, sizeof(struct master_header) + | 3796 | lseek(masterfd, sizeof(struct master_header) + |
3797 | (idx_id * sizeof(struct index_entry)), SEEK_SET); | 3797 | (idx_id * sizeof(struct index_entry)), SEEK_SET); |
@@ -3800,17 +3800,17 @@ static bool delete_entry(long idx_id) | |||
3800 | logf("delete_entry(): write_error #2"); | 3800 | logf("delete_entry(): write_error #2"); |
3801 | goto cleanup; | 3801 | goto cleanup; |
3802 | } | 3802 | } |
3803 | 3803 | ||
3804 | close(masterfd); | 3804 | close(masterfd); |
3805 | 3805 | ||
3806 | return true; | 3806 | return true; |
3807 | 3807 | ||
3808 | cleanup: | 3808 | cleanup: |
3809 | if (fd >= 0) | 3809 | if (fd >= 0) |
3810 | close(fd); | 3810 | close(fd); |
3811 | if (masterfd >= 0) | 3811 | if (masterfd >= 0) |
3812 | close(masterfd); | 3812 | close(masterfd); |
3813 | 3813 | ||
3814 | return false; | 3814 | return false; |
3815 | } | 3815 | } |
3816 | 3816 | ||
@@ -3822,10 +3822,10 @@ static bool check_event_queue(void) | |||
3822 | { | 3822 | { |
3823 | #ifndef __PCTOOL__ | 3823 | #ifndef __PCTOOL__ |
3824 | struct queue_event ev; | 3824 | struct queue_event ev; |
3825 | 3825 | ||
3826 | if(!queue_peek(&tagcache_queue, &ev)) | 3826 | if(!queue_peek(&tagcache_queue, &ev)) |
3827 | return false; | 3827 | return false; |
3828 | 3828 | ||
3829 | switch (ev.id) | 3829 | switch (ev.id) |
3830 | { | 3830 | { |
3831 | case Q_STOP_SCAN: | 3831 | case Q_STOP_SCAN: |
@@ -3834,7 +3834,7 @@ static bool check_event_queue(void) | |||
3834 | return true; | 3834 | return true; |
3835 | } | 3835 | } |
3836 | #endif /* __PCTOOL__ */ | 3836 | #endif /* __PCTOOL__ */ |
3837 | 3837 | ||
3838 | return false; | 3838 | return false; |
3839 | } | 3839 | } |
3840 | 3840 | ||
@@ -3874,12 +3874,12 @@ static bool allocate_tagcache(void) | |||
3874 | int fd = open_master_fd(&tcmh, false); | 3874 | int fd = open_master_fd(&tcmh, false); |
3875 | if (fd < 0) | 3875 | if (fd < 0) |
3876 | return false; | 3876 | return false; |
3877 | 3877 | ||
3878 | close(fd); | 3878 | close(fd); |
3879 | 3879 | ||
3880 | /** | 3880 | /** |
3881 | * Now calculate the required cache size plus | 3881 | * Now calculate the required cache size plus |
3882 | * some extra space for alignment fixes. | 3882 | * some extra space for alignment fixes. |
3883 | */ | 3883 | */ |
3884 | size_t alloc_size = tcmh.tch.datasize + 256 + TAGCACHE_RESERVE + | 3884 | size_t alloc_size = tcmh.tch.datasize + 256 + TAGCACHE_RESERVE + |
3885 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); | 3885 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); |
@@ -3910,14 +3910,14 @@ static bool tagcache_dumpload(void) | |||
3910 | 3910 | ||
3911 | tcramcache.handle = 0; | 3911 | tcramcache.handle = 0; |
3912 | tcramcache.hdr = NULL; | 3912 | tcramcache.hdr = NULL; |
3913 | 3913 | ||
3914 | fd = open(TAGCACHE_STATEFILE, O_RDONLY); | 3914 | fd = open(TAGCACHE_STATEFILE, O_RDONLY); |
3915 | if (fd < 0) | 3915 | if (fd < 0) |
3916 | { | 3916 | { |
3917 | logf("no tagcache statedump"); | 3917 | logf("no tagcache statedump"); |
3918 | return false; | 3918 | return false; |
3919 | } | 3919 | } |
3920 | 3920 | ||
3921 | /* Check the statefile memory placement */ | 3921 | /* Check the statefile memory placement */ |
3922 | rc = read(fd, &shdr, sizeof(struct statefile_header)); | 3922 | rc = read(fd, &shdr, sizeof(struct statefile_header)); |
3923 | if (rc != sizeof(struct statefile_header) | 3923 | if (rc != sizeof(struct statefile_header) |
@@ -3953,13 +3953,13 @@ static bool tagcache_dumpload(void) | |||
3953 | } | 3953 | } |
3954 | 3954 | ||
3955 | tc_stat = shdr.tc_stat; | 3955 | tc_stat = shdr.tc_stat; |
3956 | 3956 | ||
3957 | /* Now fix the pointers */ | 3957 | /* Now fix the pointers */ |
3958 | fix_ramcache(shdr.hdr, tcramcache.hdr); | 3958 | fix_ramcache(shdr.hdr, tcramcache.hdr); |
3959 | 3959 | ||
3960 | /* Load the tagcache master header (should match the actual DB file header). */ | 3960 | /* Load the tagcache master header (should match the actual DB file header). */ |
3961 | memcpy(¤t_tcmh, &shdr.mh, sizeof current_tcmh); | 3961 | memcpy(¤t_tcmh, &shdr.mh, sizeof current_tcmh); |
3962 | 3962 | ||
3963 | return true; | 3963 | return true; |
3964 | } | 3964 | } |
3965 | 3965 | ||
@@ -3967,30 +3967,30 @@ static bool tagcache_dumpsave(void) | |||
3967 | { | 3967 | { |
3968 | struct statefile_header shdr; | 3968 | struct statefile_header shdr; |
3969 | int fd; | 3969 | int fd; |
3970 | 3970 | ||
3971 | if (!tc_stat.ramcache) | 3971 | if (!tc_stat.ramcache) |
3972 | return false; | 3972 | return false; |
3973 | 3973 | ||
3974 | fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); | 3974 | fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
3975 | if (fd < 0) | 3975 | if (fd < 0) |
3976 | { | 3976 | { |
3977 | logf("failed to create a statedump"); | 3977 | logf("failed to create a statedump"); |
3978 | return false; | 3978 | return false; |
3979 | } | 3979 | } |
3980 | 3980 | ||
3981 | /* Create the header */ | 3981 | /* Create the header */ |
3982 | shdr.magic = TAGCACHE_STATEFILE_MAGIC; | 3982 | shdr.magic = TAGCACHE_STATEFILE_MAGIC; |
3983 | shdr.hdr = tcramcache.hdr; | 3983 | shdr.hdr = tcramcache.hdr; |
3984 | memcpy(&shdr.mh, ¤t_tcmh, sizeof current_tcmh); | 3984 | memcpy(&shdr.mh, ¤t_tcmh, sizeof current_tcmh); |
3985 | memcpy(&shdr.tc_stat, &tc_stat, sizeof tc_stat); | 3985 | memcpy(&shdr.tc_stat, &tc_stat, sizeof tc_stat); |
3986 | write(fd, &shdr, sizeof shdr); | 3986 | write(fd, &shdr, sizeof shdr); |
3987 | 3987 | ||
3988 | /* And dump the data too */ | 3988 | /* And dump the data too */ |
3989 | tcrc_buffer_lock(); | 3989 | tcrc_buffer_lock(); |
3990 | write(fd, tcramcache.hdr, tc_stat.ramcache_allocated); | 3990 | write(fd, tcramcache.hdr, tc_stat.ramcache_allocated); |
3991 | tcrc_buffer_unlock(); | 3991 | tcrc_buffer_unlock(); |
3992 | close(fd); | 3992 | close(fd); |
3993 | 3993 | ||
3994 | return true; | 3994 | return true; |
3995 | } | 3995 | } |
3996 | #endif /* HAVE_EEPROM_SETTINGS */ | 3996 | #endif /* HAVE_EEPROM_SETTINGS */ |
@@ -4014,7 +4014,7 @@ static bool load_tagcache(void) | |||
4014 | logf("loading tagcache to ram..."); | 4014 | logf("loading tagcache to ram..."); |
4015 | 4015 | ||
4016 | tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */ | 4016 | tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */ |
4017 | 4017 | ||
4018 | fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); | 4018 | fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); |
4019 | if (fd < 0) | 4019 | if (fd < 0) |
4020 | { | 4020 | { |
@@ -4100,7 +4100,7 @@ static bool load_tagcache(void) | |||
4100 | logf("Too big tagcache #10.75"); | 4100 | logf("Too big tagcache #10.75"); |
4101 | goto failure; | 4101 | goto failure; |
4102 | } | 4102 | } |
4103 | 4103 | ||
4104 | struct tagfile_entry *fe = (struct tagfile_entry *)p; | 4104 | struct tagfile_entry *fe = (struct tagfile_entry *)p; |
4105 | off_t pos = lseek(fd, 0, SEEK_CUR); | 4105 | off_t pos = lseek(fd, 0, SEEK_CUR); |
4106 | 4106 | ||
@@ -4234,7 +4234,7 @@ static bool load_tagcache(void) | |||
4234 | 4234 | ||
4235 | close(fd); | 4235 | close(fd); |
4236 | } | 4236 | } |
4237 | 4237 | ||
4238 | tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft; | 4238 | tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft; |
4239 | logf("tagcache loaded into ram!"); | 4239 | logf("tagcache loaded into ram!"); |
4240 | logf("utilization: %d%%", 100*tc_stat.ramcache_used / tc_stat.ramcache_allocated); | 4240 | logf("utilization: %d%%", 100*tc_stat.ramcache_used / tc_stat.ramcache_allocated); |
@@ -4255,11 +4255,11 @@ static bool check_deleted_files(void) | |||
4255 | int fd; | 4255 | int fd; |
4256 | char buf[TAG_MAXLEN+32]; | 4256 | char buf[TAG_MAXLEN+32]; |
4257 | struct tagfile_entry tfe; | 4257 | struct tagfile_entry tfe; |
4258 | 4258 | ||
4259 | logf("reverse scan..."); | 4259 | logf("reverse scan..."); |
4260 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename); | 4260 | snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename); |
4261 | fd = open(buf, O_RDONLY); | 4261 | fd = open(buf, O_RDONLY); |
4262 | 4262 | ||
4263 | if (fd < 0) | 4263 | if (fd < 0) |
4264 | { | 4264 | { |
4265 | logf("%s open fail", buf); | 4265 | logf("%s open fail", buf); |
@@ -4267,7 +4267,7 @@ static bool check_deleted_files(void) | |||
4267 | } | 4267 | } |
4268 | 4268 | ||
4269 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); | 4269 | lseek(fd, sizeof(struct tagcache_header), SEEK_SET); |
4270 | while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry) | 4270 | while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry) |
4271 | && !check_event_queue()) | 4271 | && !check_event_queue()) |
4272 | { | 4272 | { |
4273 | if (tfe.tag_length >= (long)sizeof(buf)-1) | 4273 | if (tfe.tag_length >= (long)sizeof(buf)-1) |
@@ -4276,18 +4276,18 @@ static bool check_deleted_files(void) | |||
4276 | close(fd); | 4276 | close(fd); |
4277 | return false; | 4277 | return false; |
4278 | } | 4278 | } |
4279 | 4279 | ||
4280 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) | 4280 | if (read(fd, buf, tfe.tag_length) != tfe.tag_length) |
4281 | { | 4281 | { |
4282 | logf("read error #14"); | 4282 | logf("read error #14"); |
4283 | close(fd); | 4283 | close(fd); |
4284 | return false; | 4284 | return false; |
4285 | } | 4285 | } |
4286 | 4286 | ||
4287 | /* Check if the file has already deleted from the db. */ | 4287 | /* Check if the file has already deleted from the db. */ |
4288 | if (*buf == '\0') | 4288 | if (*buf == '\0') |
4289 | continue; | 4289 | continue; |
4290 | 4290 | ||
4291 | /* Now check if the file exists. */ | 4291 | /* Now check if the file exists. */ |
4292 | if (!file_exists(buf)) | 4292 | if (!file_exists(buf)) |
4293 | { | 4293 | { |
@@ -4298,11 +4298,11 @@ static bool check_deleted_files(void) | |||
4298 | 4298 | ||
4299 | do_timed_yield(); | 4299 | do_timed_yield(); |
4300 | } | 4300 | } |
4301 | 4301 | ||
4302 | close(fd); | 4302 | close(fd); |
4303 | 4303 | ||
4304 | logf("done"); | 4304 | logf("done"); |
4305 | 4305 | ||
4306 | return true; | 4306 | return true; |
4307 | } | 4307 | } |
4308 | 4308 | ||
@@ -4354,7 +4354,7 @@ static bool search_root_exists(const char *path) | |||
4354 | * search root. | 4354 | * search root. |
4355 | * | 4355 | * |
4356 | * Returns true if it added the path to the search roots | 4356 | * Returns true if it added the path to the search roots |
4357 | * | 4357 | * |
4358 | * Windows 2000 and greater supports symlinks, but they don't provide | 4358 | * Windows 2000 and greater supports symlinks, but they don't provide |
4359 | * realpath() or readlink(), and symlinks are rarely used on them so | 4359 | * realpath() or readlink(), and symlinks are rarely used on them so |
4360 | * ignore this for windows for now | 4360 | * ignore this for windows for now |
@@ -4490,20 +4490,20 @@ static bool check_dir(const char *dirname, int add_files) | |||
4490 | else if (add_files) | 4490 | else if (add_files) |
4491 | { | 4491 | { |
4492 | tc_stat.curentry = curpath; | 4492 | tc_stat.curentry = curpath; |
4493 | 4493 | ||
4494 | /* Add a new entry to the temporary db file. */ | 4494 | /* Add a new entry to the temporary db file. */ |
4495 | add_tagcache(curpath, info.mtime); | 4495 | add_tagcache(curpath, info.mtime); |
4496 | 4496 | ||
4497 | /* Wait until current path for debug screen is read and unset. */ | 4497 | /* Wait until current path for debug screen is read and unset. */ |
4498 | while (tc_stat.syncscreen && tc_stat.curentry != NULL) | 4498 | while (tc_stat.syncscreen && tc_stat.curentry != NULL) |
4499 | yield(); | 4499 | yield(); |
4500 | 4500 | ||
4501 | tc_stat.curentry = NULL; | 4501 | tc_stat.curentry = NULL; |
4502 | } | 4502 | } |
4503 | 4503 | ||
4504 | curpath[len] = '\0'; | 4504 | curpath[len] = '\0'; |
4505 | } | 4505 | } |
4506 | 4506 | ||
4507 | closedir(dir); | 4507 | closedir(dir); |
4508 | 4508 | ||
4509 | return success; | 4509 | return success; |
@@ -4532,13 +4532,13 @@ void do_tagcache_build(const char *path[]) | |||
4532 | data_size = 0; | 4532 | data_size = 0; |
4533 | total_entry_count = 0; | 4533 | total_entry_count = 0; |
4534 | processed_dir_count = 0; | 4534 | processed_dir_count = 0; |
4535 | 4535 | ||
4536 | #ifdef HAVE_DIRCACHE | 4536 | #ifdef HAVE_DIRCACHE |
4537 | dircache_wait(); | 4537 | dircache_wait(); |
4538 | #endif | 4538 | #endif |
4539 | 4539 | ||
4540 | logf("updating tagcache"); | 4540 | logf("updating tagcache"); |
4541 | 4541 | ||
4542 | cachefd = open(TAGCACHE_FILE_TEMP, O_RDONLY); | 4542 | cachefd = open(TAGCACHE_FILE_TEMP, O_RDONLY); |
4543 | if (cachefd >= 0) | 4543 | if (cachefd >= 0) |
4544 | { | 4544 | { |
@@ -4546,7 +4546,7 @@ void do_tagcache_build(const char *path[]) | |||
4546 | close(cachefd); | 4546 | close(cachefd); |
4547 | return ; | 4547 | return ; |
4548 | } | 4548 | } |
4549 | 4549 | ||
4550 | cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC, 0666); | 4550 | cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC, 0666); |
4551 | if (cachefd < 0) | 4551 | if (cachefd < 0) |
4552 | { | 4552 | { |
@@ -4555,7 +4555,7 @@ void do_tagcache_build(const char *path[]) | |||
4555 | } | 4555 | } |
4556 | 4556 | ||
4557 | filenametag_fd = open_tag_fd(&header, tag_filename, false); | 4557 | filenametag_fd = open_tag_fd(&header, tag_filename, false); |
4558 | 4558 | ||
4559 | cpu_boost(true); | 4559 | cpu_boost(true); |
4560 | 4560 | ||
4561 | logf("Scanning files..."); | 4561 | logf("Scanning files..."); |
@@ -4620,7 +4620,7 @@ void do_tagcache_build(const char *path[]) | |||
4620 | #ifdef __PCTOOL__ | 4620 | #ifdef __PCTOOL__ |
4621 | free_tempbuf(); | 4621 | free_tempbuf(); |
4622 | #endif | 4622 | #endif |
4623 | 4623 | ||
4624 | #ifdef HAVE_TC_RAMCACHE | 4624 | #ifdef HAVE_TC_RAMCACHE |
4625 | if (tcramcache.hdr) | 4625 | if (tcramcache.hdr) |
4626 | { | 4626 | { |
@@ -4629,7 +4629,7 @@ void do_tagcache_build(const char *path[]) | |||
4629 | queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0); | 4629 | queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0); |
4630 | } | 4630 | } |
4631 | #endif | 4631 | #endif |
4632 | 4632 | ||
4633 | cpu_boost(false); | 4633 | cpu_boost(false); |
4634 | } | 4634 | } |
4635 | 4635 | ||
@@ -4652,9 +4652,9 @@ static void load_ramcache(void) | |||
4652 | { | 4652 | { |
4653 | if (!tcramcache.hdr) | 4653 | if (!tcramcache.hdr) |
4654 | return ; | 4654 | return ; |
4655 | 4655 | ||
4656 | cpu_boost(true); | 4656 | cpu_boost(true); |
4657 | 4657 | ||
4658 | /* At first we should load the cache (if exists). */ | 4658 | /* At first we should load the cache (if exists). */ |
4659 | tc_stat.ramcache = load_tagcache(); | 4659 | tc_stat.ramcache = load_tagcache(); |
4660 | 4660 | ||
@@ -4668,7 +4668,7 @@ static void load_ramcache(void) | |||
4668 | tcramcache.handle = 0; | 4668 | tcramcache.handle = 0; |
4669 | core_free(handle); | 4669 | core_free(handle); |
4670 | } | 4670 | } |
4671 | 4671 | ||
4672 | cpu_boost(false); | 4672 | cpu_boost(false); |
4673 | } | 4673 | } |
4674 | 4674 | ||
@@ -4692,7 +4692,7 @@ static void tagcache_thread(void) | |||
4692 | allocate_tempbuf(); | 4692 | allocate_tempbuf(); |
4693 | commit(); | 4693 | commit(); |
4694 | free_tempbuf(); | 4694 | free_tempbuf(); |
4695 | 4695 | ||
4696 | #ifdef HAVE_TC_RAMCACHE | 4696 | #ifdef HAVE_TC_RAMCACHE |
4697 | #ifdef HAVE_EEPROM_SETTINGS | 4697 | #ifdef HAVE_EEPROM_SETTINGS |
4698 | if (firmware_settings.initialized && firmware_settings.disk_clean | 4698 | if (firmware_settings.initialized && firmware_settings.disk_clean |
@@ -4703,15 +4703,15 @@ static void tagcache_thread(void) | |||
4703 | 4703 | ||
4704 | remove(TAGCACHE_STATEFILE); | 4704 | remove(TAGCACHE_STATEFILE); |
4705 | #endif /* HAVE_EEPROM_SETTINGS */ | 4705 | #endif /* HAVE_EEPROM_SETTINGS */ |
4706 | 4706 | ||
4707 | /* Allocate space for the tagcache if found on disk. */ | 4707 | /* Allocate space for the tagcache if found on disk. */ |
4708 | if (global_settings.tagcache_ram && !tc_stat.ramcache) | 4708 | if (global_settings.tagcache_ram && !tc_stat.ramcache) |
4709 | allocate_tagcache(); | 4709 | allocate_tagcache(); |
4710 | #endif /* HAVE_TC_RAMCACHE */ | 4710 | #endif /* HAVE_TC_RAMCACHE */ |
4711 | 4711 | ||
4712 | cpu_boost(false); | 4712 | cpu_boost(false); |
4713 | tc_stat.initialized = true; | 4713 | tc_stat.initialized = true; |
4714 | 4714 | ||
4715 | /* Don't delay bootup with the header check but do it on background. */ | 4715 | /* Don't delay bootup with the header check but do it on background. */ |
4716 | if (!tc_stat.ready) | 4716 | if (!tc_stat.ready) |
4717 | { | 4717 | { |
@@ -4719,11 +4719,11 @@ static void tagcache_thread(void) | |||
4719 | tc_stat.ready = check_all_headers(); | 4719 | tc_stat.ready = check_all_headers(); |
4720 | tc_stat.readyvalid = true; | 4720 | tc_stat.readyvalid = true; |
4721 | } | 4721 | } |
4722 | 4722 | ||
4723 | while (1) | 4723 | while (1) |
4724 | { | 4724 | { |
4725 | run_command_queue(false); | 4725 | run_command_queue(false); |
4726 | 4726 | ||
4727 | queue_wait_w_tmo(&tagcache_queue, &ev, HZ); | 4727 | queue_wait_w_tmo(&tagcache_queue, &ev, HZ); |
4728 | 4728 | ||
4729 | switch (ev.id) | 4729 | switch (ev.id) |
@@ -4731,13 +4731,13 @@ static void tagcache_thread(void) | |||
4731 | case Q_IMPORT_CHANGELOG: | 4731 | case Q_IMPORT_CHANGELOG: |
4732 | tagcache_import_changelog(); | 4732 | tagcache_import_changelog(); |
4733 | break; | 4733 | break; |
4734 | 4734 | ||
4735 | case Q_REBUILD: | 4735 | case Q_REBUILD: |
4736 | remove_files(); | 4736 | remove_files(); |
4737 | remove(TAGCACHE_FILE_TEMP); | 4737 | remove(TAGCACHE_FILE_TEMP); |
4738 | tagcache_build(); | 4738 | tagcache_build(); |
4739 | break; | 4739 | break; |
4740 | 4740 | ||
4741 | case Q_UPDATE: | 4741 | case Q_UPDATE: |
4742 | tagcache_build(); | 4742 | tagcache_build(); |
4743 | #ifdef HAVE_TC_RAMCACHE | 4743 | #ifdef HAVE_TC_RAMCACHE |
@@ -4745,13 +4745,13 @@ static void tagcache_thread(void) | |||
4745 | #endif | 4745 | #endif |
4746 | check_deleted_files(); | 4746 | check_deleted_files(); |
4747 | break ; | 4747 | break ; |
4748 | 4748 | ||
4749 | case Q_START_SCAN: | 4749 | case Q_START_SCAN: |
4750 | check_done = false; | 4750 | check_done = false; |
4751 | case SYS_TIMEOUT: | 4751 | case SYS_TIMEOUT: |
4752 | if (check_done || !tc_stat.ready) | 4752 | if (check_done || !tc_stat.ready) |
4753 | break ; | 4753 | break ; |
4754 | 4754 | ||
4755 | #ifdef HAVE_TC_RAMCACHE | 4755 | #ifdef HAVE_TC_RAMCACHE |
4756 | if (!tc_stat.ramcache && global_settings.tagcache_ram) | 4756 | if (!tc_stat.ramcache && global_settings.tagcache_ram) |
4757 | { | 4757 | { |
@@ -4764,24 +4764,24 @@ static void tagcache_thread(void) | |||
4764 | if (global_settings.tagcache_autoupdate) | 4764 | if (global_settings.tagcache_autoupdate) |
4765 | { | 4765 | { |
4766 | tagcache_build(); | 4766 | tagcache_build(); |
4767 | 4767 | ||
4768 | /* This will be very slow unless dircache is enabled | 4768 | /* This will be very slow unless dircache is enabled |
4769 | or target is flash based, but do it anyway for | 4769 | or target is flash based, but do it anyway for |
4770 | consistency. */ | 4770 | consistency. */ |
4771 | check_deleted_files(); | 4771 | check_deleted_files(); |
4772 | } | 4772 | } |
4773 | 4773 | ||
4774 | logf("tagcache check done"); | 4774 | logf("tagcache check done"); |
4775 | 4775 | ||
4776 | check_done = true; | 4776 | check_done = true; |
4777 | break ; | 4777 | break ; |
4778 | 4778 | ||
4779 | case Q_STOP_SCAN: | 4779 | case Q_STOP_SCAN: |
4780 | break ; | 4780 | break ; |
4781 | 4781 | ||
4782 | case SYS_POWEROFF: | 4782 | case SYS_POWEROFF: |
4783 | break ; | 4783 | break ; |
4784 | 4784 | ||
4785 | case SYS_USB_CONNECTED: | 4785 | case SYS_USB_CONNECTED: |
4786 | logf("USB: TagCache"); | 4786 | logf("USB: TagCache"); |
4787 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 4787 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
@@ -4795,11 +4795,11 @@ bool tagcache_prepare_shutdown(void) | |||
4795 | { | 4795 | { |
4796 | if (tagcache_get_commit_step() > 0) | 4796 | if (tagcache_get_commit_step() > 0) |
4797 | return false; | 4797 | return false; |
4798 | 4798 | ||
4799 | tagcache_stop_scan(); | 4799 | tagcache_stop_scan(); |
4800 | while (read_lock || write_lock) | 4800 | while (read_lock || write_lock) |
4801 | sleep(1); | 4801 | sleep(1); |
4802 | 4802 | ||
4803 | return true; | 4803 | return true; |
4804 | } | 4804 | } |
4805 | 4805 | ||
@@ -4807,7 +4807,7 @@ void tagcache_shutdown(void) | |||
4807 | { | 4807 | { |
4808 | /* Flush the command queue. */ | 4808 | /* Flush the command queue. */ |
4809 | run_command_queue(true); | 4809 | run_command_queue(true); |
4810 | 4810 | ||
4811 | #if defined(HAVE_EEPROM_SETTINGS) && defined(HAVE_TC_RAMCACHE) | 4811 | #if defined(HAVE_EEPROM_SETTINGS) && defined(HAVE_TC_RAMCACHE) |
4812 | if (tc_stat.ramcache) | 4812 | if (tc_stat.ramcache) |
4813 | tagcache_dumpsave(); | 4813 | tagcache_dumpsave(); |
@@ -4848,7 +4848,7 @@ struct tagcache_stat* tagcache_get_stat(void) | |||
4848 | { | 4848 | { |
4849 | tc_stat.progress = get_progress(); | 4849 | tc_stat.progress = get_progress(); |
4850 | tc_stat.processed_entries = processed_dir_count; | 4850 | tc_stat.processed_entries = processed_dir_count; |
4851 | 4851 | ||
4852 | return &tc_stat; | 4852 | return &tc_stat; |
4853 | } | 4853 | } |
4854 | 4854 | ||
@@ -4861,7 +4861,7 @@ bool tagcache_update(void) | |||
4861 | { | 4861 | { |
4862 | if (!tc_stat.ready) | 4862 | if (!tc_stat.ready) |
4863 | return false; | 4863 | return false; |
4864 | 4864 | ||
4865 | queue_post(&tagcache_queue, Q_UPDATE, 0); | 4865 | queue_post(&tagcache_queue, Q_UPDATE, 0); |
4866 | return false; | 4866 | return false; |
4867 | } | 4867 | } |
@@ -4886,12 +4886,12 @@ void tagcache_init(void) | |||
4886 | memset(¤t_tcmh, 0, sizeof(struct master_header)); | 4886 | memset(¤t_tcmh, 0, sizeof(struct master_header)); |
4887 | filenametag_fd = -1; | 4887 | filenametag_fd = -1; |
4888 | write_lock = read_lock = 0; | 4888 | write_lock = read_lock = 0; |
4889 | 4889 | ||
4890 | #ifndef __PCTOOL__ | 4890 | #ifndef __PCTOOL__ |
4891 | mutex_init(&command_queue_mutex); | 4891 | mutex_init(&command_queue_mutex); |
4892 | queue_init(&tagcache_queue, true); | 4892 | queue_init(&tagcache_queue, true); |
4893 | create_thread(tagcache_thread, tagcache_stack, | 4893 | create_thread(tagcache_thread, tagcache_stack, |
4894 | sizeof(tagcache_stack), 0, tagcache_thread_name | 4894 | sizeof(tagcache_stack), 0, tagcache_thread_name |
4895 | IF_PRIO(, PRIORITY_BACKGROUND) | 4895 | IF_PRIO(, PRIORITY_BACKGROUND) |
4896 | IF_COP(, CPU)); | 4896 | IF_COP(, CPU)); |
4897 | #else | 4897 | #else |