File: lru_cache.rb

package info (click to toggle)
ruby-aws-sdk-core 3.212.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,232 kB
  • sloc: ruby: 17,533; makefile: 4
file content (75 lines) | stat: -rw-r--r-- 1,786 bytes parent folder | download
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