the-blob 0.0.1 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,69 +2,33 @@ require File.expand_path '../../the_blob/instance', __FILE__
2
2
 
3
3
  module InstanceHandler
4
4
 
5
- class InstanceNotFound < RuntimeError; end
6
-
7
- module ClassMethods
8
-
9
- #TODO move this into seperate class
10
- def load_instances
11
- dir = File.expand_path("app/instances", ".")
12
- Dir["#{dir}/*"].each do |file|
13
- puts file
14
- require file
15
- create_methods(file)
16
- end
17
- end
18
-
19
- def create_methods(file)
20
- klass = file.scan(/\/([^\/]+)\.rb/).first.first
21
- make_class_getter(klass)
22
- make_index_getters(klass)
23
- end
24
-
25
- def make_class_getter(klass)
26
- class_eval <<-CODE
27
- def #{klass}s
28
- instance_lists["#{klass.capitalize}"]
29
- end
30
- CODE
31
- end
32
-
33
- def make_index_getters(klass)
34
- Module.const_get(klass.capitalize).get_instance_indices.each do |index|
35
- class_eval <<-CODE
36
- def emit_#{klass}_by_#{index}(id)
37
- instance = instances["#{klass.capitalize}"]["__#{index}"][id]
38
- instance || raise(InstanceNotFound)
39
- end
40
- CODE
41
- end
42
- end
43
-
44
- end
45
-
46
- def self.included(base)
47
- base.extend(ClassMethods)
48
- base.load_instances
5
+ def initialize(options = {memory: MemoryPersister})
6
+ load_instances
7
+ @memory_persister = options[:memory].new(@klass_list)
49
8
  end
50
9
 
51
10
  def absorb(instance)
52
- klass = instance.class
53
- instance_lists[klass.to_s] << instance
54
- klass.get_instance_indices.each do |index|
55
- instances[klass.to_s]["__#{index}"][instance.send(index)] = instance
56
- end
11
+ @memory_persister.absorb instance
57
12
  end
58
13
 
59
14
  private
60
-
61
- def instances
62
- hash = proc{|a| Hash.new{|hash, key| hash[key] = a} }
63
- @instances ||= hash.call( hash.call( hash.call( nil )))
15
+ def load_instances
16
+ dir = File.expand_path("app/instances", ".")
17
+ Dir["#{dir}/*"].each do |file|
18
+ require file
19
+ klass = Module.const_get file.scan(/\/([^\/]+)\.rb/).first.first.capitalize
20
+ make_index_getters(klass)
21
+ (@klass_list ||= []) << klass
22
+ end
64
23
  end
65
24
 
66
- def instance_lists
67
- @instance_lists ||= Hash.new{|hash, key| hash[key] = Array.new }
25
+ def make_index_getters(klass)
26
+ klass.get_instance_indices.each do |index|
27
+ instance_eval <<-CODE
28
+ def emit_#{klass.underscore}_by_#{index}(id)
29
+ @memory_persister.emit_#{klass.underscore}_by_#{index}(id)
30
+ end
31
+ CODE
32
+ end
68
33
  end
69
-
70
34
  end
@@ -0,0 +1,91 @@
1
+ class MemoryPersister
2
+
3
+ class Full < RuntimeError; end
4
+
5
+ def initialize(klass_list, options = {})
6
+ klass_list.each{ |klass| make_index_getters(klass) }
7
+ sub_capacity = (options[:capacity] || 100000) / 2
8
+ @new_container = MemoryContainer.new klass_list, capacity: sub_capacity
9
+ @old_container = MemoryContainer.new klass_list, capacity: sub_capacity
10
+ end
11
+
12
+ def absorb(instance)
13
+ @new_container.absorb instance
14
+ rescue MemoryPersister::Full
15
+ rotate_containers
16
+ absorb instance
17
+ end
18
+
19
+ private
20
+ def rotate_containers
21
+ @old_container.clear
22
+ p = @new_container
23
+ @new_container = @old_container
24
+ @old_container = p
25
+ end
26
+
27
+ def make_index_getters(klass)
28
+ klass.get_instance_indices.each do |index|
29
+ instance_eval <<-CODE
30
+ def emit_#{klass.underscore}_by_#{index}(id)
31
+ @new_container.emit_#{klass.underscore}_by_#{index} id
32
+ rescue TheBlob::InstanceNotFound
33
+ instance = @old_container.emit_#{klass.underscore}_by_#{index} id
34
+ @new_container.absorb instance
35
+ instance
36
+ end
37
+ CODE
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ class MemoryPersister::MemoryContainer
44
+
45
+ def initialize(klass_list, options = {})
46
+ klass_list.each {|klass| make_index_getters klass }
47
+ @capacity = options[:capacity] || 65535
48
+ clear
49
+ end
50
+
51
+ def absorb(instance)
52
+ raise MemoryPersister::Full if self.capacity_left <= 0
53
+ klass = instance.class
54
+ klass.get_instance_indices.each do |index|
55
+ instances[klass.to_s]["__#{index}"][instance.send(index)] = instance
56
+ end
57
+ @capacity_used += 1
58
+ end
59
+
60
+ def capacity_left
61
+ @capacity - @capacity_used
62
+ end
63
+
64
+ def clear
65
+ @instances = new_instances_hash
66
+ @capacity_used = 0
67
+ end
68
+
69
+ private
70
+
71
+ def make_index_getters(klass)
72
+ klass.get_instance_indices.each do |index|
73
+ instance_eval <<-CODE
74
+ def emit_#{klass.underscore}_by_#{index}(id)
75
+ instance = instances["#{klass}"]["__#{index}"][id]
76
+ instance && instance.dup || raise(TheBlob::InstanceNotFound)
77
+ end
78
+ CODE
79
+ end
80
+ end
81
+
82
+ def instances
83
+ @instances
84
+ end
85
+
86
+ def new_instances_hash
87
+ hash = proc{|a| Hash.new{|hash, key| hash[key] = a} }
88
+ hash.call( hash.call( hash.call( nil )))
89
+ end
90
+
91
+ end
@@ -1,11 +1,12 @@
1
1
  require File.expand_path '../handlers/instance_handler', __FILE__
