PageRenderTime 58ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/source/src/System/Misc/data_cache.cpp

http://itexmacs.googlecode.com/
C++ | 251 lines | 201 code | 27 blank | 23 comment | 53 complexity | 09a58dd78d358cdc175995e3bab142ab MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /******************************************************************************
  2. * MODULE : data_cache.cpp
  3. * DESCRIPTION: utilities for caching data
  4. * COPYRIGHT : (C) 2005 Joris van der Hoeven
  5. *******************************************************************************
  6. * This software falls under the GNU general public license version 3 or later.
  7. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  8. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  9. ******************************************************************************/
  10. #include "data_cache.hpp"
  11. #include "file.hpp"
  12. #include "convert.hpp"
  13. #include "iterator.hpp"
  14. /******************************************************************************
  15. * Caching routines
  16. ******************************************************************************/
  17. static hashmap<tree,tree> cache_data ("?");
  18. static hashset<string> cache_loaded;
  19. static hashset<string> cache_changed;
  20. static hashmap<string,bool> cache_valid (false);
  21. void
  22. cache_set (string buffer, tree key, tree t) {
  23. tree ckey= tuple (buffer, key);
  24. if (cache_data[ckey] != t) {
  25. cache_data (ckey)= t;
  26. cache_changed->insert (buffer);
  27. }
  28. }
  29. void
  30. cache_reset (string buffer, tree key) {
  31. tree ckey= tuple (buffer, key);
  32. cache_data->reset (ckey);
  33. cache_changed->insert (buffer);
  34. }
  35. bool
  36. is_cached (string buffer, tree key) {
  37. tree ckey= tuple (buffer, key);
  38. return cache_data->contains (ckey);
  39. }
  40. tree
  41. cache_get (string buffer, tree key) {
  42. tree ckey= tuple (buffer, key);
  43. return cache_data [ckey];
  44. }
  45. bool
  46. is_up_to_date (url dir, bool reset) {
  47. string name_dir= concretize (dir);
  48. if (reset) cache_valid->reset (name_dir);
  49. if (cache_valid->contains (name_dir)) return cache_valid [name_dir];
  50. int l= last_modified (dir, false);
  51. if (is_cached ("validate_cache.scm", name_dir)) {
  52. int r= as_int (cache_get ("validate_cache.scm", name_dir) -> label);
  53. if (l == r) {
  54. cache_valid (name_dir)= true;
  55. return true;
  56. }
  57. //cout << name_dir << " no longer up to date " << r << " -> " << l << "\n";
  58. }
  59. //else cout << name_dir << " not up to date " << l << "\n";
  60. cache_set ("validate_cache.scm", name_dir, as_string (l));
  61. cache_valid (name_dir)= false;
  62. return false;
  63. }
  64. bool
  65. is_recursively_up_to_date (url dir) {
  66. if (!is_up_to_date (dir)) return false;
  67. bool error_flag;
  68. array<string> a= read_directory (dir, error_flag);
  69. for (int i=0; i<N(a); i++)
  70. if (url (a[i]) != url_here () && url (a[i]) != url_parent ())
  71. if (is_directory (dir * a[i]))
  72. if (!is_recursively_up_to_date (dir * a[i]))
  73. return false;
  74. return true;
  75. }
  76. /******************************************************************************
  77. * Which files should be stored in the cache?
  78. ******************************************************************************/
  79. static url texmacs_path (url_none ());
  80. static url texmacs_doc_path (url_none ());
  81. static url texmacs_home_path (url_none ());
  82. static string texmacs_path_string;
  83. static string texmacs_doc_path_string;
  84. static string texmacs_home_path_string;
  85. static string texmacs_font_path_string;
  86. bool
  87. do_cache_dir (string name) {
  88. return
  89. starts (name, texmacs_path_string) ||
  90. starts (name, texmacs_doc_path_string);
  91. }
  92. bool
  93. do_cache_stat (string name) {
  94. return
  95. starts (name, texmacs_path_string) ||
  96. starts (name, texmacs_font_path_string) ||
  97. starts (name, texmacs_doc_path_string);
  98. }
  99. bool
  100. do_cache_stat_fail (string name) {
  101. return
  102. !ends (name, ".ts") &&
  103. (starts (name, texmacs_path_string) ||
  104. starts (name, texmacs_doc_path_string));
  105. }
  106. bool
  107. do_cache_file (string name) {
  108. return
  109. !ends (name, ".ts") &&
  110. (starts (name, texmacs_path_string) ||
  111. starts (name, texmacs_font_path_string));
  112. }
  113. bool
  114. do_cache_doc (string name) {
  115. return starts (name, texmacs_doc_path_string);
  116. }
  117. /******************************************************************************
  118. * Saving and loading the cache to/from disk
  119. ******************************************************************************/
  120. void
  121. cache_save (string buffer) {
  122. if (cache_changed->contains (buffer)) {
  123. url cache_file= texmacs_home_path * url ("system/cache/" * buffer);
  124. string cached;
  125. iterator<tree> it= iterate (cache_data);
  126. if (buffer == "file_cache" || buffer == "doc_cache") {
  127. while (it->busy ()) {
  128. tree ckey= it->next ();
  129. if (ckey[0] == buffer) {
  130. cached << ckey[1]->label << "\n";
  131. cached << cache_data [ckey]->label << "\n";
  132. cached << "%-%-tm-cache-%-%\n";
  133. }
  134. }
  135. }
  136. else {
  137. cached << "(tuple\n";
  138. while (it->busy ()) {
  139. tree ckey= it->next ();
  140. if (ckey[0] == buffer) {
  141. cached << tree_to_scheme (ckey[1]) << " ";
  142. cached << tree_to_scheme (cache_data [ckey]) << "\n";
  143. }
  144. }
  145. cached << ")";
  146. }
  147. (void) save_string (cache_file, cached);
  148. cache_changed->remove (buffer);
  149. }
  150. }
  151. void
  152. cache_load (string buffer) {
  153. if (!cache_loaded->contains (buffer)) {
  154. url cache_file = texmacs_home_path * url ("system/cache/" * buffer);
  155. //cout << "cache_file "<< cache_file << LF;
  156. string cached;
  157. if (!load_string (cache_file, cached, false)) {
  158. if (buffer == "file_cache" || buffer == "doc_cache") {
  159. int i=0, n= N(cached);
  160. while (i<n) {
  161. int start= i;
  162. while (i<n && cached[i] != '\n') i++;
  163. string key= cached (start, i);
  164. i++; start= i;
  165. while (i<n && (cached[i] != '\n' ||
  166. !test (cached, i+1, "%-%-tm-cache-%-%"))) i++;
  167. string im= cached (start, i);
  168. i++;
  169. while (i<n && cached[i] != '\n') i++;
  170. i++;
  171. //cout << "key= " << key << "\n----------------------\n";
  172. //cout << "im= " << im << "\n----------------------\n";
  173. cache_data (tuple (buffer, key))= im;
  174. }
  175. }
  176. else {
  177. tree t= scheme_to_tree (cached);
  178. for (int i=0; i<N(t)-1; i+=2)
  179. cache_data (tuple (buffer, t[i]))= t[i+1];
  180. }
  181. }
  182. cache_loaded->insert (buffer);
  183. }
  184. }
  185. void
  186. cache_memorize () {
  187. cache_save ("file_cache");
  188. cache_save ("doc_cache");
  189. cache_save ("dir_cache.scm");
  190. cache_save ("stat_cache.scm");
  191. cache_save ("font_cache.scm");
  192. cache_save ("validate_cache.scm");
  193. }
  194. void
  195. cache_refresh () {
  196. cache_data = hashmap<tree,tree> ("?");
  197. cache_loaded = hashset<string> ();
  198. cache_changed= hashset<string> ();
  199. cache_load ("file_cache");
  200. cache_load ("dir_cache.scm");
  201. cache_load ("stat_cache.scm");
  202. cache_load ("font_cache.scm");
  203. cache_load ("validate_cache.scm");
  204. }
  205. void
  206. cache_initialize () {
  207. texmacs_path= url_system ("$TEXMACS_PATH");
  208. if (get_env ("TEXMACS_HOME_PATH") == "")
  209. texmacs_home_path= url_system ("$HOME/.TeXmacs");
  210. else texmacs_home_path= url_system ("$TEXMACS_HOME_PATH");
  211. if (get_env ("TEXMACS_DOC_PATH") == "")
  212. texmacs_doc_path= url_system ("$TEXMACS_PATH/doc");
  213. else texmacs_doc_path= url_system ("$TEXMACS_DOC_PATH");
  214. texmacs_path_string = concretize (texmacs_path);
  215. texmacs_home_path_string = concretize (texmacs_home_path);
  216. texmacs_doc_path_string = concretize (texmacs_doc_path);
  217. texmacs_font_path_string = concretize (texmacs_home_path * "fonts/");
  218. cache_refresh ();
  219. if (is_recursively_up_to_date (texmacs_path * "fonts/type1") &&
  220. is_recursively_up_to_date (texmacs_path * "fonts/truetype") &&
  221. is_recursively_up_to_date (texmacs_home_path * "fonts/type1") &&
  222. is_recursively_up_to_date (texmacs_home_path * "fonts/truetype"));
  223. else remove (texmacs_home_path * "fonts/error" * url_wildcard ("*"));
  224. }