Back to index

texmacs  1.0.7.15
data_cache.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : data_cache.cpp
00004 * DESCRIPTION: utilities for caching data
00005 * COPYRIGHT  : (C) 2005  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "data_cache.hpp"
00013 #include "file.hpp"
00014 #include "convert.hpp"
00015 #include "iterator.hpp"
00016 
00017 /******************************************************************************
00018 * Caching routines
00019 ******************************************************************************/
00020 
00021 static hashmap<tree,tree> cache_data ("?");
00022 static hashset<string> cache_loaded;
00023 static hashset<string> cache_changed;
00024 static hashmap<string,bool> cache_valid (false);
00025 
00026 void
00027 cache_set (string buffer, tree key, tree t) {
00028   tree ckey= tuple (buffer, key);
00029   if (cache_data[ckey] != t) {
00030     cache_data (ckey)= t;
00031     cache_changed->insert (buffer);
00032   }
00033 }
00034 
00035 void
00036 cache_reset (string buffer, tree key) {
00037   tree ckey= tuple (buffer, key);
00038   cache_data->reset (ckey);
00039   cache_changed->insert (buffer);
00040 }
00041 
00042 bool
00043 is_cached (string buffer, tree key) {
00044   tree ckey= tuple (buffer, key);
00045   return cache_data->contains (ckey);
00046 }
00047 
00048 tree
00049 cache_get (string buffer, tree key) {
00050   tree ckey= tuple (buffer, key);
00051   return cache_data [ckey];
00052 }
00053 
00054 bool
00055 is_up_to_date (url dir, bool reset) {
00056   string name_dir= concretize (dir);
00057   if (reset) cache_valid->reset (name_dir);
00058   if (cache_valid->contains (name_dir)) return cache_valid [name_dir];
00059   int l= last_modified (dir, false);
00060   if (is_cached ("validate_cache.scm", name_dir)) {
00061     int r= as_int (cache_get ("validate_cache.scm", name_dir) -> label);
00062     if (l == r) {
00063       cache_valid (name_dir)= true;
00064       return true;
00065     }
00066     //cout << name_dir << " no longer up to date " << r << " -> " << l << "\n";
00067   }
00068   //else cout << name_dir << " not up to date " << l << "\n";
00069   cache_set ("validate_cache.scm", name_dir, as_string (l));
00070   cache_valid (name_dir)= false;
00071   return false;
00072 }
00073 
00074 bool
00075 is_recursively_up_to_date (url dir) {
00076   if (!is_up_to_date (dir)) return false;
00077   bool error_flag;
00078   array<string> a= read_directory (dir, error_flag);
00079   for (int i=0; i<N(a); i++)
00080     if (url (a[i]) != url_here () && url (a[i]) != url_parent ())
00081       if (is_directory (dir * a[i]))
00082        if (!is_recursively_up_to_date (dir * a[i]))
00083          return false;
00084   return true;
00085 }
00086 
00087 /******************************************************************************
00088 * Which files should be stored in the cache?
00089 ******************************************************************************/
00090 
00091 static url texmacs_path (url_none ());
00092 static url texmacs_doc_path (url_none ());
00093 static url texmacs_home_path (url_none ());
00094 
00095 static string texmacs_path_string;
00096 static string texmacs_doc_path_string;
00097 static string texmacs_home_path_string;
00098 static string texmacs_font_path_string;
00099 
00100 bool
00101 do_cache_dir (string name) {
00102   return
00103     starts (name, texmacs_path_string) ||
00104     starts (name, texmacs_doc_path_string);
00105 }
00106 
00107 bool
00108 do_cache_stat (string name) {
00109   return
00110     starts (name, texmacs_path_string) ||
00111     starts (name, texmacs_font_path_string) ||
00112     starts (name, texmacs_doc_path_string);
00113 }
00114 
00115 bool
00116 do_cache_stat_fail (string name) {
00117   return
00118     !ends (name, ".ts") &&
00119     (starts (name, texmacs_path_string) ||
00120      starts (name, texmacs_doc_path_string));
00121 }
00122 
00123 bool
00124 do_cache_file (string name) {
00125   return
00126     !ends (name, ".ts") &&
00127     (starts (name, texmacs_path_string) ||
00128      starts (name, texmacs_font_path_string));
00129 }
00130 
00131 bool
00132 do_cache_doc (string name) {
00133   return starts (name, texmacs_doc_path_string);
00134 }
00135 
00136 /******************************************************************************
00137 * Saving and loading the cache to/from disk
00138 ******************************************************************************/
00139 
00140 void
00141 cache_save (string buffer) {
00142   if (cache_changed->contains (buffer)) {
00143     url cache_file= texmacs_home_path * url ("system/cache/" * buffer);
00144     string cached;
00145     iterator<tree> it= iterate (cache_data);
00146     if (buffer == "file_cache" || buffer == "doc_cache") {
00147       while (it->busy ()) {
00148        tree ckey= it->next ();
00149        if (ckey[0] == buffer) {
00150          cached << ckey[1]->label << "\n";
00151          cached << cache_data [ckey]->label << "\n";
00152          cached << "%-%-tm-cache-%-%\n";
00153        }
00154       }
00155     }
00156     else {
00157       cached << "(tuple\n";
00158       while (it->busy ()) {
00159        tree ckey= it->next ();
00160        if (ckey[0] == buffer) {
00161          cached << tree_to_scheme (ckey[1]) << " ";
00162          cached << tree_to_scheme (cache_data [ckey]) << "\n";
00163        }
00164       }
00165       cached << ")";
00166     }
00167     (void) save_string (cache_file, cached);
00168     cache_changed->remove (buffer);
00169   }
00170 }
00171 
00172 void
00173 cache_load (string buffer) {
00174   if (!cache_loaded->contains (buffer)) {
00175     url cache_file = texmacs_home_path * url ("system/cache/" * buffer);
00176     //cout << "cache_file "<< cache_file << LF;
00177     string cached;
00178     if (!load_string (cache_file, cached, false)) {
00179       if (buffer == "file_cache" || buffer == "doc_cache") {
00180        int i=0, n= N(cached);
00181        while (i<n) {
00182          int start= i;
00183          while (i<n && cached[i] != '\n') i++;
00184          string key= cached (start, i);
00185          i++; start= i;
00186          while (i<n && (cached[i] != '\n' ||
00187                       !test (cached, i+1, "%-%-tm-cache-%-%"))) i++;
00188          string im= cached (start, i);
00189          i++;
00190          while (i<n && cached[i] != '\n') i++;
00191          i++;
00192          //cout << "key= " << key << "\n----------------------\n";
00193          //cout << "im= " << im << "\n----------------------\n";
00194          cache_data (tuple (buffer, key))= im;
00195        }
00196       }
00197       else {
00198        tree t= scheme_to_tree (cached);
00199        for (int i=0; i<N(t)-1; i+=2)
00200          cache_data (tuple (buffer, t[i]))= t[i+1];
00201       }
00202     }
00203     cache_loaded->insert (buffer);
00204   }
00205 }
00206 
00207 void
00208 cache_memorize () {
00209   cache_save ("file_cache");
00210   cache_save ("doc_cache");
00211   cache_save ("dir_cache.scm");
00212   cache_save ("stat_cache.scm");
00213   cache_save ("font_cache.scm");
00214   cache_save ("validate_cache.scm");
00215 }
00216 
00217 void
00218 cache_refresh () {
00219   cache_data   = hashmap<tree,tree> ("?");
00220   cache_loaded = hashset<string> ();
00221   cache_changed= hashset<string> ();
00222   cache_load ("file_cache");
00223   cache_load ("dir_cache.scm");
00224   cache_load ("stat_cache.scm");
00225   cache_load ("font_cache.scm");
00226   cache_load ("validate_cache.scm");
00227 }
00228 
00229 void
00230 cache_initialize () {
00231   texmacs_path= url_system ("$TEXMACS_PATH");
00232   if (get_env ("TEXMACS_HOME_PATH") == "")
00233     texmacs_home_path= url_system ("$HOME/.TeXmacs");
00234   else texmacs_home_path= url_system ("$TEXMACS_HOME_PATH");
00235   if (get_env ("TEXMACS_DOC_PATH") == "")
00236     texmacs_doc_path= url_system ("$TEXMACS_PATH/doc");
00237   else texmacs_doc_path= url_system ("$TEXMACS_DOC_PATH");
00238   
00239   texmacs_path_string = concretize (texmacs_path);
00240   texmacs_home_path_string = concretize (texmacs_home_path);
00241   texmacs_doc_path_string = concretize (texmacs_doc_path);
00242   texmacs_font_path_string = concretize (texmacs_home_path * "fonts/");
00243   
00244    
00245   cache_refresh ();
00246   if (is_recursively_up_to_date (texmacs_path * "fonts/type1") &&
00247       is_recursively_up_to_date (texmacs_path * "fonts/truetype") &&
00248       is_recursively_up_to_date (texmacs_home_path * "fonts/type1") &&
00249       is_recursively_up_to_date (texmacs_home_path * "fonts/truetype"));
00250   else remove (texmacs_home_path * "fonts/error" * url_wildcard ("*"));
00251 }