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

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: e95404d4c91af3089b9d7d5628a3449010007df8784043b3668bc028b3b54c44
4
- data.tar.gz: f8fd2afe635ceab0504a2c2aef6b4a27417ad5bdde6564a7a39fd8af9b22840d
3
+ metadata.gz: 2121d192ceadcf66d3ddcea5bbed36e4b90d5a34749e50b3f23672f61cb8a7ea
4
+ data.tar.gz: b5c009712c162fa0b761ff4b8998645aed7a09e467e6569fbc785b76ac166b78
5
5
  SHA512:
6
- metadata.gz: 5c5a41a763a413cef9e294c01e94c18808f3e817bdd4baff7ac4b936225b19f3b7785a43981b9167066123d3fd0d5673e81f5b54c71586a83e64fa39c2907a99
7
- data.tar.gz: b2029aca5aa9a5a36a82e7010cb5959787ee214d7a0b1739b8575e95e5c3cfb7a842fde3c9264449d1dcb45dc926180d9eb3bbfd18edcb4b30d0ba2d04a50206
6
+ metadata.gz: c4c45937029f9096bc8a8224decec4ab72faa98569043b1292d19e050826a92a8be57bdf26612e2800f82712654a444b03c66327e9a4baa5f8110444967397c3
7
+ data.tar.gz: 97dece56e4b22094415960285047136b15a1e02bea647b0c8b41eb2b762b661ef301f81b7acc376b27cc9027a4c86c7403971656cf824e9e8debc59439922ad0
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'cache_box'
5
- spec.version = '0.0.1-preview7'
5
+ spec.version = '0.0.1-preview8'
6
6
  spec.authors = ['Codruț Constantin Gușoi']
7
7
  spec.email = ['codrut.gusoi+rubygems.org@gmail.com']
8
8
 
@@ -19,9 +19,14 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.files = [
21
21
  'lib/cache_box.rb',
22
+ 'lib/cache_box/helper/validate.rb',
23
+ 'lib/cache_box/scheduler/serial.rb',
24
+ 'lib/cache_box/storage/file.rb',
25
+ 'lib/cache_box/storage/memory.rb',
26
+ 'lib/cache_box/box.rb',
22
27
  'lib/cache_box/chain.rb',
23
- 'lib/cache_box/file_storage.rb',
24
- 'lib/cache_box/memory_storage.rb',
28
+ 'lib/cache_box/graph.rb',
29
+ 'lib/cache_box/unit.rb',
25
30
  'LICENSE',
26
31
  'cache_box.gemspec'
27
32
  ]
@@ -3,62 +3,49 @@
3
3
  require 'fileutils'
4
4
  require 'logger'
5
5
 
6
+ require_relative 'cache_box/helper/validate'
7
+
8
+ require_relative 'cache_box/storage/file'
9
+ require_relative 'cache_box/storage/memory'
10
+
11
+ require_relative 'cache_box/box'
12
+ require_relative 'cache_box/unit'
13
+
14
+ require_relative 'cache_box/scheduler/serial'
15
+
6
16
  require_relative 'cache_box/chain'
7
- require_relative 'cache_box/file_storage'
8
- require_relative 'cache_box/memory_storage'
17
+ require_relative 'cache_box/graph'
9
18
 
10
19
  class CacheBox
20
+ include CacheBox::Helper::Validate
21
+
11
22
  # Input:
12
23
  #
13
- # namespace = String | Symbol # Default: 'namespace'
24
+ # namespace = String | Symbol # Default: :namespace
25
+ # logger = Logger
26
+ # storage = CacheBox::Storage::*
14
27
  #
15
28
  # Output: N/A
16
29
  def initialize(namespace = nil, logger: nil, storage: nil)
17
- validate_symbol_or_string!(namespace, 'namespace')
30
+ namespace ||= :namespace
31
+ validate_string_or_symbol!(namespace, 'namespace')
18
32
 
