3d_cache 0.0.01a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/3d_cache.rb +32 -0
- data/lib/three_d/class_method_cache.rb +217 -0
- data/lib/three_d/model_fragments.rb +53 -0
- data/lib/three_d/once.rb +42 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f45725b17348a1882662ca8d39411362eea45a60
|
4
|
+
data.tar.gz: 722924ec576169736f54aaa44859a2e608fcd5cb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 480cfb10842db53c1fa0cf23bf544d16f599178739a76e68f1f6fb4234b0caf07a1d4895432647374f69acb9de677b602510024a63cab264439e0499e56bc4a7
|
7
|
+
data.tar.gz: 71c086fdcdaf2497a8ad422f3a72e2c3db2623476c0affcc35ce710eab17fcec7350ad7f97853d612da612e42c9e50e89f4497341a684d086cdbf90c826c4ce5
|
data/lib/3d_cache.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#= Loading Components
|
2
|
+
|
3
|
+
# Create Logger
|
4
|
+
ThreeDCachingLog = Logger.new(STDOUT)
|
5
|
+
|
6
|
+
#== ModelFragments
|
7
|
+
# add desc here
|
8
|
+
require "three_d/model_fragments"
|
9
|
+
ActiveRecord::Base.send(:include, ThreeD::ModelFragments)
|
10
|
+
ThreeDCachingLog.info "Loaded 3D::ModelFragments"
|
11
|
+
|
12
|
+
#== Once!
|
13
|
+
# Define which methods of a instance only should be computed once
|
14
|
+
require "three_d/once"
|
15
|
+
ActiveRecord::Base.send(:include, ThreeD::Once)
|
16
|
+
ThreeDCachingLog.info "Loaded 3D::Once!"
|
17
|
+
|
18
|
+
#== ClassMethodCache
|
19
|
+
# Not finished yet, memcache support required
|
20
|
+
# require "three_d/class_method_cache"
|
21
|
+
# ActiveRecord::Base.send(:include, ThreeD::ClassMethodCache)
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
# Fix the Cache File path so ist dont use crazy hashed file- and folder names
|
27
|
+
ActiveSupport::Cache::FileStore.module_eval do
|
28
|
+
def key_file_path(key)
|
29
|
+
File.join(cache_path, key.to_s) + '.cache'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
ThreeDCachingLog.info "Fixed ActiveSupport::Cache::FileStore#key_file_path"
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module ThreeD
|
3
|
+
module ClassMethodCache
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def activate_method_cache(methods_list = {})
|
13
|
+
|
14
|
+
if !self.method_cache_enabled?
|
15
|
+
|
16
|
+
cattr_accessor :cached_methods
|
17
|
+
cattr_accessor :cache_storage
|
18
|
+
|
19
|
+
# Setting up Cache Storage Variable
|
20
|
+
cache_storage_name = "$#{self.name.underscore.upcase}_METHOD_CACHE"
|
21
|
+
eval("#{cache_storage_name} = {}")
|
22
|
+
self.cache_storage = eval(cache_storage_name)
|
23
|
+
|
24
|
+
|
25
|
+
self.add_cache_methods(methods_list)
|
26
|
+
|
27
|
+
|
28
|
+
# Instanzmethoden für den User laden
|
29
|
+
self.send :include, InstanceMethods
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def add_cache_methods(methods_list = {})
|
36
|
+
# Check cached methods list
|
37
|
+
if methods_list.is_a?(Array)
|
38
|
+
methods_list = {:default => methods_list}
|
39
|
+
end
|
40
|
+
|
41
|
+
if methods_list.is_a?(Hash)
|
42
|
+
|
43
|
+
self.cached_methods ||= {}
|
44
|
+
|
45
|
+
methods_list.each do |group, methods|
|
46
|
+
if self.cached_methods[group.to_sym].nil?
|
47
|
+
self.cached_methods[group.to_sym] = methods
|
48
|
+
else
|
49
|
+
self.cached_methods[group.to_sym] << methods
|
50
|
+
self.cached_methods[group.to_sym] = self.cached_methods[group.to_sym].flatten
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
raise ArgumentError, "Wrong definition for cached methods: Use either an array (self.cached_methods will become {:default => array}) or a hash"
|
55
|
+
end
|
56
|
+
|
57
|
+
setup_cache_method_aliasing
|
58
|
+
end
|
59
|
+
|
60
|
+
def setup_cache_method_aliasing
|
61
|
+
# Setup des MethodAliasing
|
62
|
+
self.instance_eval do
|
63
|
+
self.cached_methods.each do |method_stack, methods|
|
64
|
+
methods.each_with_index do |method, i|
|
65
|
+
puts [self.name, method, self.instance_methods.include?(method.to_sym)].inspect
|
66
|
+
|
67
|
+
# Methodennamen mit ?/! am ende fixen - Alias anlegen
|
68
|
+
needs_alias = false
|
69
|
+
if method.to_s.last == "?"
|
70
|
+
fixed_name = method.to_s.gsub("?","_with_soi")
|
71
|
+
needs_alias = true
|
72
|
+
elsif method.to_s.last == "!"
|
73
|
+
fixed_name = method.to_s.gsub("?","_with_bang")
|
74
|
+
needs_alias = true
|
75
|
+
end
|
76
|
+
|
77
|
+
if needs_alias
|
78
|
+
alias_method fixed_name, method
|
79
|
+
|
80
|
+
method = fixed_name
|
81
|
+
end
|
82
|
+
|
83
|
+
define_method("#{method}_with_caching") do |*args|
|
84
|
+
#begin
|
85
|
+
start = Time.now
|
86
|
+
# Key für den Cache erzeugen - Alle Parameter mit ablegen
|
87
|
+
args_list = *args.flatten.map {|a| a.is_a?(ActiveRecord::Base) ? "#{a.class.name}-#{a.id}" : a}
|
88
|
+
meth_name = [method,args_list].inspect.parameterize.to_s
|
89
|
+
|
90
|
+
|
91
|
+
if cached?(meth_name)
|
92
|
+
x = self.cached_attribute(meth_name)
|
93
|
+
|
94
|
+
# => ActiveRecordArray disabled (03.08.2013, 18:54, Florian Eck)
|
95
|
+
# if x.is_a?(ActiveRecordArray)
|
96
|
+
# x = x.parse_record_data
|
97
|
+
# end
|
98
|
+
CachingLog.info " ... CALL cache_data #{meth_name} (#{Time.now-start})"
|
99
|
+
return x
|
100
|
+
else
|
101
|
+
# Hier wird die Originalfunction aufgerufen
|
102
|
+
orig = self.send("#{method}_without_caching", *args)
|
103
|
+
|
104
|
+
# => ActiveRecordArray disabled
|
105
|
+
#if orig.is_active_record_array?
|
106
|
+
#parse = orig.parse_active_record_array
|
107
|
+
#CachingLog.info "save ActiveRecordArray"
|
108
|
+
#else
|
109
|
+
parse = orig
|
110
|
+
#end
|
111
|
+
|
112
|
+
v = cache_attribute!(meth_name, parse)
|
113
|
+
CachingLog.info " ... CREATE cache_data #{meth_name} (#{Time.now-start})"
|
114
|
+
|
115
|
+
return orig
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
#rescue Exception => e
|
120
|
+
# self.method_cache = {:last_error => e.backtrace, :last_error_class => e.class.inspect, :last_error_message => e.message}
|
121
|
+
# return nil #self.send("#{method}_without_caching", *args)
|
122
|
+
#end
|
123
|
+
#__send__("#{method}_without_caching", *args)
|
124
|
+
end
|
125
|
+
|
126
|
+
alias_method_chain method, :caching
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def method_cache_enabled?
|
134
|
+
self.included_modules.include?(InstanceMethods)
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
module InstanceMethods
|
141
|
+
def method_cache
|
142
|
+
m = self.class.cache_storage[self.id]
|
143
|
+
if m.nil?
|
144
|
+
# Wenn neue nutzer angelegt werden
|
145
|
+
CachingLog.info "Create cache for #{self.class.name}(#{self.id})"
|
146
|
+
self.class.cache_storage.merge!(self.id => {})
|
147
|
+
self.class.cache_storage[self.id]
|
148
|
+
return {}
|
149
|
+
else
|
150
|
+
return m
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def method_cache=(val)
|
155
|
+
self.class.cache_storage.merge!(self.id => val)
|
156
|
+
end
|
157
|
+
|
158
|
+
def cached?(att)
|
159
|
+
!self.method_cache[att.to_s].nil?
|
160
|
+
end
|
161
|
+
|
162
|
+
def cached_attribute(att)
|
163
|
+
self.method_cache[att.to_s]
|
164
|
+
end
|
165
|
+
|
166
|
+
def cache_attribute!(att, value)
|
167
|
+
m = self.method_cache.merge!(att.to_s => value)
|
168
|
+
#self.personal_status.update_attributes(:method_cache => m)
|
169
|
+
# => not using DB anymore
|
170
|
+
return value
|
171
|
+
end
|
172
|
+
|
173
|
+
# Clear methods.
|
174
|
+
# Kann ein Methodenname, ein Array von Namen oder ein Regexp sein
|
175
|
+
def clear_method_cache(meths = [], options = {})
|
176
|
+
if meths.is_a?(Regexp)
|
177
|
+
meths = self.method_cache.keys.select {|k| !k.match(meths).nil? }
|
178
|
+
elsif meths.is_a?(Symbol) || meths.is_a?(String)
|
179
|
+
meths = self.class.cached_methods[meths.to_sym]
|
180
|
+
elsif !meths.is_a?(Array)
|
181
|
+
meths = meths.to_a
|
182
|
+
end
|
183
|
+
|
184
|
+
begin
|
185
|
+
c = self.method_cache
|
186
|
+
meths_all = c.keys
|
187
|
+
meths_valid = []
|
188
|
+
meths.each do |m|
|
189
|
+
meths_all.each do |mv|
|
190
|
+
meths_valid << mv if mv.match(m)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
CachingLog.info meths_valid.inspect
|
194
|
+
meths_valid.each do |m|
|
195
|
+
CachingLog.info "DELETE cache data: #{m}"
|
196
|
+
CachingLog.info " for #{self.personal_data.first_name} #{self.personal_data.last_name}"
|
197
|
+
c.delete(m)
|
198
|
+
end
|
199
|
+
rescue
|
200
|
+
# wenn was schief läuft: $user_method_caching für den user auf {} setzen
|
201
|
+
CachingLog.info "RESET CACHE (forced): #{self.full_name} / #{self.id}"
|
202
|
+
self.class.cache_storage[self.id] = {}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def reset_cache
|
207
|
+
self.class.cache_storage[self.id] = {}
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module ThreeD
|
3
|
+
module ModelFragments
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def model_fragments
|
11
|
+
unless has_model_fragments?
|
12
|
+
|
13
|
+
if ActionController::Base.cache_store.inspect.match("FileStore")
|
14
|
+
|
15
|
+
self.send :include, InstanceMethods
|
16
|
+
cattr_accessor :caching_path
|
17
|
+
|
18
|
+
self.caching_path = ActionController::Base.cache_store.cache_path
|
19
|
+
self.after_save :clear_view_cache
|
20
|
+
self.after_destroy :clear_view_cache
|
21
|
+
else
|
22
|
+
raise "Currently, ModelFragments only support FileStore\nPlease set 'ActionController::Base.cache_store = :file_store, /path/to/cache'"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_model_fragments?
|
28
|
+
self.included_modules.include?(InstanceMethods)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module InstanceMethods
|
33
|
+
|
34
|
+
def cache_name(data, scope_data=nil)
|
35
|
+
data = data.to_s
|
36
|
+
x = "#{self.class.name.parameterize}_#{self.id}_cache_#{data}"
|
37
|
+
x << "_#{scope_data.to_s}" if scope_data
|
38
|
+
return x
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear_view_cache(data="")
|
42
|
+
%x(rm #{self.full_cache_path(data)})
|
43
|
+
end
|
44
|
+
|
45
|
+
def full_cache_path(data="")
|
46
|
+
"#{self.class.caching_path}/views/#{self.class.name.parameterize}_#{self.id}_#{data}*"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/three_d/once.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module ThreeD
|
2
|
+
module Once
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def once(*ids)
|
11
|
+
# Auch Array kann übergeben werde
|
12
|
+
ids = ids.first if ids.first.is_a?(Array)
|
13
|
+
|
14
|
+
ids.each do |id|
|
15
|
+
id = id.to_s
|
16
|
+
self.instance_eval do
|
17
|
+
|
18
|
+
alias_method "__#{id}", id
|
19
|
+
|
20
|
+
define_method(id) do |*args|
|
21
|
+
ident_name = *args.hash.to_i
|
22
|
+
|
23
|
+
# Use @once_cache[]
|
24
|
+
key_name = "#{id}_#{ident_name}_#{self.id}".gsub(/[^a-zA-Z0-9_@]/, '')
|
25
|
+
|
26
|
+
@once_cache ||= {}
|
27
|
+
|
28
|
+
if @once_cache[key_name].nil?
|
29
|
+
@once_cache[key_name] = self.send("__#{id}", *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
return @once_cache[key_name]
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: 3d_cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.01a
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Florian Eck
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Cache results of method calls for a class in RAM
|
14
|
+
email:
|
15
|
+
- it-support@friends-systems.de
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/3d_cache.rb
|
21
|
+
- lib/three_d/class_method_cache.rb
|
22
|
+
- lib/three_d/model_fragments.rb
|
23
|
+
- lib/three_d/once.rb
|
24
|
+
homepage: ''
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.3.1
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.2.1
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Caching shizznit
|
48
|
+
test_files: []
|