sinarey_cache 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 563d5fbcebdf35c800e8fb4ab1c763e71bbe95ee
4
+ data.tar.gz: 58be4d2cdac9bbd3cb380111963996dfac9d8ca4
5
+ SHA512:
6
+ metadata.gz: 0b131394f6b7356ae86224ce6b0d08a1f005861045a176f9f7886ada5e7e313ff438cd96b89b579e05e409efc8f62a9958fa265157e5444fb86afb336f99b97e
7
+ data.tar.gz: 1ef6d9564726f27767aae31499a2cd95144f1e2529feb3f9bf6f67a91c72f4feb166743f2425978532ff63bd44905af613b0ffeeaa4e282fd16f7c0fae4ecf69
@@ -0,0 +1,47 @@
1
+ module Sinarey
2
+ class FifoCache
3
+
4
+ def initialize(max_size)
5
+ @max_size = max_size
6
+ @data = {}
7
+ end
8
+
9
+ def max_size=(size)
10
+ raise ArgumentError.new(:max_size) if @max_size < 1
11
+ @max_size = size
12
+ end
13
+
14
+ def [](key)
15
+ @data[key]
16
+ end
17
+
18
+ def fetch(key)
19
+ @data[key] || yield if block_given?
20
+ end
21
+
22
+ def getset(key)
23
+ @data[key] ||= yield
24
+ end
25
+
26
+ def []=(key,val)
27
+ @data[key] = val
28
+ @data.delete(@data.first[0]) if @data.length > @max_size
29
+ val
30
+ end
31
+
32
+ alias_method :store,:[]=
33
+
34
+ def member?(key)
35
+ @data.member?(key)
36
+ end
37
+
38
+ def delete(key)
39
+ @data.delete(key)
40
+ end
41
+
42
+ def clear
43
+ @data.clear
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,91 @@
1
+ module Sinarey
2
+ class LruCache
3
+ def initialize(max_size)
4
+ @max_size = max_size
5
+ @data = {}
6
+ end
7
+
8
+ def max_size=(size)
9
+ raise ArgumentError.new(:max_size) if @max_size < 1
10
+ @max_size = size
11
+ if @max_size < @data.size
12
+ @data.keys[0..@max_size-@data.size].each do |k|
13
+ @data.delete(k)
14
+ end
15
+ end
16
+ end
17
+
18
+ def getset(key)
19
+ found = true
20
+ value = @data.delete(key){ found = false }
21
+ if found
22
+ @data[key] = value
23
+ else
24
+ result = @data[key] = yield
25
+ @data.delete(@data.first[0]) if @data.length > @max_size
26
+ result
27
+ end
28
+ end
29
+
30
+ def fetch(key)
31
+ found = true
32
+ value = @data.delete(key){ found = false }
33
+ if found
34
+ @data[key] = value
35
+ else
36
+ yield if block_given?
37
+ end
38
+ end
39
+
40
+ def [](key)
41
+ found = true
42
+ value = @data.delete(key){ found = false }
43
+ if found
44
+ @data[key] = value
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def []=(key,val)
51
+ @data.delete(key)
52
+ @data[key] = val
53
+ # this may seem odd see: http://bugs.ruby-lang.org/issues/8312
54
+ @data.delete(@data.first[0]) if @data.length > @max_size
55
+ val
56
+ end
57
+
58
+ def each
59
+ array = @data.to_a
60
+ array.reverse!.each do |pair|
61
+ yield pair
62
+ end
63
+ end
64
+
65
+ # used further up the chain, non thread safe each
66
+ alias_method :each_unsafe, :each
67
+
68
+ def to_a
69
+ array = @data.to_a
70
+ array.reverse!
71
+ end
72
+
73
+ def delete(k)
74
+ @data.delete(k)
75
+ end
76
+
77
+ def clear
78
+ @data.clear
79
+ end
80
+
81
+ def count
82
+ @data.count
83
+ end
84
+
85
+
86
+ # for cache validation only, ensures all is sound
87
+ def valid?
88
+ true
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,91 @@
1
+ module Sinarey
2
+ class LruCache
3
+ def initialize(max_size)
4
+ @max_size = max_size
5
+ @data = {}
6
+ end
7
+
8
+ def max_size=(size)
9
+ raise ArgumentError.new(:max_size) if @max_size < 1
10
+ @max_size = size
11
+ if @max_size < @data.size
12
+ @data.keys[0..@max_size-@data.size].each do |k|
13
+ @data.delete(k)
14
+ end
15
+ end
16
+ end
17
+
18
+ def getset(key)
19
+ found = true
20
+ value = @data.delete(key){ found = false }
21
+ if found
22
+ @data[key] = value
23
+ else
24
+ result = @data[key] = yield
25
+ @data.delete(@data.first[0]) if @data.length > @max_size
26
+ result
27
+ end
28
+ end
29
+
30
+ def fetch(key)
31
+ found = true
32
+ value = @data.delete(key){ found = false }
33
+ if found
34
+ @data[key] = value
35
+ else
36
+ yield if block_given?
37
+ end
38
+ end
39
+
40
+ def [](key)
41
+ found = true
42
+ value = @data.delete(key){ found = false }
43
+ if found
44
+ @data[key] = value
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def []=(key,val)
51
+ @data.delete(key)
52
+ @data[key] = val
53
+ # this may seem odd see: http://bugs.ruby-lang.org/issues/8312
54
+ @data.delete(@data.first[0]) if @data.length > @max_size
55
+ val
56
+ end
57
+
58
+ def each
59
+ array = @data.to_a
60
+ array.reverse!.each do |pair|
61
+ yield pair
62
+ end
63
+ end
64
+
65
+ # used further up the chain, non thread safe each
66
+ alias_method :each_unsafe, :each
67
+
68
+ def to_a
69
+ array = @data.to_a
70
+ array.reverse!
71
+ end
72
+
73
+ def delete(k)
74
+ @data.delete(k)
75
+ end
76
+
77
+ def clear
78
+ @data.clear
79
+ end
80
+
81
+ def count
82
+ @data.count
83
+ end
84
+
85
+
86
+ # for cache validation only, ensures all is sound
87
+ def valid?
88
+ true
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module SinareyCache
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,75 @@
1
+
2
+ require 'sinarey_cache/fifo/cache'
3
+
4
+ major,minor = RUBY_VERSION.split(".").map{|a| a.to_i}
5
+ if major > 1 || (major == 1 && minor > 8)
6
+ require "sinarey_cache/lru_redux/cache19"
7
+ else
8
+ require "sinarey_cache/lru_redux/cache"
9
+ end
10
+
11
+ module Sinarey
12
+ class SmartCache
13
+
14
+ def initialize(data_size,fifo_size)
15
+ @fifo = Sinarey::FifoCache.new(fifo_size)
16
+ @data = Sinarey::LruCache.new(data_size)
17
+ end
18
+
19
+ def [](key)
20
+ @data[key]
21
+ end
22
+
23
+ def fetch(key)
24
+ if cache = @data[key]
25
+ return cache
26
+ else
27
+ yield if block_given?
28
+ end
29
+ end
30
+
31
+ def []=(key,val,options={})
32
+ return @data[key] = val if options[:force]
33
+ val,version = val,options[:uuid]
34
+ if @fifo.member?(key)
35
+ if version.nil?
36
+ @data[key] = val
37
+ elsif version!= @fifo[key]
38
+ @fifo[key] = version
39
+ @data[key] = val
40
+ end
41
+ else
42
+ @fifo[key] = version
43
+ end
44
+ val
45
+ end
46
+
47
+ alias_method :store,:[]=
48
+
49
+ def getset(key,options={})
50
+ if cache = @data[key]
51
+ return cache
52
+ else
53
+ store(key,yield,options) if block_given?
54
+ end
55
+ end
56
+
57
+ def count
58
+ @data.count
59
+ end
60
+
61
+ def delete(k)
62
+ @fifo.delete(k)
63
+ @data.delete(k)
64
+ end
65
+
66
+ def clear
67
+ @fifo.clear
68
+ @data.clear
69
+ end
70
+
71
+ end
72
+ end
73
+
74
+
75
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sinarey_cache/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sinarey_cache"
8
+ spec.version = SinareyCache::VERSION
9
+ spec.authors = ["Jeffrey"]
10
+ spec.email = ["jeffrey6052@163.com"]
11
+ spec.description = "smart and fast cache"
12
+ spec.summary = ""
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = ['lib/sinarey_cache/fifo/cache.rb',
17
+ 'lib/sinarey_cache/lru_redux/cache.rb',
18
+ 'lib/sinarey_cache/lru_redux/cache19.rb',
19
+ 'lib/sinarey_cache/version.rb',
20
+ 'lib/sinarey_cache.rb',
21
+ 'test/smart_cache_test.rb',
22
+ 'sinarey_cache.gemspec']
23
+ end
@@ -0,0 +1,116 @@
1
+
2
+ $:.unshift File.expand_path("../lib", __dir__)
3
+
4
+ require 'sinarey_cache'
5
+ require 'minitest/autorun'
6
+
7
+ ObjectCache = Sinarey::SmartCache.new(100,100)
8
+
9
+ # MARK 实例方法 []= , store , [], fetch , getset , delete , count , clear
10
+
11
+ class SmartCacheTest < MiniTest::Unit::TestCase
12
+
13
+ def setup
14
+ @object = {id:1, msg:'this is the object for test', name:'object'}
15
+ @object1 = {id:2, msg:'I need some more object for test', name:'object1'}
16
+ @object2 = {id:3, msg:'hahahahaha', name:'object2'}
17
+ end
18
+
19
+ #基本测试 [] , []= , store , fetch, count , delete , clear
20
+ def test_basic
21
+
22
+ obj_id = @object[:id]
23
+
24
+ #第一次不会缓存,只在FIFO队列里留下标记
25
+ ObjectCache[obj_id] = @object
26
+ assert_equal ObjectCache[obj_id], nil
27
+ assert_equal ObjectCache.fetch(obj_id), nil
28
+ assert_equal ObjectCache.count, 0
29
+
30
+ #fetch方法,获取不到内容的时候会取后面block返回值
31
+ #这个方法不会缓存block返回值,另一个getset方法会,并且遵循缓存规则。
32
+ assert_equal ObjectCache.fetch(obj_id), nil
33
+ assert_equal ObjectCache.fetch(obj_id){123}, 123
34
+ assert_equal ObjectCache.count, 0
35
+
36
+ #第二次会缓存,因为FIFO队列里已经有标记
37
+ ObjectCache[obj_id] = @object
38
+ assert_equal ObjectCache[obj_id], @object
39
+ assert_equal ObjectCache.fetch(obj_id), @object
40
+ assert_equal ObjectCache.count, 1
41
+
42
+ #fetch方法,有缓存的情况下返回缓存内容
43
+ assert_equal ObjectCache.fetch(obj_id), @object
44
+ assert_equal ObjectCache.fetch(obj_id){123}, @object
45
+ assert_equal ObjectCache.count, 1
46
+
47
+ #delete方法 同时清除FIFO队列里的标记
48
+ ObjectCache.delete(obj_id)
49
+ assert_equal ObjectCache[obj_id], nil
50
+ assert_equal ObjectCache.fetch(obj_id), nil
51
+
52
+ #按照缓存规则 这一次缓存不会真正建立
53
+ ObjectCache[obj_id] = @object
54
+ assert_equal ObjectCache[obj_id], nil
55
+ assert_equal ObjectCache.fetch(obj_id), nil
56
+
57
+ #第二次缓存顺利建立
58
+ ObjectCache[obj_id] = @object
59
+ assert_equal ObjectCache[obj_id], @object
60
+ assert_equal ObjectCache.fetch(obj_id), @object
61
+
62
+ #store方法等价于[]=方法
63
+ ObjectCache.store @object1[:id], @object1
64
+ #按照规则,需要连写两遍,才能成功缓存
65
+ ObjectCache.store @object1[:id], @object1
66
+
67
+ #调用store方法,可以添加force选项,绕过规则,强制缓存
68
+ ObjectCache.store @object2[:id], @object2, force:true
69
+
70
+ #现在应该有3个缓存
71
+ assert_equal ObjectCache.count, 3
72
+
73
+ #测试clear方法,清空所有缓存和FIFO标记
74
+ ObjectCache.clear
75
+ assert_equal ObjectCache.count, 0
76
+
77
+ end
78
+
79
+ #测试getset方法 这个方法类似于fetch方法,不同的是,会缓存block的返回值,遵循缓存规则
80
+ def test_getset_method
81
+ obj_id = @object[:id]
82
+
83
+ assert_equal ObjectCache.count, 0
84
+
85
+ ObjectCache.getset(obj_id){ @object }
86
+ #按照规则这一次缓存也不会建立
87
+ assert_equal ObjectCache[obj_id], nil
88
+
89
+ ObjectCache.getset(obj_id){ @object }
90
+ #这一次建立成功
91
+ assert_equal ObjectCache[obj_id], @object
92
+
93
+ #同样可以通过force绕过规则强制缓存
94
+ ObjectCache.getset(@object1[:id],force:true){ @object1 }
95
+ assert_equal ObjectCache[@object1[:id]], @object1
96
+
97
+ ObjectCache.getset(@object2[:id],force:true){ @object2 }
98
+ assert_equal ObjectCache[@object2[:id]], @object2
99
+
100
+
101
+ end
102
+
103
+
104
+ #同一个用户不可以创建缓存
105
+ def test_uuid_options
106
+
107
+ end
108
+
109
+ #可以绕过规则强制建立缓存
110
+ def test_force_options
111
+
112
+ end
113
+
114
+ end
115
+
116
+
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinarey_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jeffrey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: smart and fast cache
14
+ email:
15
+ - jeffrey6052@163.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/sinarey_cache/fifo/cache.rb
21
+ - lib/sinarey_cache/lru_redux/cache.rb
22
+ - lib/sinarey_cache/lru_redux/cache19.rb
23
+ - lib/sinarey_cache/version.rb
24
+ - lib/sinarey_cache.rb
25
+ - test/smart_cache_test.rb
26
+ - sinarey_cache.gemspec
27
+ homepage: ''
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.0.14
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: ''
51
+ test_files: []