Skip to content

Instantly share code, notes, and snippets.

@mweppler
Created May 8, 2013 19:15
Show Gist options
  • Save mweppler/5542865 to your computer and use it in GitHub Desktop.
Save mweppler/5542865 to your computer and use it in GitHub Desktop.
store = {}
store.setdefault = (key, def) ->
@[key] = def unless @[key]
@[key]
namespace = 'pcache'
formatKey = ->
[].slice.call(arguments).join '.'
Cache = (cache_name) ->
registration_table_key = formatKey namespace, 'registration_table'
registration_table = store[registration_table_key]
cache_info = registration_table[cache_name]
@_cache_name = cache_name
@_version = cache_info[0]
@_data_type = cache_info[1]
@_timeout = cache_info[2]
Cache.register = (cache_name, data_type, timeout) ->
throw new TypeError 'Unsupported type' unless /number|string/.test typeof data_type
registration_table_key = formatKey namespace, 'registration_table'
registration_table = store.setdefault registration_table_key, {}
registration_table[cache_name] = [1, data_type, timeout] unless registration_table[cache_name]
new Cache cache_name
Cache.prototype =
timeout: ->
@_timeout
cache_name: ->
@_cache_name
version: ->
@_version
getFullKey: (key) ->
formatKey namespace, @_cache_name, @_version, key
timeInSeconds: ->
Math.floor Date.now() / 1000
getTimeout: ->
@timeInSeconds() + @_timeout
validateCollection: (collection) ->
for d in collection
do (d) ->
throw new TypeError if typeof d != @_data_type
validateTTL: (ttl, full_key) ->
if ttl < @timeInSeconds()
delete store[full_key]
throw new Error 'key expired'
bump_version: ->
registration_table_key = formatKey namespace, 'registration_table'
registration_table = store[registration_table_key]
version = registration_table[@_cache_name][0]
@_version = version + 1
registration_table[@_cache_name] = [@_version, @_data_type, @_timeout]
write: (key, datum) ->
throw new TypeError if typeof datum != @_data_type
full_key = @getFullKey key
ttl = @getTimeout()
store[full_key] = [datum, ttl]
write_collection: (key, datum_collection) ->
collection = datum_collection.slice()
@validateCollection datum_collection
full_key = @getFullKey key
ttl = @getTimeout()
store[full_key] = [collection, ttl]
read: (key) ->
full_key = @getFullKey key
datum = store[full_key][0]
ttl = store[full_key][1]
@validateTTL ttl, full_key
throw new TypeError if typeof datum != @_data_type
ttl = @timeInSeconds() + @_timeout
store[full_key] = [datum, ttl]
return datum
read_collection: (key) ->
full_key = @getFullKey key
collection = store[full_key][0]
ttl = store[full_key][1]
@validateTTL ttl, full_key
@validateCollection datum_collection
ttl = @getTimeout()
store[full_key] = [collection, ttl]
return collection
module.exports = Cache;
cache = Cache.register 'test', 'number', 30
cache.write 'test', 2342
console.log cache.read 'test'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment