cache_tree 0.0.0

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.8.3"
13
+ gem "rcov", ">= 0"
14
+ end
15
+
16
+ gem 'isna'
17
+ gem 'tree_node'
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 kazuyoshi tlacaelel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,28 @@
1
+ = cache_tree
2
+
3
+ Btree based cache
4
+
5
+ == Contributing to cache_tree
6
+
7
+ require 'rubygems'
8
+ require 'cache_tree'
9
+
10
+ class Record
11
+ def id
12
+ 1
13
+ end
14
+ end
15
+
16
+ CacheTree::Node.directory = 'cache_tree'
17
+ record = CacheTree::Node.new(Record.new)
18
+ CacheTree::Manager.instance.use(record)
19
+ unless CacheTree::Manager.instance.exists?
20
+ CacheTree::Manager.instance.save('data')
21
+ end
22
+ puts CacheTree::Manager.instance.read
23
+
24
+ == Copyright
25
+
26
+ Copyright (c) 2012 kazuyoshi tlacaelel. See LICENSE.txt for
27
+ further details.
28
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "cache_tree"
18
+ gem.homepage = "http://github.com/ktlacaelel/cache_tree"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Simple cache tree}
21
+ gem.description = %Q{Cache based on btrees, for large ammounts of cache.}
22
+ gem.email = "kazu.dev@gmail.com"
23
+ gem.authors = ["kazuyoshi tlacaelel"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "cache_tree #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/lib/cache_tree.rb ADDED
@@ -0,0 +1,155 @@
1
+ require 'md5'
2
+ require 'singleton'
3
+ require 'fileutils'
4
+ require 'isna'
5
+ require 'tree_node'
6
+
7
+ module CacheTree
8
+
9
+ class Manager
10
+
11
+ include Singleton
12
+
13
+ def initialize
14
+ @current_link = nil
15
+ @configuration = { :perform_caching => true }
16
+ end
17
+
18
+ def configure(options)
19
+ @configuration.merge(options)
20
+ end
21
+
22
+ def use(cache_link)
23
+ @current_link = cache_link
24
+ end
25
+
26
+ def exists?
27
+ return false unless @configuration[:perform_caching]
28
+ btree_key_files = @current_link.map(:up) { |node| node.btree_key }
29
+ return false unless btree_key_files.all? { |btree_key| File.exists?(btree_key) }
30
+ @current_link.map(:up) { |node| node.load_btree_key }
31
+ File.exists?(@current_link.cache_file)
32
+ end
33
+
34
+ def expire!
35
+ @current_link.expire
36
+ end
37
+
38
+ def read
39
+ @current_link.map(:up) { |node| node.load_btree_key }
40
+ File.read(@current_link.cache_file)
41
+ end
42
+
43
+ def save(data)
44
+ @current_link.map(:up) { |node| node.save }
45
+ FileUtils.mkdir_p(File.dirname(@current_link.cache_file))
46
+ File.open(@current_link.cache_file, 'w+') { |file| file.write data }
47
+ end
48
+
49
+ end
50
+
51
+ class Node
52
+
53
+ class << self
54
+ attr_accessor :directory
55
+ end
56
+
57
+ SEPARATOR = '/'
58
+
59
+ attr_accessor :name, :value, :stamp
60
+
61
+ include Tree::Node
62
+
63
+ def initialize(target)
64
+ @name = target.class.name.gsub(/([A-Z])/) { "_#{$1}" }.gsub(/^./, '').downcase
65
+ @value = target.id
66
+ @stamp = generate_stamp
67
+ end
68
+
69
+ def directory
70
+ self.class.directory
71
+ end
72
+
73
+ def generate_stamp
74
+ (Time.now.to_f * 1.0).to_s + '-' + Kernel.rand(1000000).to_s
75
+ end
76
+
77
+ # Path of the cache node
78
+ def path
79
+ "#{name}#{SEPARATOR}#{value}#{SEPARATOR}"
80
+ end
81
+
82
+ # Resolves final name for btree_key file.
83
+ def btree_key
84
+ directory + SEPARATOR + (map(:up) { |node| node.path } * '') + 'btree.key'
85
+ end
86
+
87
+ # Updates current node stamp from btree_key
88
+ def load_btree_key
89
+ @stamp = eval(File.read(btree_key))
90
+ end
91
+
92
+ # Sums up all stamps and generates a checksum.
93
+ def checksum
94
+ MD5.hexdigest(map(:up) { |node| node.stamp } * '')
95
+ end
96
+
97
+ # Resolves final name for cache file.
98
+ def cache_file
99
+ directory + SEPARATOR + (map(:up) { |node| node.path } * '') + checksum + '.cache'
100
+ end
101
+
102
+ # Writes node stamp from to btree_key file
103
+ def save
104
+ FileUtils.mkdir_p File.dirname(btree_key)
105
+ File.open(btree_key, 'w+') { |file| file.write stamp.inspect }
106
+ end
107
+
108
+ # Quickly expire a whole cache-tree or a single node.
109
+ # Expiring a node in the middle will automatically expire all
110
+ # children nodes. no need to expire each one individually.
111
+ def expire
112
+ @stamp = generate_stamp
113
+ save
114
+ end
115
+
116
+ # Cleans up expired cache files for a specific node.
117
+ #
118
+ # You need to be specific the engine will not walk down the tree
119
+ # for you to prevent iterating through large trees.
120
+ #
121
+ # @return [Array] of items that were deleted.
122
+ def clean
123
+ diagnose[:dead].each { |file| FileUtils.rm file }
124
+ end
125
+
126
+ # Runs an analysis on a given node and returns its status.
127
+ #
128
+ # @return [Hash] with detailed diagnosis of curret status for that
129
+ # node's cache
130
+ def diagnose
131
+ file_alive = cache_file
132
+ base = File.basename(file_alive)
133
+ dir = File.dirname(file_alive)
134
+ diagnostic = {}
135
+ diagnostic[:btree_key] = btree_key
136
+ diagnostic[:alive] = file_alive
137
+ diagnostic[:dead] = []
138
+ Dir["#{dir}/*.cache"].each do |cached_file|
139
+ next if File.basename(cached_file) == base
140
+ diagnostic[:dead] << cached_file
141
+ end
142
+ diagnostic
143
+ end
144
+
145
+ # Prints out active cache in green, and expired files in red.
146
+ def debug
147
+ puts cache_file.to_ansi.green
148
+ diagnose[:dead].each { |file| puts file.to_ansi.red }
149
+ nil
150
+ end
151
+
152
+ end
153
+
154
+ end
155
+
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'cache_tree'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestCacheTree < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cache_tree
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - kazuyoshi tlacaelel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-11-01 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ type: :runtime
23
+ prerelease: false
24
+ name: isna
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ requirement: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ type: :runtime
37
+ prerelease: false
38
+ name: tree_node
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ requirement: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ type: :development
51
+ prerelease: false
52
+ name: shoulda
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirement: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ type: :development
65
+ prerelease: false
66
+ name: rdoc
67
+ version_requirements: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ hash: 31
73
+ segments:
74
+ - 3
75
+ - 12
76
+ version: "3.12"
77
+ requirement: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ type: :development
80
+ prerelease: false
81
+ name: bundler
82
+ version_requirements: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 23
88
+ segments:
89
+ - 1
90
+ - 0
91
+ - 0
92
+ version: 1.0.0
93
+ requirement: *id005
94
+ - !ruby/object:Gem::Dependency
95
+ type: :development
96
+ prerelease: false
97
+ name: jeweler
98
+ version_requirements: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ hash: 49
104
+ segments:
105
+ - 1
106
+ - 8
107
+ - 3
108
+ version: 1.8.3
109
+ requirement: *id006
110
+ - !ruby/object:Gem::Dependency
111
+ type: :development
112
+ prerelease: false
113
+ name: rcov
114
+ version_requirements: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirement: *id007
124
+ description: Cache based on btrees, for large ammounts of cache.
125
+ email: kazu.dev@gmail.com
126
+ executables: []
127
+
128
+ extensions: []
129
+
130
+ extra_rdoc_files:
131
+ - LICENSE.txt
132
+ - README.rdoc
133
+ files:
134
+ - .document
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.rdoc
138
+ - Rakefile
139
+ - VERSION
140
+ - lib/cache_tree.rb
141
+ - test/helper.rb
142
+ - test/test_cache_tree.rb
143
+ has_rdoc: true
144
+ homepage: http://github.com/ktlacaelel/cache_tree
145
+ licenses:
146
+ - MIT
147
+ post_install_message:
148
+ rdoc_options: []
149
+
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ hash: 3
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ hash: 3
167
+ segments:
168
+ - 0
169
+ version: "0"
170
+ requirements: []
171
+
172
+ rubyforge_project:
173
+ rubygems_version: 1.3.7
174
+ signing_key:
175
+ specification_version: 3
176
+ summary: Simple cache tree
177
+ test_files: []
178
+