cache_box 0.0.1.pre.preview7 → 0.0.1.pre.preview8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ class Unit
5
+ include CacheBox::Helper::Validate
6
+
7
+ # Input:
8
+ #
9
+ # namespace = String | Symbol # Default: :namespace
10
+ #
11
+ # Output: N/A
12
+ def initialize(namespace = nil, logger: nil, storage: nil)
13
+ namespace ||= :namespace
14
+ validate_string_or_symbol!(namespace, 'namespace')
15
+
16
+ @namespace = namespace
17
+ @logger = logger || Logger.new(STDOUT, level: Logger::INFO)
18
+ @storage = storage || ::CacheBox::Storage::File.new(namespace: @namespace)
19
+
20
+ @state = { result: {}, stash: {} }
21
+ end
22
+
23
+ # Input:
24
+ #
25
+ # name = String | Symbol # Default: 'name'
26
+ # args = Object
27
+ # input = Object
28
+ # &block = Proc(CacheBox::Box)
29
+ #
30
+ # Output: Object # Anything the &block returns.
31
+ def with(name = nil, args = nil, input = nil, &block)
32
+ name ||= 'name'
33
+ validate_string_or_symbol!(name, 'name')
34
+ validate_block_presence!(block, '#with')
35
+
36
+ name_o = name
37
+ name_s = name.to_s
38
+
39
+ return @state[:result][name_s] if @state[:result].key?(name_s)
40
+
41
+ data = @storage.read!(name_s)
42
+ if data&.key?(:result)
43
+ @state[:result][name_s] = data[:result]
44
+
45
+ return data[:result]
46
+ elsif data&.key?(:stash)
47
+ @state[:stash][name_s] = data[:stash]
48
+ end
49
+
50
+ box = ::CacheBox::Box.new(
51
+ namespace: @namespace.dup,
52
+ name: name_o.dup,
53
+ args: args,
54
+ input: input,
55
+ stash: @state[:stash][name] || {},
56
+ logger: @logger
57
+ )
58
+
59
+ begin
60
+ @state[:result][name_s] = block.call(box)
61
+ ensure
62
+ if @state[:result].key?(name_s)
63
+ @state[:stash].delete(name_s)
64
+ @storage.write!(name_s, { result: @state[:result][name_s] })
65
+ else
66
+ stash = box.stash
67
+ dump = { stash: stash }
68
+
69
+ @state[:stash][name_s] = stash
70
+ @storage.write!(name_s, dump)
71
+ end
72
+ end
73
+ end
74
+
75
+ # Input:
76
+ #
77
+ # name = String | Symbol # Default: 'name'
78
+ #
79
+ # Output: true | false
80
+ def has?(name = nil)
81
+ name ||= 'name'
82
+ validate_string_or_symbol!(name, 'name')
83
+ name = name.to_s
84
+
85
+ return true if @state[:result].key?(name)
86
+
87
+ data = @storage.read!(name)
88
+
89
+ if data&.key?(:result)
90
+ @state[:result][name] = data[:result]
91
+ elsif data&.key?(:stash)
92
+ @state[:stash][name] = data[:stash]
93
+ end
94
+
95
+ @state[:result].key?(name)
96
+ end
97
+
98
+ # Input:
99
+ #
100
+ # name = String | Symbol # Default: 'name'
101
+ #
102
+ # Output: true | false
103
+ def result(name = nil)
104
+ name ||= 'name'
105
+ validate_string_or_symbol!(name, 'name')
106
+ name = name.to_s
107
+
108
+ return @state[:result][name] if @state[:result].key?(name)
109
+
110
+ data = @storage.read!(name)
111
+
112
+ if data&.key?(:result)
113
+ @state[:result][name] = data[:result]
114
+ elsif data&.key?(:stash)
115
+ @state[:stash][name] = data[:stash]
116
+ end
117
+
118
+ @state[:result][name]
119
+ end
120
+
121
+ # Input:
122
+ #
123
+ # name = Array[String | Symbol] # Default: []
124
+ #
125
+ # Output: self
126
+ def expire!(*names)
127
+ validate_array_of_string_or_symbol!(names, 'names')
128
+
129
+ if names.empty?
130
+ @state = { result: {}, stash: {} }
131
+
132
+ @storage.reset!
133
+ else
134
+ names.each do |name|
135
+ name = name.to_s
136
+ @state[:result].delete(name)
137
+ @state[:stash].delete(name)
138
+
139
+ @storage.delete!(name)
140
+ end
141
+ end
142
+
143
+ self
144
+ end
145
+
146
+ # Input:
147
+ #
148
+ # name = Array[String | Symbol] # Default: []
149
+ #
150
+ # Output: self
151
+ def clear(*names)
152
+ validate_array_of_string_or_symbol!(names, 'names')
153
+
154
+ if names.empty?
155
+ @state = { result: {}, stash: {} }
156
+ else
157
+ names.each do |name_o|
158
+ name_s = name_o.to_s
159
+
160
+ @state[:result].delete(name_s)
161
+ @state[:stash].delete(name_s)
162
+ end
163
+ end
164
+
165
+ self
166
+ end
167
+ end
168
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_box
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre.preview7
4
+ version: 0.0.1.pre.preview8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Codruț Constantin Gușoi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-23 00:00:00.000000000 Z
11
+ date: 2020-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.88'
69
- description:
69
+ description:
70
70
  email:
71
71
  - codrut.gusoi+rubygems.org@gmail.com
72
72
  executables: []
@@ -76,16 +76,21 @@ files:
76
76
  - LICENSE
77
77
  - cache_box.gemspec
78
78
  - lib/cache_box.rb
79
+ - lib/cache_box/box.rb
79
80
  - lib/cache_box/chain.rb
80
- - lib/cache_box/file_storage.rb
81
- - lib/cache_box/memory_storage.rb
81
+ - lib/cache_box/graph.rb
82
+ - lib/cache_box/helper/validate.rb
83
+ - lib/cache_box/scheduler/serial.rb
84
+ - lib/cache_box/storage/file.rb
85
+ - lib/cache_box/storage/memory.rb
86
+ - lib/cache_box/unit.rb
82
87
  homepage: https://gitlab.com/sdwolfz/cache_box_rb
83
88
  licenses:
84
89
  - BSD-3-Clause
85
90
  metadata:
86
91
  homepage_uri: https://gitlab.com/sdwolfz/cache_box_rb
87
92
  source_code_uri: https://gitlab.com/sdwolfz/cache_box_rb
88
- post_install_message:
93
+ post_install_message:
89
94
  rdoc_options: []
90
95
  require_paths:
91
96
  - lib
@@ -100,8 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
105
  - !ruby/object:Gem::Version
101
106
  version: 1.3.1
102
107
  requirements: []
103
- rubygems_version: 3.1.2
104
- signing_key:
108
+ rubygems_version: 3.1.3
109
+ signing_key:
105
110
  specification_version: 4
106
111
  summary: A simple, fast, and easy to use local cache.