19
- @namespace = namespace&.to_s || 'namespace'
20
- @logger = logger || Logger.new(STDOUT, level: Logger::INFO)
21
- @storage = storage || FileStorage.new(namespace: @namespace)
22
- @state = { result: {}, stash: {} }
33
+ @unit = ::CacheBox::Unit.new(namespace, logger: logger, storage: storage)
23
34
  end
24
35
 
25
36
  # Input:
26
37
  #
27
38
  # name = String | Symbol # Default: 'name'
28
- # args = Array[...Object]
29
- # &block = Proc(Hash{...Object => Object}, *args)
39
+ # args = Object
40
+ # &block = Proc(CacheBox::Box)
30
41
  #
31
42
  # Output: Object # Anything the &block returns.
32
- def with(name = nil, *args)
33
- validate_symbol_or_string!(name, 'name')
34
- unless block_given?
35
- raise(ArgumentError, 'The `:with` method requires a block')
36
- end
37
-
38
- name = name&.to_s || 'name'
39
- return @state[:result][name] if @state[:result].key?(name)
40
-
41
- data = @storage.read!(name)
42
- if data&.key?(:result)
43
- @state[:result][name] = data[:result]
44
-
45
- return data[:result]
46
- elsif data&.key?(:stash)
47
- @state[:stash][name] = data[:stash]
48
- end
49
-
50
- stash = @state[:stash][name] || {}
51
- begin
52
- @state[:result][name] = yield(stash, *args)
53
- ensure
54
- if @state[:result].key?(name)
55
- @state[:stash].delete(name)
56
- @storage.write!(name, { result: @state[:result][name] })
57
- else
58
- @state[:stash][name] = stash
59
- @storage.write!(name, { stash: stash })
60
- end
61
- end
43
+ def with(name = nil, args = nil, &block)
44
+ name ||= 'name'
45
+ validate_string_or_symbol!(name, 'name')
46
+ validate_block_presence!(block, '#with')
47
+
48
+ @unit.with(name, args, nil, &block)
62
49
  end
63
50
 
64
51
  # Input:
@@ -67,20 +54,10 @@ class CacheBox
67
54
  #
68
55
  # Output: true | false
69
56
  def has?(name = nil)
70
- validate_symbol_or_string!(name, 'name')
71
-
72
- name = name&.to_s || 'name'
73
- return true if @state[:result].key?(name)
57
+ name ||= 'name'
58
+ validate_string_or_symbol!(name, 'name')
74
59
 
75
- data = @storage.read!(name)
76
-
77
- if data&.key?(:result)
78
- @state[:result][name] = data[:result]
79
- elsif data&.key?(:stash)
80
- @state[:stash][name] = data[:stash]
81
- end
82
-
83
- @state[:result].key?(name)
60
+ @unit.has?(name)
84
61
  end
85
62
 
86
63
  # Input:
@@ -89,59 +66,10 @@ class CacheBox
89
66
  #
90
67
  # Output: self
91
68
  def expire!(*names)
92
- validate_array_of_symbol_or_string!(names, 'names')
93
-
94
- if names.empty?
95
- @state = { result: {}, stash: {} }
69
+ validate_array_of_string_or_symbol!(names, 'names')
96
70
 
97
- @storage.reset!
98
- else
99
- names.each do |name|
100
- name = name.to_s
101
- @state[:result].delete(name)
102
- @state[:stash].delete(name)
103
-
104
- @storage.delete!(name)
105
- end
106
- end
71
+ @unit.expire!(*names)
107
72
 
108
73
  self
109
74
  end
