summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/tagcache.c151
1 files changed, 110 insertions, 41 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 5566b17f03..dbf58c69fa 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -187,11 +187,9 @@ struct tempbuf_searchidx {
187 struct tempbuf_id_list idlist; 187 struct tempbuf_id_list idlist;
188}; 188};
189 189
190/* Lookup buffer for fixing messed up index while after sorting. */
190static long commit_entry_count; 191static long commit_entry_count;
191 192static long lookup_buffer_depth;
192#define LOOKUP_BUF_DEPTH (commit_entry_count*2 \
193 * (TAGFILE_ENTRY_AVG_LENGTH/TAGFILE_ENTRY_CHUNK_LENGTH))
194
195struct tempbuf_searchidx **lookup; 193struct tempbuf_searchidx **lookup;
196 194
197/* Used when building the temporary file. */ 195/* Used when building the temporary file. */
@@ -289,7 +287,7 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
289 close(fd); 287 close(fd);
290 return -2; 288 return -2;
291 } 289 }
292 290
293 return fd; 291 return fd;
294} 292}
295 293
@@ -1134,7 +1132,7 @@ static bool get_next(struct tagcache_search *tcs)
1134 if (read(tcs->idxfd[tcs->type], buf, entry.tag_length) != entry.tag_length) 1132 if (read(tcs->idxfd[tcs->type], buf, entry.tag_length) != entry.tag_length)
1135 { 1133 {
1136 tcs->valid = false; 1134 tcs->valid = false;
1137 logf("read error"); 1135 logf("read error #4");
1138 return false; 1136 return false;
1139 } 1137 }
1140 1138
@@ -1206,7 +1204,7 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
1206 if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) != 1204 if (read(tcs->idxfd[tcs->type], &tfe, sizeof(struct tagfile_entry)) !=
1207 sizeof(struct tagfile_entry)) 1205 sizeof(struct tagfile_entry))
1208 { 1206 {
1209 logf("read error"); 1207 logf("read error #5");
1210 return false; 1208 return false;
1211 } 1209 }
1212 1210
@@ -1219,7 +1217,7 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
1219 if (read(tcs->idxfd[tcs->type], buf, tfe.tag_length) != 1217 if (read(tcs->idxfd[tcs->type], buf, tfe.tag_length) !=
1220 tfe.tag_length) 1218 tfe.tag_length)
1221 { 1219 {
1222 logf("read error #2"); 1220 logf("read error #6");
1223 return false; 1221 return false;
1224 } 1222 }
1225 1223
@@ -1481,9 +1479,13 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique)
1481 1479
1482 if (!strcasecmp(str, index[i].str)) 1480 if (!strcasecmp(str, index[i].str))
1483 { 1481 {
1484 if (id >= 0 && id < LOOKUP_BUF_DEPTH) 1482 if (id < 0 || id >= lookup_buffer_depth)
1485 lookup[id] = &index[i]; 1483 {
1484 logf("lookup buf overf.: %d", id);
1485 return false;
1486 }
1486 1487
1488 lookup[id] = &index[i];
1487 return true; 1489 return true;
1488 } 1490 }
1489 } 1491 }
@@ -1498,7 +1500,13 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique)
1498 if (tempbuf_left - 4 < 0 || tempbufidx >= commit_entry_count-1) 1500 if (tempbuf_left - 4 < 0 || tempbufidx >= commit_entry_count-1)
1499 return false; 1501 return false;
1500 1502
1501 if (id >= 0 && id < LOOKUP_BUF_DEPTH) 1503 if (id >= lookup_buffer_depth)
1504 {
1505 logf("lookup buf overf. #2: %d", id);
1506 return false;
1507 }
1508
1509 if (id >= 0)
1502 { 1510 {
1503 lookup[id] = &index[tempbufidx]; 1511 lookup[id] = &index[tempbufidx];
1504 index[tempbufidx].idlist.id = id; 1512 index[tempbufidx].idlist.id = id;
@@ -1540,7 +1548,7 @@ static int tempbuf_sort(int fd)
1540 int length; 1548 int length;
1541 1549
1542 /* Generate reverse lookup entries. */ 1550 /* Generate reverse lookup entries. */
1543 for (i = 0; i < LOOKUP_BUF_DEPTH; i++) 1551 for (i = 0; i < lookup_buffer_depth; i++)
1544 { 1552 {
1545 struct tempbuf_id_list *idlist; 1553 struct tempbuf_id_list *idlist;
1546 1554
@@ -1573,7 +1581,7 @@ static int tempbuf_sort(int fd)
1573 } 1581 }
1574 1582
1575 qsort(index, tempbufidx, sizeof(struct tempbuf_searchidx), compare); 1583 qsort(index, tempbufidx, sizeof(struct tempbuf_searchidx), compare);
1576 memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(struct tempbuf_searchidx **)); 1584 memset(lookup, 0, lookup_buffer_depth * sizeof(struct tempbuf_searchidx **));
1577 1585
1578 for (i = 0; i < tempbufidx; i++) 1586 for (i = 0; i < tempbufidx; i++)
1579 { 1587 {
@@ -1633,7 +1641,7 @@ static int tempbuf_sort(int fd)
1633 1641
1634inline static struct tempbuf_searchidx* tempbuf_locate(int id) 1642inline static struct tempbuf_searchidx* tempbuf_locate(int id)
1635{ 1643{
1636 if (id < 0 || id >= LOOKUP_BUF_DEPTH) 1644 if (id < 0 || id >= lookup_buffer_depth)
1637 return NULL; 1645 return NULL;
1638 1646
1639 return lookup[id]; 1647 return lookup[id];
@@ -1764,10 +1772,60 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
1764 commit_entry_count += tcmh.tch.entry_count; 1772 commit_entry_count += tcmh.tch.entry_count;
1765 close(masterfd); 1773 close(masterfd);
1766 } 1774 }
1775
1776 /* Open the index file, which contains the tag names. */
1777 fd = open_tag_fd(&tch, index_type, true);
1778 if (fd >= 0)
1779 {
1780 logf("tch.datasize=%d", tch.datasize);
1781 lookup_buffer_depth = 1 +
1782 /* First part */ commit_entry_count +
1783 /* Second part */ (tch.datasize / TAGFILE_ENTRY_CHUNK_LENGTH);
1784 }
1785 else
1786 {
1787 lookup_buffer_depth = 1 +
1788 /* First part */ commit_entry_count +
1789 /* Second part */ 0;
1790 }
1767 1791
1792 logf("lookup_buffer_depth=%d", lookup_buffer_depth);
1793 logf("commit_entry_count=%d", commit_entry_count);
1794
1795 /* Allocate buffer for all index entries from both old and new
1796 * tag files. */
1768 tempbufidx = 0; 1797 tempbufidx = 0;
1769 tempbuf_pos = commit_entry_count * sizeof(struct tempbuf_searchidx); 1798 tempbuf_pos = commit_entry_count * sizeof(struct tempbuf_searchidx);
1770 tempbuf_pos += LOOKUP_BUF_DEPTH * sizeof(void **); 1799
1800 /* Allocate lookup buffer. The first portion of commit_entry_count
1801 * contains the new tags in the temporary file and the second
1802 * part for locating entries already in the db.
1803 *
1804 * New tags Old tags
1805 * +---------+---------------------------+
1806 * | index | position/ENTRY_CHUNK_SIZE | lookup buffer
1807 * +---------+---------------------------+
1808 *
1809 * Old tags are inserted to a temporary buffer with position:
1810 * tempbuf_insert(position/ENTRY_CHUNK_SIZE, ...);
1811 * And new tags with index:
1812 * tempbuf_insert(idx, ...);
1813 *
1814 * The buffer is sorted and written into tag file:
1815 * tempbuf_sort(...);
1816 * leaving master index locations messed up.
1817 *
1818 * That is fixed using the lookup buffer for old tags:
1819 * new_seek = tempbuf_find_location(old_seek, ...);
1820 * and for new tags:
1821 * new_seek = tempbuf_find_location(idx);
1822 */
1823 lookup = (struct tempbuf_searchidx **)&tempbuf[tempbuf_pos];
1824 tempbuf_pos += lookup_buffer_depth * sizeof(void **);
1825 memset(lookup, 0, lookup_buffer_depth * sizeof(void **));
1826
1827 /* And calculate the remaining data space used mainly for storing
1828 * tag data (strings). */
1771 tempbuf_left = tempbuf_size - tempbuf_pos - 8; 1829 tempbuf_left = tempbuf_size - tempbuf_pos - 8;
1772 if (tempbuf_left - TAGFILE_ENTRY_AVG_LENGTH * commit_entry_count < 0) 1830 if (tempbuf_left - TAGFILE_ENTRY_AVG_LENGTH * commit_entry_count < 0)
1773 { 1831 {
@@ -1775,13 +1833,6 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
1775 return 0; 1833 return 0;
1776 } 1834 }
1777 1835
1778 lookup = (struct tempbuf_searchidx **)
1779 (tempbuf + sizeof(struct tempbuf_searchidx)*commit_entry_count);
1780 memset(lookup, 0, LOOKUP_BUF_DEPTH * sizeof(void **));
1781
1782 /* Open the index file, which contains the tag names. */
1783 fd = open_tag_fd(&tch, index_type, true);
1784
1785 if (fd >= 0) 1836 if (fd >= 0)
1786 { 1837 {
1787 /** 1838 /**
@@ -1796,11 +1847,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
1796 { 1847 {
1797 struct tagfile_entry entry; 1848 struct tagfile_entry entry;
1798 int loc = lseek(fd, 0, SEEK_CUR); 1849 int loc = lseek(fd, 0, SEEK_CUR);
1850 bool ret;
1799 1851
1800 if (read(fd, &entry, sizeof(struct tagfile_entry)) 1852 if (read(fd, &entry, sizeof(struct tagfile_entry))
1801 != sizeof(struct tagfile_entry)) 1853 != sizeof(struct tagfile_entry))
1802 { 1854 {
1803 logf("read error"); 1855 logf("read error #7");
1804 close(fd); 1856 close(fd);
1805 return -2; 1857 return -2;
1806 } 1858 }
@@ -1814,7 +1866,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
1814 1866
1815 if (read(fd, buf, entry.tag_length) != entry.tag_length) 1867 if (read(fd, buf, entry.tag_length) != entry.tag_length)
1816 { 1868 {
1817 logf("read error #2"); 1869 logf("read error #8");
1818 close(fd); 1870 close(fd);
1819 return -2; 1871 return -2;
1820 } 1872 }
@@ -1828,9 +1880,14 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
1828 * is saved so we can later reindex the master lookup 1880 * is saved so we can later reindex the master lookup
1829 * table when the index gets resorted. 1881 * table when the index gets resorted.
1830 */ 1882 */
1831 tempbuf_insert(buf, loc/TAGFILE_ENTRY_CHUNK_LENGTH 1883 ret = tempbuf_insert(buf, loc/TAGFILE_ENTRY_CHUNK_LENGTH
1832 + commit_entry_count, entry.idx_id, 1884 + commit_entry_count, entry.idx_id,
1833 tagcache_is_unique_tag(index_type)); 1885 tagcache_is_unique_tag(index_type));
1886 if (!ret)
1887 {
1888 close(fd);
1889 return -3;
1890 }
1834 yield(); 1891 yield();
1835 } 1892 }
1836 logf("done"); 1893 logf("done");
@@ -2186,7 +2243,7 @@ static bool commit(void)
2186 2243
2187 while (write_lock) 2244 while (write_lock)
2188 sleep(1); 2245 sleep(1);
2189 2246
2190 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 2247 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY);
2191 if (tmpfd < 0) 2248 if (tmpfd < 0)
2192 { 2249 {
@@ -2214,6 +2271,15 @@ static bool commit(void)
2214 return true; 2271 return true;
2215 } 2272 }
2216 2273
2274#ifdef HAVE_EEPROM_SETTINGS
2275 remove(TAGCACHE_STATEFILE);
2276#endif
2277
2278 /* At first be sure to unload the ramcache! */
2279#ifdef HAVE_TC_RAMCACHE
2280 stat.ramcache = false;
2281#endif
2282
2217 read_lock++; 2283 read_lock++;
2218 2284
2219 /* Try to steal every buffer we can :) */ 2285 /* Try to steal every buffer we can :) */
@@ -2230,7 +2296,6 @@ static bool commit(void)
2230 if (tempbuf_size > 0) 2296 if (tempbuf_size > 0)
2231 { 2297 {
2232 dircache_buffer_stolen = true; 2298 dircache_buffer_stolen = true;
2233 stat.ramcache = false;
2234 } 2299 }
2235 } 2300 }
2236#endif 2301#endif
@@ -2238,7 +2303,6 @@ static bool commit(void)
2238#ifdef HAVE_TC_RAMCACHE 2303#ifdef HAVE_TC_RAMCACHE
2239 if (tempbuf_size == 0 && stat.ramcache_allocated > 0) 2304 if (tempbuf_size == 0 && stat.ramcache_allocated > 0)
2240 { 2305 {
2241 stat.ramcache = false;
2242 tempbuf = (char *)(hdr + 1); 2306 tempbuf = (char *)(hdr + 1);
2243 tempbuf_size = stat.ramcache_allocated - sizeof(struct ramcache_header) - 128; 2307 tempbuf_size = stat.ramcache_allocated - sizeof(struct ramcache_header) - 128;
2244 tempbuf_size &= ~0x03; 2308 tempbuf_size &= ~0x03;
@@ -2325,7 +2389,7 @@ static bool commit(void)
2325 2389
2326#ifdef HAVE_TC_RAMCACHE 2390#ifdef HAVE_TC_RAMCACHE
2327 /* Reload tagcache. */ 2391 /* Reload tagcache. */
2328 if (stat.ramcache_allocated > 0 && !stat.ramcache) 2392 if (stat.ramcache_allocated > 0)
2329 tagcache_start_scan(); 2393 tagcache_start_scan();
2330#endif 2394#endif
2331 2395
@@ -2710,7 +2774,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
2710 if (read(tcs->masterfd, &idx, sizeof(struct index_entry)) 2774 if (read(tcs->masterfd, &idx, sizeof(struct index_entry))
2711 != sizeof(struct index_entry)) 2775 != sizeof(struct index_entry))
2712 { 2776 {
2713 logf("read error"); 2777 logf("read error #9");
2714 tagcache_search_finish(tcs); 2778 tagcache_search_finish(tcs);
2715 close(clfd); 2779 close(clfd);
2716 return false; 2780 return false;
@@ -2755,20 +2819,22 @@ static bool delete_entry(long idx_id)
2755 char buf[MAX_PATH]; 2819 char buf[MAX_PATH];
2756 int in_use[TAG_COUNT]; 2820 int in_use[TAG_COUNT];
2757 2821
2822 logf("delete_entry(): %d", idx_id);
2823
2758#ifdef HAVE_TC_RAMCACHE 2824#ifdef HAVE_TC_RAMCACHE
2759 /* At first mark the entry removed from ram cache. */ 2825 /* At first mark the entry removed from ram cache. */
2760 if (hdr) 2826 if (hdr)
2761 hdr->indices[idx_id].flag |= FLAG_DELETED; 2827 hdr->indices[idx_id].flag |= FLAG_DELETED;
2762#endif 2828#endif
2763 2829
2764 if ( (fd = open_master_fd(&myhdr, true) < 0) ) 2830 if ( (fd = open_master_fd(&myhdr, true) ) < 0)
2765 return false; 2831 return false;
2766 2832
2767 lseek(fd, idx_id * sizeof(struct index_entry), SEEK_CUR); 2833 lseek(fd, idx_id * sizeof(struct index_entry), SEEK_CUR);
2768 if (read(fd, &myidx, sizeof(struct index_entry)) 2834 if (read(fd, &myidx, sizeof(struct index_entry))
2769 != sizeof(struct index_entry)) 2835 != sizeof(struct index_entry))
2770 { 2836 {
2771 logf("read error"); 2837 logf("delete_entry(): read error");
2772 close(fd); 2838 close(fd);
2773 return false; 2839 return false;
2774 } 2840 }
@@ -2778,7 +2844,7 @@ static bool delete_entry(long idx_id)
2778 if (write(fd, &myidx, sizeof(struct index_entry)) 2844 if (write(fd, &myidx, sizeof(struct index_entry))
2779 != sizeof(struct index_entry)) 2845 != sizeof(struct index_entry))
2780 { 2846 {
2781 logf("write error"); 2847 logf("delete_entry(): write_error");
2782 close(fd); 2848 close(fd);
2783 return false; 2849 return false;
2784 } 2850 }
@@ -2793,7 +2859,7 @@ static bool delete_entry(long idx_id)
2793 if (read(fd, &idx, sizeof(struct index_entry)) 2859 if (read(fd, &idx, sizeof(struct index_entry))
2794 != sizeof(struct index_entry)) 2860 != sizeof(struct index_entry))
2795 { 2861 {
2796 logf("read error"); 2862 logf("delete_entry(): read error #2");
2797 close(fd); 2863 close(fd);
2798 return false; 2864 return false;
2799 } 2865 }
@@ -3024,7 +3090,7 @@ static bool load_tagcache(void)
3024 rc = read(fd, idx, sizeof(struct index_entry)); 3090 rc = read(fd, idx, sizeof(struct index_entry));
3025 if (rc != sizeof(struct index_entry)) 3091 if (rc != sizeof(struct index_entry))
3026 { 3092 {
3027 logf("read error #1"); 3093 logf("read error #10");
3028 close(fd); 3094 close(fd);
3029 return false; 3095 return false;
3030 } 3096 }
@@ -3084,7 +3150,7 @@ static bool load_tagcache(void)
3084 if (rc != sizeof(struct tagfile_entry)) 3150 if (rc != sizeof(struct tagfile_entry))
3085 { 3151 {
3086 /* End of lookup table. */ 3152 /* End of lookup table. */
3087 logf("read error"); 3153 logf("read error #11");
3088 close(fd); 3154 close(fd);
3089 return false; 3155 return false;
3090 } 3156 }
@@ -3113,7 +3179,7 @@ static bool load_tagcache(void)
3113 rc = read(fd, buf, fe->tag_length); 3179 rc = read(fd, buf, fe->tag_length);
3114 if (rc != fe->tag_length) 3180 if (rc != fe->tag_length)
3115 { 3181 {
3116 logf("read error #3"); 3182 logf("read error #12");
3117 close(fd); 3183 close(fd);
3118 return false; 3184 return false;
3119 } 3185 }
@@ -3195,7 +3261,7 @@ static bool load_tagcache(void)
3195 3261
3196 if (rc != fe->tag_length) 3262 if (rc != fe->tag_length)
3197 { 3263 {
3198 logf("read error #4"); 3264 logf("read error #13");
3199 logf("rc=0x%04x", rc); // 0x431 3265 logf("rc=0x%04x", rc); // 0x431
3200 logf("len=0x%04x", fe->tag_length); // 0x4000 3266 logf("len=0x%04x", fe->tag_length); // 0x4000
3201 logf("pos=0x%04x", lseek(fd, 0, SEEK_CUR)); // 0x433 3267 logf("pos=0x%04x", lseek(fd, 0, SEEK_CUR)); // 0x433
@@ -3243,7 +3309,7 @@ static bool check_deleted_files(void)
3243 3309
3244 if (read(fd, buf, tfe.tag_length) != tfe.tag_length) 3310 if (read(fd, buf, tfe.tag_length) != tfe.tag_length)
3245 { 3311 {
3246 logf("read error"); 3312 logf("read error #14");
3247 close(fd); 3313 close(fd);
3248 return false; 3314 return false;
3249 } 3315 }
@@ -3509,6 +3575,9 @@ static void tagcache_thread(void)
3509 3575
3510 case Q_UPDATE: 3576 case Q_UPDATE:
3511 build_tagcache(); 3577 build_tagcache();
3578#ifdef HAVE_TC_RAMCACHE
3579 load_ramcache();
3580#endif
3512 check_deleted_files(); 3581 check_deleted_files();
3513 break ; 3582 break ;
3514 3583