minuteman 0.2.0 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- minuteman (0.2.0)
4
+ minuteman (1.0.0.pre)
5
5
  redis (~> 3.0.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Minuteman
2
2
  [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/elcuervo/minuteman)
3
+ [![Build Status](https://secure.travis-ci.org/elcuervo/minuteman.png?branch=master)](https://travis-ci.org/elcuervo/minuteman)
3
4
 
4
5
  _Wikipedia_: Minutemen were members of teams from Massachusetts that were well-prepared
5
6
  militia companies of select men from the American colonial partisan militia
@@ -40,13 +41,13 @@ Freenode - #cuba.rb - 2012/10/30 15:20 UYT
40
41
  Depends on Redis 2.6 for the `bitop` operation. You can install it using:
41
42
 
42
43
  ```bash
43
- brew install --devel redis
44
+ brew install redis
44
45
  ```
45
46
 
46
47
  or upgrading your current version:
47
48
 
48
49
  ```bash
49
- brew upgrade --devel redis
50
+ brew upgrade redis
50
51
  ```
51
52
 
52
53
  And then install the gem
@@ -73,13 +73,19 @@ class Minuteman
73
73
  redis.getbit(key, id) == 1
74
74
  end
75
75
 
76
- # Private: executes an operation between the current timespan and another
76
+ # Private: Cxecutes an operation between the current timespan and another
77
77
  #
78
78
  # type: The operation type
79
79
  # timespan: The given timespan
80
80
  #
81
81
  def operation(type, timespan)
82
- Operation.new(redis, type, self, timespan).call
82
+ operate.call(type, timespan)
83
+ end
84
+
85
+ # Private: Memoizes the operation class
86
+ #
87
+ def operate
88
+ @_operate ||= Operation.new(redis, self)
83
89
  end
84
90
  end
85
91
  end
@@ -10,25 +10,92 @@ class Minuteman
10
10
  # timespan: One of the timespans to be permuted
11
11
  # other: The other timespan to be permuted
12
12
  #
13
- class Operation < Struct.new(:redis, :type, :timespan, :other)
14
- def call
15
- if type == "MINUS" && operable?
16
- return timespan ^ (timespan & other)
13
+ class Operation < Struct.new(:redis, :timespan)
14
+ # Public: Caches operations against Array
15
+ #
16
+ class Cache
17
+ attr_reader :cache
18
+
19
+ def initialize
20
+ @cache = {}
21
+ end
22
+
23
+ # Public: Access a cached object
24
+ #
25
+ # array: The original data set
26
+ #
27
+ def [](array)
28
+ cache.fetch(array.sort.hash)
17
29
  end
18
30
 
19
- klass.new(redis, type, other, timespan.key).call
31
+ # Public: Caches an object
32
+ #
33
+ # array: The original data set
34
+ # object: The object to be cached
35
+ #
36
+ def []=(array, object)
37
+ cache[array.sort.hash] = object
38
+ end
39
+
40
+ # Public: Checks for the existance of an array in the cache
41
+ #
42
+ # array: The original data set
43
+ #
44
+ def include?(array)
45
+ cache.keys.include?(array.sort.hash) if array.is_a?(Array)
46
+ end
47
+ end
48
+
49
+ attr_reader :other
50
+ attr_accessor :cache
51
+
52
+ # Public: Initializes the Operation and starts the cache
53
+ #
54
+ def initialize(*)
55
+ super
56
+
57
+ @cache = Cache.new
58
+ end
59
+
60
+ # Public: Executes an operation
61
+ #
62
+ # type: The string type of the operation
63
+ # other: The other set to be operated, can be Array or BitOperations
64
+ #
65
+ def call(type, other)
66
+ @other = other
67
+
68
+ return minus_operation if type == "MINUS" && operable?
69
+ return cache[other] if cache.include?(other)
70
+
71
+ caching { klass.new(redis, type, other, timespan.key).call }
20
72
  end
21
73
 
22
74
  private
23
75
 
76
+ # Private: Executes a minus operation between the sets
77
+ #
78
+ def minus_operation
79
+ timespan ^ (timespan & other)
80
+ end
81
+
82
+ # Private: Caches any caching capable operation
83
+ #
84
+ def caching
85
+ executed_class = yield
86
+ cache[other] = executed_class if other.is_a?(Array)
87
+ executed_class
88
+ end
89
+
24
90
  # Private: returns the class to use for the operation
25
91
  #
26
92
  # timespan: The given timespan
27
93
  #
28
94
  def klass
29
95
  case true
30
- when other.is_a?(Array) then WithData
31
96
  when other.is_a?(String), operable? then Plain
97
+ when other.is_a?(Array) then WithData
98
+ else raise(TypeError, "Unsupported type")
32
99
  end
33
100
  end
34
101
 
@@ -22,6 +22,7 @@ class Minuteman
22
22
 
23
23
  key = destination_key(type, events)
24
24
  redis.bitop(type, key, events)
25
+
25
26
  Result.new(redis, key)
26
27
  end
27
28
  end
@@ -25,7 +25,10 @@ class Minuteman
25
25
  redis.getbit(source_key, id) == 1
26
26
  end
27
27
 
28
- intersected_data.each { |id| redis.setbit(key, id, 1) }
28
+ if !redis.exists(key)
29
+ intersected_data.each { |id| redis.setbit(key, id, 1) }
30
+ end
31
+
29
32
  Data.new(redis, key, intersected_data)
30
33
  end
31
34
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "minuteman"
3
- s.version = "0.2.0"
3
+ s.version = "1.0.0.pre"
4
4
  s.summary = "Bit Analytics"
5
5
  s.description = "Fast and furious tracking system using Redis bitwise operations"
6
6
  s.authors = ["elcuervo"]
@@ -152,7 +152,7 @@ describe Minuteman do
152
152
  assert_equal [43], ids
153
153
  end
154
154
 
155
- it "a resulting set with data should behave like an array" do
155
+ it "should return a set with data that behaves like an array" do
156
156
  ids = @week_events & [2, 12, 43]
157
157
 
158
158
  assert_kind_of Enumerator, ids.each
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minuteman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 1.0.0.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - elcuervo
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-14 00:00:00.000000000 Z
12
+ date: 2012-11-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -91,9 +91,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
91
  required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  none: false
93
93
  requirements:
94
- - - ! '>='
94
+ - - ! '>'
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 1.3.1
97
97
  requirements: []
98
98
  rubyforge_project:
99
99
  rubygems_version: 1.8.23