110
-
111
- private
112
-
113
- # Input:
114
- #
115
- # arg = String | Symbol
116
- # name = String
117
- #
118
- # Output: N/A
119
- def validate_symbol_or_string!(arg, name)
120
- return if arg.nil? || arg.is_a?(Symbol) || arg.is_a?(String)
121
-
122
- klass = arg.class
123
- value = arg.inspect
124
-
125
- raise(ArgumentError, "#{name} must be a Symbol or String, got #{klass}: #{value}")
126
- end
127
-
128
- # Input:
129
- #
130
- # arg = Array[String | Symbol]
131
- # name = String
132
- #
133
- # Output: N/A
134
- def validate_array_of_symbol_or_string!(args, name)
135
- args.each do |arg|
136
- next if arg.is_a?(Symbol) || arg.is_a?(String)
137
-
138
- klass = arg.class
139
- value = arg.inspect
140
-
141
- raise(
142
- ArgumentError,
143
- "#{name} must each be Symbol or String, got #{klass}: #{value} in #{args}"
144
- )
145
- end
146
- end
147
75
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ # A container for references needed during execution.
5
+ class Box
6
+ attr_reader :namespace, :name, :args, :input, :stash, :logger
7
+
8
+ def initialize(namespace:, name:, args:, input:, stash:, logger:)
9
+ @namespace = namespace
10
+ @name = name
11
+ @args = args
12
+ @input = input
13
+ @stash = stash
14
+ @logger = logger
15
+ end
16
+ end
17
+ end
@@ -2,43 +2,52 @@
2
2
 
3
3
  class CacheBox
4
4
  class Chain
5
+ include CacheBox::Helper::Validate
6
+
5
7
  # Input:
6
8
  #
7
9
  # namespace = String | Symbol # Default: 'namespace'
8
10
  #
9
11
  # Output: N/A
10
12
  def initialize(namespace = nil, logger: nil, storage: nil)
11
- namespace ||= 'namespace'
12
- logger ||= Logger.new(STDOUT, level: Logger::INFO)
13
- storage ||= FileStorage.new(namespace: namespace)
13
+ namespace ||= :namespace
14
+ validate_string_or_symbol!(namespace, 'namespace')
15
+
16
+ logger ||= Logger.new(STDOUT, level: Logger::INFO)
17
+ storage ||= ::CacheBox::Storage::File.new(namespace: namespace)
18
+
19
+ @unit = ::CacheBox::Unit.new(namespace, logger: logger, storage: storage)
20
+ @chain = []
21
+ @lookup = Set.new
14
22
 
15
- @cache = ::CacheBox.new(namespace, logger: logger, storage: storage)
16
- @chain = []
17
- @set = Set.new
23
+ @namespace = namespace
24
+ @logger = logger
18
25
  end
19
26
 
20
27
  # Input:
21
28
  #
22
29
  # name = String | Symbol
23
- # args = Array[...Object]
30
+ # input = Object # Default: nil
24
31
  # &block = Proc(Hash{...Object => Object}, *args)
25
32
  #
26
33
  # Output: self
27
- def add(name, *args, &block)
28
- validate_add!(name, &block)
34
+ def add(name, args = nil, &block)
35
+ validate_string_or_symbol!(name, 'name')
36
+ validate_block_presence!(block, '#add')
29
37
 
30
- string_name = name.to_s
31
- if @set.include?(string_name)
38
+ name_o = name
39
+ name_s = name.to_s
40
+ if @lookup.include?(name_s)
32
41
  raise(
33
42
  ArgumentError,
34
- "Chain already contains a step named #{name.inspect}"
43
+ "Chain already contains a step named #{name_o.inspect}"
35
44
  )
36
45
  else
37
- @set << string_name
46
+ @lookup << name_s
38
47
  end
39
48
 
40
49
  @chain.push(
41
- [name, args, proc { |*all| @cache.with(string_name, *all, &block) }]
50
+ [name_o, proc { |input| @unit.with(name_s, args, input, &block) }]
42
51
  )
43
52
 
44
53
  self
@@ -48,19 +57,19 @@ class CacheBox
48
57
  def run!
49
58
  work = []
50
59
 
51
- @chain.reverse_each do |name, args, callable|
52
- work.push([name, args, callable])
60
+ @chain.reverse_each do |name, callable|
61
+ work.push([name, callable])
53
62
 
54
- break if @cache.has?(name)
63
+ break if @unit.has?(name)
55
64
  end
56
65
 
57
- result = nil
58
- work.reverse_each do |_name, args, callable|
59
- input = []
60
- input << result if result
61
- input += args if args
66
+ result = nil
67
+ previous = nil
68
+ work.reverse_each do |name, callable|
69
+ result = callable.call(result)
62
70
 
