minuteman 0.2.0 → 1.0.0.pre

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