the-blob 0.0.1 → 0.0.21

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.
@@ -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