2
- require File.expand_path '../handlers/link_handler', __FILE__
2
+ require File.expand_path '../persisters/memory_persister', __FILE__
3
3
 
4
4
  module TheBlob
5
5
 
6
+ class InstanceNotFound < RuntimeError; end
7
+
6
8
  def self.included(base)
7
9
  base.class_eval do
8
- include LinkHandler
9
10
  include InstanceHandler
10
11
  end
11
12
  end
@@ -1,7 +1,43 @@
1
- require 'the_blob/instance_methods'
1
+ module Instance
2
2
 
3
- class Instance
3
+ def self.included(base)
4
+ base.instance_eval do
5
+ def self.underscore
6
+ self.to_s.gsub(/::/, '/').
7
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
8
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
9
+ tr("-", "_").
10
+ downcase
11
+ end
4
12
 
5
- include InstanceMethods
13
+ def self.get_next_id
14
+ @next_id ||= 0
15
+ @next_id += 1
16
+ end
17
+
18
+ def self.instance_indices(*ind)
19
+ indices = ind << :id
20
+ attr_accessor *indices
21
+ @instance_indices = indices
22
+ end
23
+
24
+ def self.get_instance_indices
25
+ @instance_indices ||= []
26
+ end
27
+ end
28
+ end
29
+
30
+ def initialize(attrs = {})
31
+ @id = self.class.get_next_id
32
+ attrs.each{ |name, value| name.inspect; send("#{name}=", value) }
33
+ end
34
+
35
+ def id
36
+ @id
37
+ end
38
+
39
+ def ==(instance_2)
40
+ self.class == instance_2.class && id == instance_2.id
41
+ end
6
42
 
7
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: the-blob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.21
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,15 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-12 00:00:00.000000000 Z
12
+ date: 2012-09-14 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: The blob provides hash-based instance handling.
14
+ description: ! 'The blob is an instance handling interface that seperates ORM responsibilities
15
+ from application instances.
16
+
17
+ This allows for fast and easy testing of your application by not needing to load
18
+ ORM code in your business logic.
19
+
20
+ '
15
21
  email: kwstannard@gmail.com
16
22
  executables: []
17
23
  extensions: []
@@ -19,9 +25,8 @@ extra_rdoc_files: []
19
25
  files:
20
26
  - lib/the_blob.rb
21
27
  - lib/handlers/instance_handler.rb
22
- - lib/handlers/link_handler.rb
28
+ - lib/persisters/memory_persister.rb
23
29
  - lib/the_blob/instance.rb
24
- - lib/the_blob/instance_methods.rb
25
30
  homepage: https://github.com/kwstannard/the_blob
26
31
  licenses: []
27
32
  post_install_message:
@@ -1,25 +0,0 @@
1
- module LinkHandler
2
-
3
- def create_link (instance_1, instance_2)
4
- links[instance_1][instance_2.class] << instance_2
5
- links[instance_2][instance_1.class] << instance_1
6
- nil
7
- end
8
-
9
- def delete_link(instance_1, instance_2)
10
- links[instance_1][instance_2.class].delete(instance_2)
11
- links[instance_2][instance_1.class].delete(instance_1)
12
- nil
13
- end
14
-
15
- def get_links(instance, klass)
16
- links[instance][klass].dup
17
- end
18
-
19
- private
20
-
21
- def links
22
- @links ||= Hash.new{|hash, key| hash[key] = Hash.new{|hash, key| hash[key] = []} }
23
- end
24
-
25
- end
@@ -1,31 +0,0 @@
1
- module InstanceMethods
2
-
3
- def self.included(base)
4
- base.instance_eval do
5
- def self.get_next_id
6
- @next_id ||= 0
7
- @next_id += 1
8
- end
9
-
10
- def self.instance_indices(*ind)
11
- indices = ind << :id
12
- attr_accessor *indices
13
- @instance_indices = indices
14
- end
15
-
16
- def self.get_instance_indices
17
- @instance_indices ||= []
18
- end
19
- end
20
- end
21
-
22
- def initialize(attrs = {})
23
- @id = self.class.get_next_id
24
- attrs.each{ |name, value| name.inspect; send("#{name}=", value) }
25
- end
26
-
27
- def id
28
- @id
29
- end
30
-
31
- end