caches 0.0.4 → 0.0.5

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
  SHA1:
3
- metadata.gz: 89ecbca50c8eeca4f3a3ba844fc8af31051e0aca
4
- data.tar.gz: 7bb00ffe94dd6f21767037d14217223e7f4bad86
3
+ metadata.gz: c9e78a1f8363d6a34aa3ecfcf301b2bc1390ade2
4
+ data.tar.gz: 3cb95979ea3b0c416029e2b0791558b48c190b1f
5
5
  SHA512:
6
- metadata.gz: afa402ae0b268873414fbd05f13a9c1d15982272523ab3e70d6badd37b6d05d03bf5054e774e1f17cfee93317460839018766fd76b7d8eb286b118821acfaadd
7
- data.tar.gz: 36e84e288dc638a1c0b184136965fba84b737d243d81f334a0feddd356c95d3fb16631336bed1b0770ed76e29635e5d34390418ffa57fa7846083b1b4c6c594c
6
+ metadata.gz: 413dc61d9667e5825611409ec0a3b2d1abd8b20f3c93128440ab1a5226755ae331093a18e32d478255c25e5b94430912c566b8d25fbfcf7d9ccc75bbf68a3a9e
7
+ data.tar.gz: 3e11bc28feb7a34b4a782c4020b7ee61c7e73113636f74c4146ba686a1722f8265af2347c80aebb68483cecc0f20139fbd7eec7adf1a86b2c424740d851f3565
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## Unreleased
5
+
6
+ - Nothing
7
+
8
+ ## 0.0.5 - 2015-03-09
9
+
10
+ ### Added
11
+
12
+ - `Caches::TTL` and `Caches::LRU` support `#stats`, which gives counts of how many cache hits and misses have occurred
13
+
4
14
  ## 0.0.4 - 2015-03-03
5
15
 
6
16
  ### Added
@@ -10,12 +20,6 @@ All notable changes to this project will be documented in this file.
10
20
  - Benchmarking with Ruby 2.1.3
11
21
  - `Caches::LRU` can handle `max_keys: 0`
12
22
 
13
- ### Changed
14
- Nothing
15
-
16
- ### Removed
17
- Nothing
18
-
19
23
  ## 0.0.3 - 2014-08-22
20
24
 
21
25
  Currently have `Caches::TTL` and `Caches::LRU`
data/README.md CHANGED
@@ -61,6 +61,12 @@ h[:d] = "dingo"
61
61
  puts h[:a] # => nil
62
62
  ```
63
63
 
64
+ ## Methods Common to All Caches
65
+
66
+ - `stats` tells how many cache hits and misses have occurred
67
+ - `fetch` works like `Hash#fetch`
68
+ - `memoize` returns the key's value, if any; if not, it gets its return value from the block, and sets the key before it returns
69
+
64
70
  ## Installation
65
71
 
66
72
  Add this line to your application's Gemfile:
@@ -2,7 +2,8 @@ module Caches
2
2
  module Accessible
3
3
 
4
4
  def fetch(key, default = (default_omitted = true; nil))
5
- return self[key] if data.has_key?(key)
5
+ value = self[key]
6
+ return value if data.has_key?(key)
6
7
  return yield(key) if block_given?
7
8
  return default unless default_omitted
8
9
  raise KeyError
@@ -10,8 +11,8 @@ module Caches
10
11
 
11
12
  def memoize(key)
12
13
  raise ArgumentError, "Block is required" unless block_given?
13
- self[key] # triggers flush or refresh if expired
14
- return self[key] if data.has_key?(key)
14
+ value = self[key]
15
+ return value if data.has_key?(key)
15
16
  self[key] = yield(key) if block_given?
16
17
  end
17
18
 
data/lib/caches/lru.rb CHANGED
@@ -1,20 +1,29 @@
1
1
  require_relative 'accessible'
2
2
  require_relative 'linked_list'
3
+ require_relative 'stats'
3
4
 
4
5
  module Caches
5
6
  class LRU
6
7
  include Accessible
8
+ prepend Stats
7
9
  attr_accessor :max_keys
8
10
 
11
+ attr_accessor :keys, :data
12
+ private :keys, :data
13
+
9
14
  def initialize(options = {})