63
- result = callable.call(*input)
71
+ @unit.clear(previous) if previous
72
+ previous = name
64
73
  end
65
74
 
66
75
  result
@@ -72,33 +81,10 @@ class CacheBox
72
81
  #
73
82
  # Output: self
74
83
  def expire!(*names)
75
- @cache.expire!(*names)
84
+ validate_array_of_string_or_symbol!(names, 'names')
85
+ @unit.expire!(*names)
76
86
 
77
87
  self
78
88
  end
79
-
80
- private
81
-
82
- # Input:
83
- #
84
- # name = String | Symbol
85
- # &block = Proc
86
- #
87
- # Output: N/A
88
- def validate_add!(name, &block)
89
- unless name.is_a?(Symbol) || name.is_a?(String)
90
- klass = name.class
91
- value = name.inspect
92
-
93
- raise(
94
- ArgumentError,
95
- "name must be a Symbol or String, got #{klass}: #{value}"
96
- )
97
- end
98
-
99
- return unless block.nil?
100
-
101
- raise(ArgumentError, 'The `:add` method requires a block')
102
- end
103
89
  end
104
90
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ class Graph
5
+ include CacheBox::Helper::Validate
6
+
7
+ # Input:
8
+ #
9
+ # namespace = String | Symbol # Default: 'namespace'
10
+ # scheduler = CacheBox::Scheduler::*
11
+ # storage = CacheBox::Storage::*
12
+ # logger = Logger
13
+ #
14
+ # Output: N/A
15
+ def initialize(namespace = nil, scheduler: nil, storage: nil, logger: nil)
16
+ namespace ||= :namespace
17
+ validate_string_or_symbol!(namespace, 'namespace')
18
+
19
+ @namespace = namespace
20
+ @logger = logger || Logger.new(STDOUT, level: Logger::INFO)
21
+ @storage = storage || ::CacheBox::Storage::File.new(namespace: @namespace)
22
+ @scheduler = scheduler || ::CacheBox::Scheduler::Serial.new(logger: @logger)
23
+ @unit = ::CacheBox::Unit.new(@namespace, logger: @logger, storage: @storage)
24
+
25
+ @nodes = {}
26
+ end
27
+
28
+ # Input:
29
+ #
30
+ # edge = String |
31
+ # Symbol |
32
+ # Hash{String | Symbol => String | Symbol | Array[String | Symbol]}
33
+ # args = Object
34
+ # &block = Proc(Hash{...Object => Object}, *args)
35
+ #
36
+ # Output: self
37
+ def node(edge, args = nil, &block)
38
+ validate_edge!(edge)
39
+ validate_block_presence!(block, '#node')
40
+
41
+ @scheduler.add(edge)
42
+ name_o = extract_name(edge)
43
+ name_s = name_o.to_s
44
+
45
+ @nodes[name_s] = [
46
+ name_o,
47
+ proc { |input| @unit.with(name_s, args, input, &block) }
48
+ ]
49
+
50
+ self
51
+ end
52
+
53
+ # Input: N/A
54
+ #
55
+ # Output: Object # Anything the last block in the chain returns.
56
+ def run!
57
+ @scheduler.run!(@nodes, @unit)
58
+ end
59
+
60
+ # Input:
61
+ #
62
+ # name = Array[String | Symbol] # Default: []
63
+ #
64
+ # Output: self
65
+ def expire!(*names)
66
+ validate_array_of_string_or_symbol!(names, 'names')
67
+ @unit.expire!(*names)
68
+
69
+ self
70
+ end
71
+
72
+ private
73
+
74
+ # Input:
75
+ #
76
+ # edge = String |
77
+ # Symbol |
78
+ # Hash{String | Symbol => String | Symbol | Array[String | Symbol]}
79
+ #
80
+ # Output: String
81
+ def extract_name(edge)
82
+ return edge.to_s if edge.is_a?(Symbol) || edge.is_a?(String)
83
+
84
+ edge.keys.first.to_s
85
+ end
86
+ end
87
+ end