libcache 0.2.1 → 0.3
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 +4 -4
- data/Gemfile +2 -1
- data/lib/libcache/cache.rb +27 -4
- data/lib/libcache/cache_builder.rb +10 -0
- data/lib/libcache/file_cache.rb +20 -2
- data/lib/libcache/version.rb +1 -1
- data/lib/libcache.rb +3 -4
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1745f8dfa5166c285d38f5a9303350590e1aae2f
|
4
|
+
data.tar.gz: e54f0dabd6ac9874078e89494d3ff32a3b79e53a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0bd90c60a77bfed598db5f7a707fb15fa9c06cf290d320fa44b6a2d7025fba30cfd87bddb65ed92ada94b95c1147872321da4f52f8029a13b63123dffd29a69
|
7
|
+
data.tar.gz: e065672af43bb05078e505a1469ec6c440edee36650156d7718c9d4a4d54c995322de8e657830bb6010f6659913dffbfae5ae8a658dc430f561e612427bf7dce
|
data/Gemfile
CHANGED
data/lib/libcache/cache.rb
CHANGED
@@ -5,20 +5,25 @@ class Cache
|
|
5
5
|
|
6
6
|
attr_accessor :expiry_time, :refresh, :store, :max_size
|
7
7
|
|
8
|
+
# Creates a basic Cache with the UTC timezone
|
8
9
|
def initialize
|
9
10
|
ENV['TZ'] = 'UTC'
|
10
11
|
@scheduler = Rufus::Scheduler.new
|
11
12
|
@time_tracker = Hash.new
|
12
13
|
end
|
13
14
|
|
15
|
+
# Initializes the cache store
|
14
16
|
def create_store
|
15
17
|
@cache = Hash.new
|
16
18
|
end
|
17
19
|
|
20
|
+
# Places an object inside the cache and handles max size eviction
|
21
|
+
# @param [String] key The key value used to identify an object in the cache
|
22
|
+
# @param [Object] value The object to be placed in the cache
|
18
23
|
def put(key, value)
|
19
24
|
# removed oldest entry if max_size is approached
|
20
25
|
if max_size != nil
|
21
|
-
if @cache.size >= max_size
|
26
|
+
if @cache.size >= max_size - 1
|
22
27
|
key, value = @time_tracker.values.sort {|v| Time.now - v }.reverse.first
|
23
28
|
invalidate(key)
|
24
29
|
@time_tracker.delete(key)
|
@@ -26,21 +31,31 @@ class Cache
|
|
26
31
|
@time_tracker[key] = Time.now
|
27
32
|
end
|
28
33
|
@cache[key] = value
|
29
|
-
|
30
|
-
|
34
|
+
if expiry_time != nil
|
35
|
+
@scheduler.in expiry_time, :blocking => true do
|
36
|
+
invalidate key
|
37
|
+
end
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
41
|
+
# Gets the object that corresponds with the key
|
42
|
+
# @param [String] key The key value used to identify an object in the cache
|
43
|
+
# @return [Object] The object that corresponds with the key
|
34
44
|
def get(key)
|
35
45
|
check_refresh(key)
|
36
46
|
return @cache[key]
|
37
47
|
end
|
38
48
|
|
49
|
+
# Checks if a key-value pair exists in the cache
|
50
|
+
# @param [String] key The key value used to identify an object in the cache
|
51
|
+
# @return [Boolean] The existence of the key in the cache
|
39
52
|
def exists?(key)
|
40
53
|
return @cache.key?(key)
|
41
54
|
end
|
42
55
|
|
43
|
-
|
56
|
+
# Refreshes an object if it has been invalidated
|
57
|
+
# @param [String] key The key value used to identify an object in the cache
|
58
|
+
# @return [Object] The refreshed object that is recalled from the refresh method
|
44
59
|
def check_refresh(key)
|
45
60
|
if @cache[key] == nil && !has_refresh?
|
46
61
|
val = refresh.call(key)
|
@@ -49,14 +64,22 @@ class Cache
|
|
49
64
|
end
|
50
65
|
end
|
51
66
|
|
67
|
+
# @return [Boolean] Checks if the cache has a refresh method
|
52
68
|
def has_refresh?
|
53
69
|
return refresh == nil
|
54
70
|
end
|
55
71
|
|
72
|
+
def get_size
|
73
|
+
return @cache.size
|
74
|
+
end
|
75
|
+
|
76
|
+
# Deletes a key-value pair from the cache
|
77
|
+
# @param [String] key The key value used to identify an object in the cache
|
56
78
|
def invalidate(key)
|
57
79
|
@cache.delete key
|
58
80
|
end
|
59
81
|
|
82
|
+
# Clears all items in the cache
|
60
83
|
def invalidateAll
|
61
84
|
@cache.clear
|
62
85
|
end
|
@@ -2,34 +2,44 @@ require_relative 'cache'
|
|
2
2
|
|
3
3
|
class CacheBuilder
|
4
4
|
|
5
|
+
# @param [Cache] cache Initializes with the type of Cache to be used
|
5
6
|
def initialize(cache)
|
6
7
|
@cache = cache.new
|
7
8
|
end
|
8
9
|
|
10
|
+
# @param [Cache] cache Sets the type of Cache to be used
|
9
11
|
def self.with(cache)
|
10
12
|
return self.new(cache)
|
11
13
|
end
|
12
14
|
|
15
|
+
# Sets the required file path for the FileCache
|
16
|
+
# @param [String] path The path of the directory where cached files should be stored
|
13
17
|
def set_store(path)
|
14
18
|
@cache.store = path
|
15
19
|
return self
|
16
20
|
end
|
17
21
|
|
22
|
+
# @param [String] time The time value after which an object should expire in the cache. Can be written as '2s' for two seconds, for example. For more info see: https://github.com/jmettraux/rufus-scheduler/blob/two/README.rdoc#the-time-strings-understood-by-rufus-scheduler
|
18
23
|
def set_expiry(time)
|
19
24
|
@cache.expiry_time = time
|
20
25
|
return self
|
21
26
|
end
|
22
27
|
|
28
|
+
# Sets the refresh method required for recalling new objects after expiration
|
29
|
+
# @param [Proc] proc The refresh method as a Proc object
|
23
30
|
def set_refresh(proc)
|
24
31
|
@cache.refresh = proc
|
25
32
|
return self
|
26
33
|
end
|
27
34
|
|
35
|
+
# Sets the optional max size of a cache
|
36
|
+
# @param [Integer] max_size The max size of the cache
|
28
37
|
def set_max(max_size)
|
29
38
|
@cache.max_size = max_size
|
30
39
|
return self
|
31
40
|
end
|
32
41
|
|
42
|
+
# Returns the newly created cache
|
33
43
|
def build
|
34
44
|
@cache.create_store
|
35
45
|
return @cache.dup
|
data/lib/libcache/file_cache.rb
CHANGED
@@ -8,6 +8,7 @@ class FileCache < Cache
|
|
8
8
|
super
|
9
9
|
end
|
10
10
|
|
11
|
+
# Initializes the cache store along with the keys store. Raises an exception if the store path is not supplied.
|
11
12
|
def create_store
|
12
13
|
@cache = Hash.new
|
13
14
|
@keys = Hash.new
|
@@ -16,9 +17,19 @@ class FileCache < Cache
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
20
|
+
# Places an object inside the cache, and by extension, into the filesystem. Handles max size eviction. Raises an InvalidKey exception if the key is not formatted properly.
|
21
|
+
# @param [String] key The key value used to identify an object in the cache
|
22
|
+
# @param [Object] value The object to be placed in the cache
|
19
23
|
def put(key, value)
|
20
|
-
|
21
|
-
|
24
|
+
raise InvalidKey unless key.is_a? String
|
25
|
+
raise InvalidKey unless key =~ /\A[a-zA-Z0-9_-]+\z/
|
26
|
+
if max_size != nil
|
27
|
+
if @cache.size >= max_size - 1
|
28
|
+
key, value = @time_tracker.values.sort {|v| Time.now - v }.reverse.first
|
29
|
+
invalidate(key)
|
30
|
+
@time_tracker.delete(key)
|
31
|
+
end
|
32
|
+
@time_tracker[key] = Time.now
|
22
33
|
end
|
23
34
|
@keys[key] = Digest::MD5.hexdigest(key) + Time.now.to_i.to_s
|
24
35
|
@cache[key] = value
|
@@ -30,16 +41,23 @@ class FileCache < Cache
|
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
44
|
+
# Gets the object that corresponds with the key that is read from the filesystem
|
45
|
+
# @param [String] key The key value used to identify an object in the cache
|
46
|
+
# @return [Object] The object that corresponds with the key
|
33
47
|
def get(key)
|
34
48
|
refresh
|
35
49
|
return File.read(File.join(store, @keys[key]))
|
36
50
|
end
|
37
51
|
|
52
|
+
# Deletes a key-value pair from the cache and store directory
|
53
|
+
# @param [String] key The key value used to identify an object in the cache
|
38
54
|
def invalidate(key)
|
39
55
|
super
|
56
|
+
@keys.delete key
|
40
57
|
File.delete(File.join(store, @keys[key]))
|
41
58
|
end
|
42
59
|
|
60
|
+
# Clears all items in the cache and the cached files in the store directory
|
43
61
|
def invalidateAll
|
44
62
|
super
|
45
63
|
Dir.foreach(store) do |f|
|
data/lib/libcache/version.rb
CHANGED
data/lib/libcache.rb
CHANGED