in_memory_cache 0.0.0 → 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7550d96162651e202ede0fd0b8672a4439e8eca791c9a9b8aef3f178f19514fe
4
- data.tar.gz: cf16e84e42cc8d3edd7b6142222bfd69c663c7a3fdee0ca1ff392b077f9f032a
3
+ metadata.gz: 74663c00729180e3f82f1d8f6d4988eb8c02d8485e0cb1d80093d8178ad72d70
4
+ data.tar.gz: db98b4e0bd4c1172e5011896b6a177af5de6c253e4d48d6deccab05ff202eb9f
5
5
  SHA512:
6
- metadata.gz: cb0341fdba9f8f9e8477ff777bca46a6d33b8728b0554dfc36f187f22c1db3ef2f37141812a3085dfc7895a49049a7ea6f1c277444f327e2fb8f4962f249fb82
7
- data.tar.gz: 6068b434a0f8b85d687809d3e4ec1a4ae4eaaf56cb48bac95df853bd6f80391f8ac3b6f3bfea3f4743a8ab4ee5a9179393d96be54182371b534ec124e9e72408
6
+ metadata.gz: d732a622f11a188fe57085eb0261055551db626e53dd7647d07353b3d13bfc08c27b20bc134b58322f436728c6c1d35ac74866a2ff230be285357096ba6d4956
7
+ data.tar.gz: a5b15cee0e4f91d2e8c45c22eaa683c5157911c7f009f15efcc556bffac279d555ad736ec6b727eaf029c3c7243582fb3d82fec01b3bef4bbf53de4247465d55
@@ -1,10 +1,18 @@
1
1
  module MemoryCache
2
2
  # A processor level in memory cache storage. Data is not across multiple processes. Thread-safe
3
3
  class MemoryCacheStore
4
+
5
+ MEGABYTE = 1024 * 1024
6
+
4
7
  def initialize
5
8
  @data = {}
6
9
  @key_access_store = {}
7
10
  @lock = Monitor.new
11
+ @cache_size = 0
12
+ @max_size = 25 * MEGABYTE
13
+ @buffer_size = 5 * MEGABYTE
14
+ @max_wait_loop_for_flush = 100
15
+ @max_single_value_limit = 2 * MEGABYTE
8
16
  end
9
17
 
10
18
 
@@ -12,8 +20,21 @@ module MemoryCache
12
20
  # return true if success, false if any exception
13
21
  def write(key, value, options = {})
14
22
  synchronize_block do
23
+ return false unless can_allocate_value?(value)
24
+ prune_keys(@buffer_size) if is_buffer_limit_reached?
25
+
26
+ old_value_present = false
27
+
28
+ if key_exists?(key)
29
+ old_value_present = true
30
+ old_value = @data[key]
31
+ old_value_size = compute_value_size(old_value)
32
+ end
33
+
15
34
  @data[key] = value
16
35
  @key_access_store[key] = Time.now.utc.to_i
36
+ @cache_size -= old_value_size if old_value_present
37
+ @cache_size += compute_value_size(value)
17
38
  return true
18
39
  end
19
40
  end
@@ -23,14 +44,17 @@ module MemoryCache
23
44
  def read(key, options = {})
24
45
  synchronize_block do
25
46
  @key_access_store[key] = Time.now.utc.to_i
26
- return @data[key] ? @data[key].dup : nil
47
+ return @data[key] ? dup_value(@data[key]) : nil
27
48
  end
28
49
  end
29
50
 
30
51
  # delete key from store
31
52
  def delete(key, options = {})
53
+ old_key_present = key_exists?(key)
54
+ value = @data[key]
32
55
  @data.delete(key)
33
56
  @key_access_store.delete(key)
57
+ @cache_size -= compute_value_size(value) if @cache_size > 0 && old_key_present
34
58
  end
35
59
 
36
60
  # Synchronize calls to the cache for thread safety
@@ -46,5 +70,46 @@ module MemoryCache
46
70
  end
47
71
  end
48
72
 
73
+ def key_exists?(key)
74
+ @data.key?(key)
75
+ end
76
+
77
+ private
78
+
79
+ def prune_keys(new_allocate_size = 0)
80
+ keys = synchronize_block { @key_access_store.keys.sort { |a, b| @key_access_store[a] <=> @key_access_store[b] } }
81
+ loop_counter = 0
82
+ keys.each do |key|
83
+ delete(key)
84
+ return if available_size > new_allocate_size
85
+ if loop_counter >= @max_wait_loop_for_flush
86
+ clear
87
+ return
88
+ end
89
+ loop_counter += 1
90
+ end
91
+ end
92
+
93
+ def compute_value_size(value = '')
94
+ value.to_s.bytesize
95
+ end
96
+
97
+ def available_size
98
+ size = @max_size - @cache_size
99
+ size < 0 ? 0 : size
100
+ end
101
+
102
+ def is_buffer_limit_reached?
103
+ available_size <= @buffer_size
104
+ end
105
+
106
+ def can_allocate_value?(value = '')
107
+ value.to_s.bytesize < @max_single_value_limit
108
+ end
109
+
110
+ def dup_value(value)
111
+ value.is_a?(String) ? value.dup : value
112
+ end
113
+
49
114
  end
50
115
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: in_memory_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - kathir