Class: RedParse::Cache
- Inherits:
-
Object
- Object
- RedParse::Cache
- Defined in:
- lib/redparse/cache.rb
Class Method Summary collapse
- .attempt_read(cache_fn, inputdigest, options, output_identity, want_file = false) ⇒ Object
- .attempt_write(cache_fn, inputdigest, options, output_identity, result) ⇒ Object
- .cachename_for_file(name, output_type) ⇒ Object
- .cachename_for_str(str, options, output_type) ⇒ Object
-
.find_home ⇒ Object
Finds the user’s home directory.
- .get(input, name, input_id, output_type, outputter_id) ⇒ Object
- .put(input, name, input_id, output_type, outputter_id, result) ⇒ Object
- .read(input, name, input_id, output_type, outputter_id) ⇒ Object
- .read_for_file(input, name, options, output_type, output_identity, &if_missing) ⇒ Object
- .read_for_str(input, options, output_type, output_identity, &if_missing) ⇒ Object
-
.read_trailer(f) ⇒ Object
encoder, options, inputhash, outputterhash, size.
- .write_for_file(input, name, options, output_type, output_identity, result) ⇒ Object
- .write_for_str(input, options, output_type, output_identity, result) ⇒ Object
Instance Method Summary collapse
- #all_entry_files ⇒ Object
- #cachedir ⇒ Object
- #get(input, output_type = "parsed") ⇒ Object
- #hash_of_input(input) ⇒ Object
-
#initialize(is_file, name, *params) ⇒ Cache
constructor
A new instance of Cache.
- #old_get(input) ⇒ Object
- #old_initialize(*params) ⇒ Object
- #old_put(input, result) ⇒ Object
- #put(input, result, output_type = "parsed") ⇒ Object
Constructor Details
#initialize(is_file, name, *params) ⇒ Cache
Returns a new instance of Cache.
26 27 28 29 30 31 32 33 |
# File 'lib/redparse/cache.rb', line 26 def initialize(is_file,name,*params) divider=params.index(:/) @input_id=params[0...divider] @output_id=params[divider+1..-1] @rubyversion=@input_id.pop @name=name @is_file=is_file end |
Class Method Details
.attempt_read(cache_fn, inputdigest, options, output_identity, want_file = false) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/redparse/cache.rb', line 307 def Cache.attempt_read(cache_fn,inputdigest,,output_identity,want_file=false) return if !File.exist? cache_fn #warn "...reading from cache file #{cache_fn}" #warn "...options=#{options.inspect}" outid=Digest::SHA2.hexdigest output_identity.join(',') cache_f=File.open(cache_fn,"rb") pos=cache_f.pos =.to_s encoder,,saved_inputdigest,saved_outid=read_trailer cache_f error=case when !encoder; "trailer not found" when saved_inputdigest!=inputdigest; "input changed" when saved_outid!=outid; "outputter changed" when =; "options changed from #{saved_options.inspect} to #{options.inspect}" end if error #warn "...cache read failed because #{error}" cache_f.close cache_f=nil return end case encoder when 'ascii' return cache_f if want_file return cache_f.read when 'Ron' begin require 'ron' return Ron.load( cache_f.read ) rescue Exception=>e warn "#{e.class}: #{e}" warn "cache ron read failed for:#{cache_fn}" return nil end when 'Marshal' cache_f.pos=pos begin return Marshal.load( cache_f ) rescue Exception=>e warn "#{e.class}: #{e}" warn "cache read failed for:#{cache_fn}" return nil end else warn "unrecognized RedParse::Cache encoder type: #{encoder}" return nil end end |
.attempt_write(cache_fn, inputdigest, options, output_identity, result) ⇒ Object
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
# File 'lib/redparse/cache.rb', line 361 def Cache.attempt_write(cache_fn,inputdigest,,output_identity,result) #STDERR.write "...writing to cache file #{cache_fn}... " if result.respond_to? :sysread path=result.path begin FileUtils.move(path,cache_fn) rescue Exception FileUtils.copy(path,cache_fn) end encoder= "ascii" #STDERR.puts 'file' cache_f=File.open(cache_fn,"a") else cache_f=File.open(cache_fn,"wb") if String===result cache_f.write result encoder= "ascii" #STDERR.puts 'ascii' else begin Thread.current["Marshal.ignore_sclass"]=true Marshal.dump(result,cache_f) encoder= "Marshal" #STDERR.puts 'Marshal' rescue TypeError #dump failed #STDERR.write "Marshal failed => " cache_f.close cache_f=File.open(cache_fn,"wb") begin require 'ron' cache_f.write Ron.dump(result) encoder='Ron' #STDERR.puts "Ron" rescue Exception #STDERR.puts "Ron failed" File.unlink(cache_fn) return end ensure Thread.current["Marshal.ignore_sclass"]=nil end end end outid=Digest::SHA2.hexdigest output_identity.join(',') trailer= "\n#encoded with #{encoder}\n##{options}\n##{inputdigest}\n##{outid}\n" sz=trailer.size+2 szsz=sz.to_s.size sz+=szsz sz+=1 unless szsz==sz.to_s.size trailer<< "##{sz}\n" fail 'bad trailer size' unless trailer[/^\#([0-9]+)\n\Z/,1].to_i==trailer.size cache_f.write trailer return result ensure cache_f.close if cache_f #STDERR.puts("...options=#{options.inspect}") end |
.cachename_for_file(name, output_type) ⇒ Object
261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/redparse/cache.rb', line 261 def Cache.cachename_for_file(name,output_type) cache_fn=File.join(File.dirname(name),CACHEDIRNAME,File.basename(name))+"."+output_type dir=File.dirname(cache_fn) begin Dir.mkdir dir unless File.exists?(dir) raise unless File.writable?(dir) rescue Exception #chosen dir is not writeable cache_fn=File.join(find_home,GLOBALCACHEDIRNAME,name)+"."+output_type FileUtils.mkdir_p( File.dirname( cache_fn ) ) end return cache_fn end |
.cachename_for_str(str, options, output_type) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/redparse/cache.rb', line 274 def Cache.cachename_for_str(str,,output_type) =.to_a.sort_by{|k,v| k}.map{|k,v| k+'='+v} if Hash=== =.join(',') unless String=== #options.gsub!('%n','%%n'); options.gsub!("\n",'%n') #fail if /\n/===options #str=options+"\n"+str =Digest::SHA2.hexdigest() if .size>100 digest=Digest::SHA2.hexdigest(str) cache_fn=File.join(find_home, GLOBALCACHEDIRNAME,"-e",,digest)+"."+output_type FileUtils.mkdir_p( File.dirname( cache_fn ) ) return cache_fn end |
.find_home ⇒ Object
Finds the user’s home directory. – Some comments from the ruby-talk list regarding finding the home directory:
I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
to be depending on HOME in those code samples. I propose that
it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
least on Win32).
(originally stolen from rubygems) before trying env variables, try getpwuid, since the environment might have been cleansed (eg by a cgi server) or altered (eg by rubygems tests).
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/redparse/cache.rb', line 115 def Cache.find_home begin return Etc.getpwuid.dir rescue Exception #do nothing end ['HOME', 'USERPROFILE'].each do |homekey| return ENV[homekey] if ENV[homekey] end if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" end begin File.("~") rescue if File::ALT_SEPARATOR then "C:/" else "/" end end end |
.get(input, name, input_id, output_type, outputter_id) ⇒ Object
237 238 239 240 241 242 243 |
# File 'lib/redparse/cache.rb', line 237 def Cache.get input,name,input_id,output_type,outputter_id if String===input read_for_str(input,input_id,output_type,outputter_id) else read_for_file(input,name,input_id,output_type,outputter_id) end end |
.put(input, name, input_id, output_type, outputter_id, result) ⇒ Object
245 246 247 248 249 250 251 |
# File 'lib/redparse/cache.rb', line 245 def Cache.put input,name,input_id,output_type,outputter_id,result if String===input write_for_str(input,input_id,output_type,outputter_id,result) else write_for_file(input,name,input_id,output_type,outputter_id,result) end end |
.read(input, name, input_id, output_type, outputter_id) ⇒ Object
253 254 255 256 257 258 259 |
# File 'lib/redparse/cache.rb', line 253 def Cache.read input,name,input_id,output_type,outputter_id result=get input,name,input_id,output_type,outputter_id return result if result result=yield put input,name,input_id,output_type,outputter_id,result end |
.read_for_file(input, name, options, output_type, output_identity, &if_missing) ⇒ Object
421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/redparse/cache.rb', line 421 def Cache.read_for_file(input,name,,output_type,output_identity,&if_missing) name=File.(name) inputdigest=Digest::SHA2.file(name).hexdigest cache_fn=cachename_for_file name,output_type result=attempt_read(cache_fn,inputdigest,,output_identity,:want_file) return result if result if if_missing and result=if_missing.call write_for_file(input,name,,output_type,output_identity,result) end end |
.read_for_str(input, options, output_type, output_identity, &if_missing) ⇒ Object
440 441 442 443 444 445 446 447 448 449 |
# File 'lib/redparse/cache.rb', line 440 def Cache.read_for_str(input,,output_type,output_identity,&if_missing) inputdigest=Digest::SHA2.hexdigest(input) cache_fn= cachename_for_str input,,output_type result=attempt_read(cache_fn,inputdigest,,output_identity) return result if result if if_missing and result=if_missing.call write_for_str(input,,output_type,output_identity,result) end end |
.read_trailer(f) ⇒ Object
encoder, options, inputhash, outputterhash, size
295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/redparse/cache.rb', line 295 def Cache.read_trailer(f) f.seek(-(9*3+2+1),IO::SEEK_END) size=f.read[/\n\# *([0-9]+) *\n\z/,1].to_i return if size.zero? f.seek(-size,IO::SEEK_END) buf=f.read return unless result=buf.match(HEADER_REX) result=result.to_a result.shift return result end |
.write_for_file(input, name, options, output_type, output_identity, result) ⇒ Object
433 434 435 436 437 438 |
# File 'lib/redparse/cache.rb', line 433 def Cache.write_for_file(input,name,,output_type,output_identity,result) name=File.(name) inputdigest=Digest::SHA2.file(name).hexdigest cache_fn=cachename_for_file name,output_type attempt_write(cache_fn,inputdigest,,output_identity,result) end |
.write_for_str(input, options, output_type, output_identity, result) ⇒ Object
451 452 453 454 455 |
# File 'lib/redparse/cache.rb', line 451 def Cache.write_for_str(input,,output_type,output_identity,result) inputdigest=Digest::SHA2.hexdigest(input) cache_fn= cachename_for_str input,,output_type attempt_write(cache_fn,inputdigest,,output_identity,result) end |
Instance Method Details
#all_entry_files ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/redparse/cache.rb', line 59 def all_entry_files Dir[@homedir+"*"].select{|fn| File.directory? fn }.map{|dirname| Dir[dirname+"/*"] }.flatten end |
#cachedir ⇒ Object
51 52 53 |
# File 'lib/redparse/cache.rb', line 51 def cachedir @homedir+@callersfile+"/" end |
#get(input, output_type = "parsed") ⇒ Object
215 216 217 218 219 220 221 222 |
# File 'lib/redparse/cache.rb', line 215 def get input,output_type="parsed" output_type=@rubyversion.to_s+output_type if @is_file Cache.read_for_file(input,@name,@input_id,output_type,@output_id) else Cache.read_for_str(input,@input_id,output_type,@output_id) end end |
#hash_of_input(input) ⇒ Object
143 144 145 146 147 148 149 |
# File 'lib/redparse/cache.rb', line 143 def hash_of_input input if IO===input hexdigest_of_file input else Digest::SHA2.hexdigest input end end |
#old_get(input) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/redparse/cache.rb', line 151 def old_get input hash=hash_of_input input cachefile=cachedir+hash if File.exist? cachefile result=File.open(cachefile,"rb"){|fd| line=fd.readline fd.rewind if /#encoded with Ron\n/i===line begin require 'ron' Ron.load fd.read rescue Exception return nil end else begin Marshal.load fd rescue Exception=>e warn "#{e.class}: #{e}" warn "cache read failed for:\n#{input}" return nil end end } begin t=Time.now File.utime(t,t,cachefile) rescue Exception File.open(cachefile,"a"){|fd| } #touch cache date end return result end rescue EOFError,Errno::EACCES return nil end |
#old_initialize(*params) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/redparse/cache.rb', line 35 def old_initialize *params @callersfile=Digest::SHA2.hexdigest params.join(',') @homedir=find_home+"/.redparse/" Dir.mkdir @homedir unless File.exist? @homedir Dir.mkdir cachedir unless File.exist? cachedir saved_digest= File.open(@homedir+"/parserdigest","rb"){|fd| fd.read.chomp } if File.exist?(@homedir+"/parserdigest") actual_digest= @@saved_parser_digest ||= redparse_rb_hexdigest if saved_digest!=actual_digest File.unlink(*all_entry_files) #flush cache File.open(@homedir+"/parserdigest","wb"){|fd| fd.puts actual_digest } #update saved digest end retire_old_entries rescue Errno::EACCES #do nothing end |
#old_put(input, result) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/redparse/cache.rb', line 188 def old_put input,result hash=hash_of_input input File.open(cachedir+hash, "wb"){|fd| begin Thread.current["Marshal.ignore_sclass"]=true Marshal.dump(result,fd) rescue TypeError #dump failed File.unlink cachedir+hash begin require 'ron' File.open(cachedir+hash, "wb"){|fd2| fd2.write "#encoded with Ron\n" fd2.write Ron.dump(result) } rescue Exception return end ensure Thread.current["Marshal.ignore_sclass"]=nil end } rescue Exception=>e #dump failed warn "#{e.class}: #{e}" warn "cache write failed for:\n#{result.inspect}" File.unlink cachedir+hash end |
#put(input, result, output_type = "parsed") ⇒ Object
224 225 226 227 228 229 230 231 |
# File 'lib/redparse/cache.rb', line 224 def put input,result,output_type="parsed" output_type=@rubyversion.to_s+output_type if @is_file Cache.write_for_file(input,@name,@input_id,output_type,@output_id,result) else Cache.write_for_str(input,@input_id,output_type,@output_id,result) end end |