10
15
  self.max_keys = options.fetch(:max_keys, 20)
11
16
  self.data = {}
12
- self.keys = LinkedList.new
17
+ self.keys = LinkedList.new
13
18
  end
14
19
 
15
20
  def [](key)
16
21
  return nil if max_keys.zero?
17
- return nil unless data.has_key?(key)
22
+ unless data.has_key?(key)
23
+ record_cache_miss
24
+ return nil
25
+ end
26
+ record_cache_hit
18
27
  value, node = data[key]
19
28
  keys.move_to_head(node)
20
29
  value
@@ -37,7 +46,6 @@ module Caches
37
46
  end
38
47
 
39
48
  private
40
- attr_accessor :keys, :data
41
49
 
42
50
  def prune
43
51
  return unless keys.length > max_keys
@@ -0,0 +1,25 @@
1
+ module Caches
2
+ module Stats
3
+
4
+ def initialize(*args)
5
+ @hits = 0
6
+ @misses = 0
7
+ super
8
+ end
9
+
10
+ def stats
11
+ {hits: @hits, misses: @misses}
12
+ end
13
+
14
+ private
15
+
16
+ def record_cache_hit
17
+ @hits += 1
18
+ end
19
+
20
+ def record_cache_miss
21
+ @misses += 1
22
+ end
23
+
24
+ end
25
+ end
data/lib/caches/ttl.rb CHANGED
@@ -1,12 +1,17 @@
1
1
  require 'time'
2
2
  require_relative 'accessible'
3
3
  require_relative 'linked_list'
4
+ require_relative 'stats'
4
5
 
5
6
  module Caches
6
7
  class TTL
7
8
  include Accessible
9
+ prepend Stats
8
10
  attr_accessor :ttl, :refresh
9
11
 
12
+ attr_accessor :data, :nodes, :max_keys
13
+ private :data, :nodes, :max_keys
14
+
10
15
  def initialize(options = {})
11
16
  self.ttl = options.fetch(:ttl) { 3600 }
12
17
  self.refresh = !!(options.fetch(:refresh, false))
@@ -16,12 +21,17 @@ module Caches
16
21
  end
17
22
 
18
23
  def [](key)
19
- return nil unless data.has_key?(key)
24
+ unless data.has_key?(key)
25
+ record_cache_miss
26
+ return nil
27
+ end
20
28
  if current?(key)
29
+ record_cache_hit
21
30
  data[key][:value].tap {
22
31
  data[key][:time] = current_time if refresh
23
32
  }
24
33
  else
34
+ record_cache_miss
25
35
  delete(key)
26
36
  nil
27
37
  end
@@ -74,8 +84,6 @@ module Caches
74
84
  max_keys && size >= max_keys
75
85
  end
76
86
 
77
- attr_accessor :data, :nodes, :max_keys
78
-
79
87
  def current_time
80
88
  Time.now
81
89
  end
@@ -1,3 +1,3 @@
1
1
  module Caches
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -123,5 +123,16 @@ describe Caches::LRU do
123
123
 
124
124
  end
125
125
 
126
+ describe "stats" do
127
+
128
+ it "can report hits and misses" do
129
+ cache[:a]
130
+ cache[:b]
131
+ cache[:nope]
132
+ expect(cache.stats).to eq(hits: 2, misses: 1)
133
+ end
134
+
135
+ end
136
+
126
137
  end
127
138
 
@@ -222,4 +222,15 @@ describe Caches::TTL do
222
222
 
223
223
  end
224
224
 
225
+ describe "stats" do
226
+
227
+ it "can report hits and misses" do
228
+ cache[:a]
229
+ cache[:b]
230
+ cache[:nope]
231
+ expect(cache.stats).to eq(hits: 2, misses: 1)
232
+ end
233
+
234
+ end
235
+
225
236
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caches
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Long
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-03 00:00:00.000000000 Z
11
+ date: 2015-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,6 +88,7 @@ files:
88
88
  - lib/caches/all.rb
89
89
  - lib/caches/linked_list.rb
90
90
  - lib/caches/lru.rb
91
+ - lib/caches/stats.rb
91
92
  - lib/caches/ttl.rb
92
93
  - lib/caches/version.rb
93
94
  - spec/benchmark_spec.rb