libcache 0.2.1 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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