Class: ThreeScale::Backend::Memoizer

Inherits:
Object
  • Object
show all
Defined in:
lib/3scale/backend/memoizer.rb

Defined Under Namespace

Modules: Decorator

Class Method Summary collapse

Class Method Details

.build_key(klass, method, *args) ⇒ Object

Generate a key for the given class, method and args



70
71
72
73
74
# File 'lib/3scale/backend/memoizer.rb', line 70

def self.build_key(klass, method, *args)
  key = build_class_key klass
  key = build_method_key key, method.to_s
  build_args_key key, *args
end

.build_keys_for_class(klass, methods_n_args) ⇒ Object

Pass in the class or object that receives the memoized methods, and a hash containing the methods as keys and an array of their arguments in order.



79
80
81
82
83
84
85
# File 'lib/3scale/backend/memoizer.rb', line 79

def self.build_keys_for_class(klass, methods_n_args)
  classkey = build_class_key klass
  methods_n_args.map do |method, args|
    key = build_method_key(classkey, method.to_s)
    build_args_key key, *args
  end
end

.clear(keys) ⇒ Object



128
129
130
131
132
# File 'lib/3scale/backend/memoizer.rb', line 128

def self.clear(keys)
  Array(keys).each do |key|
    @memoizer_cache.delete key
  end
end

.fetch(_key) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/3scale/backend/memoizer.rb', line 91

def self.fetch(key)
  @memoizer_stats_count = @memoizer_stats_count + 1

  cached = @memoizer_cache[key]

  now = Time.now.getutc.to_i
  purge(now) if now > @memoizer_purge_time

  if cached && now <= cached.expire
    @memoizer_stats_hits = @memoizer_stats_hits + 1
    cached
  end
end

.get(key) ⇒ Object



119
120
121
122
# File 'lib/3scale/backend/memoizer.rb', line 119

def self.get(key)
  entry = @memoizer_cache[key]
  entry.obj if entry
end

.memoize(_key, obj) ⇒ Object



105
106
107
108
# File 'lib/3scale/backend/memoizer.rb', line 105

def self.memoize(key, obj)
  @memoizer_cache[key] = Entry.new(obj, Time.now.getutc.to_i + EXPIRE)
  obj
end

.memoize_block(key, &block) ⇒ Object



153
154
155
156
157
158
159
160
# File 'lib/3scale/backend/memoizer.rb', line 153

def self.memoize_block(key, &block)
  entry = fetch key
  if entry.nil?
    Memoizer.memoize(key, yield)
  else
    entry.obj
  end
end

.memoized?(key) ⇒ Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/3scale/backend/memoizer.rb', line 124

def self.memoized?(key)
  !!(fetch key)
end

.purge(time) ⇒ Object



134
135
136
137
138
139
140
141
142
143
# File 'lib/3scale/backend/memoizer.rb', line 134

def self.purge(time)
  @memoizer_purge_time = time + PURGE

  @memoizer_cache.delete_if do |_, entry|
    time > entry.expire
  end

  ##safety, should never reach this unless massive concurrency
  reset! if @memoizer_cache.size > MAX_ENTRIES
end

.reset!Object



12
13
14
15
16
17
18
19
20
# File 'lib/3scale/backend/memoizer.rb', line 12

def self.reset!
  # Initialize class instance variables
  # Note: we would be better off pre-allocating the Hash size
  # ie. rb_hash_new_with_size(MAX_ENTRIES)
  @memoizer_cache = Hash.new
  @memoizer_purge_time = Time.now.getutc.to_i + PURGE
  @memoizer_stats_count = 0
  @memoizer_stats_hits = 0
end

.statsObject



145
146
147
148
149
150
151
# File 'lib/3scale/backend/memoizer.rb', line 145

def self.stats
  {
    size: @memoizer_cache.size,
    count: @memoizer_stats_count,
    hits: @memoizer_stats_hits,
  }
end