107
112
  test_files: []
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CacheBox
4
- # A storage backed by files.
5
- class FileStorage
6
- # Input:
7
- #
8
- # namespace = Symbol | String # Default: 'namespace'
9
- # path = String # Path; Default: nil
10
- #
11
- # Output: N/A
12
- def initialize(namespace: nil, path: nil)
13
- validate_symbol_or_string!(namespace, 'namespace')
14
- validate_string!(path, 'path')
15
-
16
- @namespace = namespace.to_s || 'namespace'
17
-
18
- root = path || File.join(Dir.pwd, '.cache')
19
- @path = File.join(root, @namespace)
20
- end
21
-
22
- # Output: self
23
- def reset!
24
- FileUtils.remove_entry_secure(@path, true)
25
-
26
- self
27
- end
28
-
29
- # Reads the content.
30
- #
31
- # Input:
32
- #
33
- # name = String
34
- #
35
- # Output: Object # Anything
36
- def read!(name)
37
- validate_string!(name, 'name')
38
-
39
- file = File.join(@path, name)
40
- return unless File.exist?(file)
41
-
42
- Marshal.load(File.read(file))
43
- end
44
-
45
- # Input:
46
- #
47
- # name = String
48
- # data = Object # Anything
49
- #
50
- # Output: self
51
- def write!(name, data)
52
- validate_string!(name, 'name')
53
-
54
- FileUtils.mkdir_p(@path) unless Dir.exist?(@path)
55
-
56
- content = Marshal.dump(data)
57
- file = File.join(@path, name)
58
-
59
- File.write(file, content)
60
-
61
- self
62
- end
63
-
64
- # Input:
65
- #
66
- # name = String
67
- #
68
- # Output: self
69
- def delete!(name)
70
- validate_string!(name, 'name')
71
-
72
- file = File.join(@path, name)
73
- FileUtils.remove_entry_secure(file, true)
74
-
75
- self
76
- end
77
-
78
- # Input:
79
- #
80
- # name = String
81
- #
82
- # Output: true | false
83
- def has?(name)
84
- validate_string!(name, 'name')
85
-
86
- file = File.join(@path, name)
87
- File.file?(file)
88
- end
89
-
90
- private
91
-
92
- def validate_symbol_or_string!(arg, name)
93
- return if arg.nil? || arg.is_a?(Symbol) || arg.is_a?(String)
94
-
95
- klass = arg.class
96
- value = arg.inspect
97
-
98
- raise(
99
- ArgumentError,
100
- "#{name} must be a Symbol or String, got #{klass}: #{value}"
101
- )
102
- end
103
-
104
- def validate_string!(arg, name)
105
- return if arg.nil? || arg.is_a?(String)
106
-
107
- klass = arg.class
108
- value = arg.inspect
109
-
110
- raise(
111
- ArgumentError,
112
- "#{name} must be a String, got #{klass}: #{value}"
113
- )
114
- end
115
- end
116
- end
@@ -1,193 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CacheBox
4
- # A storage backed by an in memory Hash.
5
- class MemoryStorage
6
- # Accepts a Hash or any Hash-like object as argument. Will use a plain Hash
7
- # if none provided.
8
- #
9
- # Input:
10
- #
11
- # state = Hash{...Object => Object} # Default: nil
12
- #
13
- # Output: N/A
14
- def initialize(state = nil)
15
- validate!(state)
16
-
17
- @state = state || {}
18
- end
19
-
20
- # Accepts a Hash or any Hash-like object as argument. Will use a plain Hash
21
- # if none provided.
22
- #
23
- # Input:
24
- #
25
- # state = Hash{...Object => Object}
26
- #
27
- # Output: self
28
- def reset!(state = nil)
29
- initialize(state)
30
-
31
- self
32
- end
33
-
34
- # Input:
35
- #
36
- # name = String
37
- #
38
- # Output: Object # Anything
39
- def read!(name)
40
- validate_string!(name, 'name')
41
-
42
- @state[name]
43
- end
44
-
45
- # Input:
46
- #
47
- # name = String
48
- # data = Object # Anything
49
- #
50
- # Output: self
51
- def write!(name, data)
52
- validate_string!(name, 'name')
53
-
54
- @state[name] = data
55
-
56
- self
57
- end
58
-
59
- # Input:
60
- #
61
- # name = String
62
- #
63
- # Output: self
64
- def delete!(name)
65
- validate_string!(name, 'name')
66
-
67
- @state.delete(name)
68
-
69
- self
70
- end
71
-
72
- # Input:
73
- #
74
- # name = String
75
- #
76
- # Output: true | false
77
- def has?(name)
78
- validate_string!(name, 'name')
79
-
80
- @state.key?(name)
81
- end
82
-
83
- private
84
-
85
- # Input:
86
- #
87
- # state = Object # Anything
88
- #
89
- # Output: N/A
90
- def validate!(state)
91
- return if state.nil? || state.is_a?(Hash)
92
-
93
- validate_get!(state)
94
- validate_set!(state)
95
- validate_delete!(state)
96
- validate_key!(state)
97
- end
98
-
99
- # Input:
100
- #
101
- # state = Object # Anything
102
- #
103
- # Output: N/A
104
- def validate_get!(state)
105
- unless state.respond_to?(:[])
106
- raise(ArgumentError, 'Given state object does not respond to `:[]`')
107
- end
108
-
109
- arity = state.method(:[]).arity
110
- unless arity == 1
111
- raise(
112
- ArgumentError,
113
- "Given state object's `:[]` method arity must be 1, got: #{arity}"
114
- )
115
- end
116
- end
117
-
118
- # Input:
119
- #
120
- # state = Object # Anything
121
- #
122
- # Output: N/A
123
- def validate_set!(state)
124
- unless state.respond_to?(:[]=)
125
- raise(ArgumentError, 'Given state object does not respond to `:[]=`')
126
- end
127
-
128
- arity = state.method(:[]=).arity
129
- unless arity == 2
130
- raise(
131
- ArgumentError,
132
- "Given state object's `:[]=` method arity must be 2, got: #{arity}"
133
- )
134
- end
135
- end
136
-
137
- # Input:
138
- #
139
- # state = Object # Anything
140
- #
141
- # Output: N/A
142
- def validate_delete!(state)
143
- unless state.respond_to?(:delete)
144
- raise(ArgumentError, 'Given state object does not respond to `delete`')
145
- end
146
-
147
- arity = state.method(:delete).arity
148
- unless arity == 1
149
- raise(
150
- ArgumentError,
151
- "Given state object's `:delete` method arity must be 1, got: #{arity}"
152
- )
153
- end
154
- end
155
-
156
- # Input:
157
- #
158
- # state = Object # Anything
159
- #
160
- # Output: N/A
161
- def validate_key!(state)
162
- unless state.respond_to?(:key?)
163
- raise(ArgumentError, 'Given state object does not respond to `:key?`')
164
- end
165
-
166
- arity = state.method(:key?).arity
167
- unless arity == 1
168
- raise(
169
- ArgumentError,
170
- "Given state object's `:key?` method arity must be 1, got: #{arity}"
171
- )
172
- end
173
- end
174
-
175
- # Input:
176
- #
177
- # arg = String
178
- # name = String
179
- #
180
- # Output: N/A
181
- def validate_string!(arg, name)
182
- return if arg.nil? || arg.is_a?(String)
183
-
184
- klass = arg.class
185
- value = arg.inspect
186
-
187
- raise(
188
- ArgumentError,
189
- "#{name} must be a String, got #{klass}: #{value}"
190
- )
191
- end
192
- end
193
- end