Module: Air18n::ChunkCache
- Defined in:
- lib/air18n/chunk_cache.rb
Constant Summary collapse
- MAX_CHUNK_SIZE =
Define constants and cache keys.
We divide things into chunks of 900000 bytes to accomodate memcaches with 1mb max value size.
900000
- CHECKSUM_CACHE_KEY =
"%s_0_nchunks+checksum"
- CHUNK_CACHE_KEY =
"%s_%d"
Class Method Summary collapse
-
.get(cache, key) ⇒ Object
This returns nil if the chunks are corrupt or missing.
- .set(cache, key, value, expires_in) ⇒ Object
Class Method Details
.get(cache, key) ⇒ Object
This returns nil if the chunks are corrupt or missing.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/air18n/chunk_cache.rb', line 38 def get(cache, key) buffer = "" chunk = cache.read(CHECKSUM_CACHE_KEY % key) if chunk num_chunks, checksum = JSON.parse(chunk) else LoggingHelper.error "ChunkCache get: no checksum stored for #{key}" return nil end for i in 1..num_chunks chunk = cache.read(CHUNK_CACHE_KEY % [key, i]) if chunk.nil? # Return nil if any chunk is missing. LoggingHelper.error "ChunkCache get: chunk #{CHUNK_CACHE_KEY % [key, i]} is missing" return nil end buffer << chunk end if Zlib::crc32(buffer) != checksum LoggingHelper.error "ChunkCache get: invalid checksum for #{key}" return nil else return JSON.parse(buffer)[0] end end |
.set(cache, key, value, expires_in) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/air18n/chunk_cache.rb', line 19 def set(cache, key, value, expires_in) # We put the value in an array because plain strings are not valid JSON. value_json = [value].to_json # We use divmod to avoid the edge condition where the floating point math # result is 5.000001 and the ceil would result in 6. quotient, modulus = value_json.bytesize.divmod(MAX_CHUNK_SIZE) num_chunks = modulus > 0 ? quotient + 1 : quotient cache.write(CHECKSUM_CACHE_KEY % key, [num_chunks, Zlib::crc32(value_json)].to_json) 1.upto(num_chunks) do |i| chunk = value_json.byteslice((i-1)*MAX_CHUNK_SIZE, MAX_CHUNK_SIZE) if cache.write(CHUNK_CACHE_KEY % [key, i], chunk, :expires_in => expires_in) == false LoggingHelper.error "ChunkCache set: failed to write chunk #{CHUNK_CACHE_KEY % [key, i]} (#{chunk.size} chars / #{chunk.bytesize} bytes)" end end end |