1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 67 68 69 70 71 72 73 74 75
|
# frozen_string_literal: true
module Aws
# @api private
# A simple thread safe LRU cache
class LRUCache
# @param [Hash] options
# @option options [Integer] :max_entries (100) Maximum number of entries
# @option options [Integer] :expiration (nil) Expiration time in seconds
def initialize(options = {})
@max_entries = options[:max_entries] || 100
@expiration = options[:expiration]
@entries = {}
@mutex = Mutex.new
end
# @param [String] key
# @return [Object]
def [](key)
@mutex.synchronize do
value = @entries[key]
if value
@entries.delete(key)
@entries[key] = value unless value.expired?
end
@entries[key]&.value
end
end
# @param [String] key
# @param [Object] value
def []=(key, value)
@mutex.synchronize do
@entries.shift unless @entries.size < @max_entries
# delete old value if exists
@entries.delete(key)
@entries[key] = Entry.new(value: value, expiration: @expiration)
@entries[key].value
end
end
# @param [String] key
# @return [Boolean]
def key?(key)
@mutex.synchronize do
@entries.delete(key) if @entries.key?(key) && @entries[key].expired?
@entries.key?(key)
end
end
def clear
@mutex.synchronize do
@entries.clear
end
end
# @api private
class Entry
def initialize(options = {})
@value = options[:value]
@expiration = options[:expiration]
@created_time = Time.now
end
# @return [Object]
attr_reader :value
def expired?
return false unless @expiration
Time.now - @created_time > @expiration
end
end
end
end
|