diff options
Diffstat (limited to 'firmware/include/dircache.h')
-rw-r--r-- | firmware/include/dircache.h | 209 |
1 files changed, 140 insertions, 69 deletions
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 019ccf49b7..7e8c764e7f 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2005 by Miika Pekkarinen | 10 | * Copyright (C) 2005 by Miika Pekkarinen |
11 | * Copyright (C) 2014 by Michael Sevakis | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
@@ -21,84 +22,154 @@ | |||
21 | #ifndef _DIRCACHE_H | 22 | #ifndef _DIRCACHE_H |
22 | #define _DIRCACHE_H | 23 | #define _DIRCACHE_H |
23 | 24 | ||
24 | #include "config.h" | 25 | #include "mv.h" |
25 | #include "dir_uncached.h" | 26 | #include <string.h> /* size_t */ |
26 | #include <string.h> /* size_t */ | 27 | #include <sys/types.h> /* ssize_t */ |
27 | 28 | ||
28 | #ifdef HAVE_DIRCACHE | 29 | #ifdef HAVE_DIRCACHE |
29 | 30 | ||
30 | #define DIRCACHE_RESERVE (1024*64) | 31 | /**************************************************************************** |
31 | #define DIRCACHE_LIMIT (1024*1024*6) | 32 | ** Configurable values |
32 | 33 | **/ | |
33 | #define DIRCACHE_APPFLAG_TAGCACHE 0x0001 | 34 | |
34 | #define DIRCACHE_APPFLAG_PLAYLIST 0x0002 | 35 | #if 0 |
35 | 36 | /* enable dumping code */ | |
36 | /* Internal structures. */ | 37 | #define DIRCACHE_DUMPSTER |
37 | struct travel_data { | 38 | #define DIRCACHE_DUMPSTER_BIN "/dircache_dump.bin" |
38 | struct dircache_entry *first; | 39 | #define DIRCACHE_DUMPSTER_CSV "/dircache_dump.csv" |
39 | struct dircache_entry *ce; | ||
40 | struct dircache_entry *down_entry; | ||
41 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | ||
42 | DIR_UNCACHED *dir, *newdir; | ||
43 | struct dirent_uncached *entry; | ||
44 | #else | ||
45 | struct fat_dir *dir; | ||
46 | struct fat_dir newdir; | ||
47 | struct fat_direntry entry; | ||
48 | #endif | 40 | #endif |
49 | int pathpos; | 41 | |
42 | /* dircache builds won't search below this but will work down to this point | ||
43 | while below it the cache will just pass requests through to the storage; | ||
44 | the limiting factor is the scanning thread stack size, not the | ||
45 | implementation -- tune the two together */ | ||
46 | #define DIRCACHE_MAX_DEPTH 15 | ||
47 | #define DIRCACHE_STACK_SIZE (DEFAULT_STACK_SIZE + 0x100) | ||
48 | |||
49 | /* memory buffer constants that control allocation */ | ||
50 | #define DIRCACHE_RESERVE (1024*64) /* 64 KB - new entry slack */ | ||
51 | #define DIRCACHE_MIN (1024*1024*1) /* 1 MB - provision min size */ | ||
52 | #define DIRCACHE_LIMIT (1024*1024*6) /* 6 MB - provision max size */ | ||
53 | |||
54 | /* make it easy to change serialnumber size without modifying anything else; | ||
55 | 32 bits allows 21845 builds before wrapping in a 6MB cache that is filled | ||
56 | exclusively with entries and nothing else (32 byte entries), making that | ||
57 | figure pessimistic */ | ||
58 | typedef uint32_t dc_serial_t; | ||
59 | |||
60 | /** | ||
61 | ****************************************************************************/ | ||
62 | |||
63 | #if CONFIG_PLATFORM & PLATFORM_NATIVE | ||
64 | /* native dircache is lower-level than on a hosted target */ | ||
65 | #define DIRCACHE_NATIVE | ||
66 | #endif | ||
67 | |||
68 | struct dircache_file | ||
69 | { | ||
70 | int idx; /* this file's cache index */ | ||
71 | dc_serial_t serialnum; /* this file's serial number */ | ||
50 | }; | 72 | }; |
51 | 73 | ||
52 | struct dirent_cached { | 74 | enum dircache_status |
53 | struct dirinfo info; | 75 | { |
54 | char *d_name; | 76 | DIRCACHE_IDLE = 0, /* no volume is initialized */ |
55 | long startcluster; | 77 | DIRCACHE_SCANNING = 1, /* dircache is scanning a volume */ |
78 | DIRCACHE_READY = 2, /* dircache is ready to be used */ | ||
79 | }; | ||
80 | |||
81 | /** Dircache control **/ | ||
82 | void dircache_wait(void); | ||
83 | void dircache_suspend(void); | ||
84 | int dircache_resume(void); | ||
85 | int dircache_enable(void); | ||
86 | void dircache_disable(void); | ||
87 | void dircache_free_buffer(void); | ||
88 | |||
89 | /** Volume mounting **/ | ||
90 | void dircache_mount(void); /* always tries building everything it can */ | ||
91 | void dircache_unmount(IF_MV_NONVOID(int volume)); | ||
92 | |||
93 | |||
94 | /** File API service functions **/ | ||
95 | |||
96 | /* avoid forcing #include of file_internal.h, fat.h and dir.h */ | ||
97 | struct filestr_base; | ||
98 | struct file_base_info; | ||
99 | struct file_base_binding; | ||
100 | struct dirent; | ||
101 | struct dirscan_info; | ||
102 | struct dirinfo_native; | ||
103 | |||
104 | int dircache_readdir_dirent(struct filestr_base *stream, | ||
105 | struct dirscan_info *scanp, | ||
106 | struct dirent *entry); | ||
107 | void dircache_rewinddir_dirent(struct dirscan_info *scanp); | ||
108 | |||
109 | #ifdef DIRCACHE_NATIVE | ||
110 | struct fat_direntry; | ||
111 | int dircache_readdir_internal(struct filestr_base *stream, | ||
112 | struct file_base_info *infop, | ||
113 | struct fat_direntry *fatent); | ||
114 | void dircache_rewinddir_internal(struct file_base_info *info); | ||
115 | #endif /* DIRCACHE_NATIVE */ | ||
116 | |||
117 | |||
118 | /** Dircache live updating **/ | ||
119 | |||
120 | void dircache_get_rootinfo(struct file_base_info *infop); | ||
121 | void dircache_bind_file(struct file_base_binding *bindp); | ||
122 | void dircache_unbind_file(struct file_base_binding *bindp); | ||
123 | void dircache_fileop_create(struct file_base_info *dirinfop, | ||
124 | struct file_base_binding *bindp, | ||
125 | const char *basename, | ||
126 | const struct dirinfo_native *dinp); | ||
127 | void dircache_fileop_rename(struct file_base_info *dirinfop, | ||
128 | struct file_base_binding *bindp, | ||
129 | const char *basename); | ||
130 | void dircache_fileop_remove(struct file_base_binding *bindp); | ||
131 | void dircache_fileop_sync(struct file_base_binding *infop, | ||
132 | const struct dirinfo_native *dinp); | ||
133 | |||
134 | |||
135 | /** Dircache paths and files **/ | ||
136 | ssize_t dircache_get_path(const struct dircache_file *dcfilep, char *buf, | ||
137 | size_t size); | ||
138 | int dircache_get_file(const char *path, struct dircache_file *dcfilep); | ||
139 | |||
140 | |||
141 | /** Debug screen/info stuff **/ | ||
142 | |||
143 | struct dircache_info | ||
144 | { | ||
145 | enum dircache_status status; /* current composite status value */ | ||
146 | const char *statusdesc; /* pointer to string describing 'status' */ | ||
147 | size_t last_size; /* cache size after last build */ | ||
148 | size_t size; /* total size of entries (with holes) */ | ||
149 | size_t sizeused; /* bytes of 'size' actually utilized */ | ||
150 | size_t size_limit; /* maximum possible size */ | ||
151 | size_t reserve; /* size of reserve area */ | ||
152 | size_t reserve_used; /* amount of reserve used */ | ||
153 | unsigned int entry_count; /* number of cache entries */ | ||
154 | long build_ticks; /* total time used to build cache */ | ||
56 | }; | 155 | }; |
57 | 156 | ||
58 | typedef struct { | 157 | void dircache_get_info(struct dircache_info *info); |
59 | bool busy; | 158 | #ifdef DIRCACHE_DUMPSTER |
60 | struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ | 159 | void dircache_dump(void); |
61 | int internal_entry; /* the current entry in the directory */ | 160 | #endif /* DIRCACHE_DUMPSTER */ |
62 | DIR_UNCACHED *regulardir; | 161 | |
63 | } DIR_CACHED; | ||
64 | 162 | ||
65 | void dircache_init(void) INIT_ATTR; | 163 | /** Misc. stuff **/ |
164 | void dircache_dcfile_init(struct dircache_file *dcfilep); | ||
165 | |||
166 | #ifdef HAVE_EEPROM_SETTINGS | ||
66 | int dircache_load(void); | 167 | int dircache_load(void); |
67 | int dircache_save(void); | 168 | int dircache_save(void); |
68 | int dircache_build(int last_size); | 169 | #endif /* HAVE_EEPROM_SETTINGS */ |
69 | void* dircache_steal_buffer(size_t *size); | ||
70 | bool dircache_is_enabled(void); | ||
71 | bool dircache_is_initializing(void); | ||
72 | void dircache_set_appflag(long mask); | ||
73 | bool dircache_get_appflag(long mask); | ||
74 | int dircache_get_entry_count(void); | ||
75 | int dircache_get_cache_size(void); | ||
76 | int dircache_get_reserve_used(void); | ||
77 | int dircache_get_build_ticks(void); | ||
78 | void dircache_disable(void); | ||
79 | void dircache_suspend(void); | ||
80 | bool dircache_resume(void); | ||
81 | int dircache_get_entry_id(const char *filename); | ||
82 | size_t dircache_copy_path(int index, char *buf, size_t size); | ||
83 | |||
84 | /* the next two are internal for file.c */ | ||
85 | long _dircache_get_entry_startcluster(int id); | ||
86 | struct dirinfo* _dircache_get_entry_dirinfo(int id); | ||
87 | |||
88 | void dircache_bind(int fd, const char *path); | ||
89 | void dircache_update_filesize(int fd, long newsize, long startcluster); | ||
90 | void dircache_update_filetime(int fd); | ||
91 | void dircache_mkdir(const char *path); | ||
92 | void dircache_rmdir(const char *path); | ||
93 | void dircache_remove(const char *name); | ||
94 | void dircache_rename(const char *oldpath, const char *newpath); | ||
95 | void dircache_add_file(const char *path, long startcluster); | ||
96 | |||
97 | DIR_CACHED* opendir_cached(const char* name); | ||
98 | struct dirent_cached* readdir_cached(DIR_CACHED* dir); | ||
99 | int closedir_cached(DIR_CACHED *dir); | ||
100 | int mkdir_cached(const char *name); | ||
101 | int rmdir_cached(const char* name); | ||
102 | #endif /* !HAVE_DIRCACHE */ | ||
103 | 170 | ||
104 | #endif | 171 | void dircache_init(size_t last_size) INIT_ATTR; |
172 | |||
173 | #endif /* HAVE_DIRCACHE */ | ||
174 | |||
175 | #endif /* _DIRCACHE_H */ | ||