redis-set 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85fb6b90aa4d2878c749b147389a183557967f5a
4
- data.tar.gz: e6d89f6f66dd79108298f7d97cab63ca8e3a1e22
3
+ metadata.gz: 38c7747969cffe4f84c06b7c4c249e1db96b60b2
4
+ data.tar.gz: cc72aef22abc64c4a4ed886eef069865451131a3
5
5
  SHA512:
6
- metadata.gz: 703d725c82cc116107ded6d3174dc2646ab419cbc0c11665523a0386e6688f104854a7c45c8feaaf18e61fdbcaf5a6e8c862ba3605461bb4b86962f0832275c5
7
- data.tar.gz: a1ac7949c4cbf73eb0c9bd4f5d1c930e355860d1064a7a8dfd5c2c19d9b4d0cff4f189bc3b0f1b23705a6398fd4899e206c444195db9951d9282c225fbddf56a
6
+ metadata.gz: 4b38c5833ea9b105ae3a516154319389708db9b3f6e2103d7215736673f686bbba823ed25fd8064be7bf4062e295f158c07a34b436d5febf59469801c61d94e6
7
+ data.tar.gz: 53c98de243c00205a442a6e7ca987e15219260eda9bc9c8820e7ad22fedfc408a9159bee0f82a0c638b63a50b82be10722612a31e9c34c9ecc7ef25c4117ba18
data/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  A unique set of unordered items. Lightweight wrapper over redis sets with some additional enumeration and atomic operations.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
5
  ## Installation
8
6
 
9
7
  Add this line to your application's Gemfile:
@@ -23,19 +21,19 @@ Or install it yourself as:
23
21
  ## Getting started
24
22
 
25
23
  ```ruby
26
- s = Redis::Set.new 'completed_customer_ids'
24
+ s = RedisSet.new 'completed_customer_ids'
27
25
  ```
28
26
 
29
27
  Or you can pass in your own instance of the Redis class.
30
28
 
31
29
  ```ruby
32
- s = Redis::Set.new 'completed_customer_ids', Redis.new(:host => "10.0.1.1", :port => 6380, :db => 15)
30
+ s = RedisSet.new 'completed_customer_ids', Redis.new(:host => "10.0.1.1", :port => 6380, :db => 15)
33
31
  ```
34
32
 
35
33
  A third option is to instead pass your Redis configurations.
36
34
 
37
35
  ```ruby
38
- s = Redis::Set.new 'completed_customer_ids', :host => "10.0.1.1", :port => 6380, :db => 15
36
+ s = RedisSet.new 'completed_customer_ids', :host => "10.0.1.1", :port => 6380, :db => 15
39
37
  ```
40
38
 
41
39
  ## Using the set
@@ -48,11 +46,11 @@ s.add "world"
48
46
  s.add "hello" # the item 'hello' will only exist once in the set since it is unique
49
47
  ```
50
48
 
51
- You can insert multiple items set using the add_multi or push_multi methods
49
+ You can add multiple items
52
50
 
53
51
  ```ruby
54
- s.add_multi ["one","two","three"]
55
- s.add_multi "four","five","six"
52
+ s.add ["one","two","three"]
53
+ s.add "four","five","six"
56
54
  # set should have items "one","two","three","four","five","six" now
57
55
  ```
58
56
 
@@ -68,7 +66,7 @@ result = s.pop
68
66
 
69
67
  You can pop multiple random items from the set
70
68
  ```ruby
71
- result = s.pop_multi 5 # pop 5 random items from set and return them
69
+ result = s.pop 5 # pop 5 random items from set and return them
72
70
  ```
73
71
 
74
72
  You can remove a specific item from the set
@@ -79,7 +77,7 @@ s.remove 5 #remove the item 5 from the set if it exists
79
77
  You can atomically remove multiple items from the set.
80
78
 
81
79
  ```ruby
82
- s.remove_multi 3,4,5 #removes items 3,4, and 5 from the set if they exist
80
+ s.remove 3,4,5 #removes items 3,4, and 5 from the set if they exist
83
81
  ```
84
82
 
85
83
  You can get the size of the set.
@@ -105,6 +103,22 @@ The set can be cleared of all items
105
103
  s.clear
106
104
  ```
107
105
 
106
+ You can get the intersection between the set and another set
107
+ ```ruby
108
+ a = RedisSet.new 'a'
109
+ a.push 'a', 'b', 'c', 'd'
110
+
111
+ b = RedisSet.new 'b'
112
+ b.push 'c', 'd', 'e', 'f'
113
+
114
+ c = RedisSet.new 'c'
115
+ c.push 'c', 'd', 'f'
116
+
117
+ # should return ['c', 'd']
118
+ a.intersection b, c
119
+
120
+ ```
121
+
108
122
  The set can also be set to expire (in seconds).
109
123
  ```ruby
110
124
  # expire in five minutes
@@ -0,0 +1,150 @@
1
+ require "redis"
2
+
3
+ class RedisSet
4
+ attr_reader :name
5
+
6
+ VERSION = "0.0.3"
7
+
8
+ class InvalidNameException < StandardError; end;
9
+ class InvalidRedisConfigException < StandardError; end;
10
+
11
+ def initialize(name, redis_or_options = {})
12
+ name = name.to_s if name.kind_of? Symbol
13
+
14
+ raise InvalidNameException.new unless name.kind_of?(String) && name.size > 0
15
+ @name = name
16
+ @redis = if redis_or_options.kind_of?(Redis)
17
+ redis_or_options
18
+ elsif redis_or_options.kind_of? Hash
19
+ ::Redis.new redis_or_options
20
+ elsif defined?(ActiveSupport::Cache::RedisStore) && redis_or_options.kind_of?(ActiveSupport::Cache::RedisStore)
21
+ @pooled = redis_or_options.data.kind_of?(ConnectionPool)
22
+ redis_or_options.data
23
+ elsif defined?(ConnectionPool) && redis_or_options.kind_of?(ConnectionPool)
24
+ @pooled = true
25
+ redis_or_options
26
+ else
27
+ raise InvalidRedisConfigException.new
28
+ end
29
+ end
30
+
31
+ def add *values
32
+ values = [values].flatten
33
+ with{|redis| redis.sadd name, values} if values.size > 0
34
+ end
35
+
36
+ alias push add
37
+
38
+ def add_with_count value
39
+ block_on_atomic_attempt { attempt_atomic_add_read_count value }
40
+ end
41
+
42
+ alias push_with_count add_with_count
43
+
44
+ def remove *values
45
+ values = [values].flatten
46
+ with{|redis|redis.srem name, values} if values.size > 0
47
+ end
48
+
49
+ def pop(amount = 1)
50
+ with{|redis| redis.spop name, amount}
51
+ end
52
+
53
+ def include? value
54
+ with{|redis| redis.sismember(name, value)}
55
+ end
56
+
57
+ def size
58
+ with{|redis| redis.scard name}
59
+ end
60
+
61
+ alias count size
62
+
63
+ def all
64
+ with{|redis| redis.smembers name}
65
+ end
66
+
67
+ def intersection *sets
68
+ sets = [sets].flatten
69
+ sets = sets.map do |s|
70
+ if s.kind_of?(self.class)
71
+ s.name
72
+ else
73
+ s
74
+ end
75
+ end
76
+
77
+ with{|redis| redis.sinter *sets }
78
+ end
79
+
80
+ def scan cursor = 0, amount = 10, match = "*"
81
+ with{|redis| redis.sscan name, cursor, :count => amount, :match => match}
82
+ end
83
+
84
+ def enumerator(slice_size = 10)
85
+ cursor = 0
86
+ Enumerator.new do |yielder|
87
+ loop do
88
+ cursor, items = scan cursor, slice_size
89
+ items.each do |item|
90
+ yielder << item
91
+ end
92
+ raise StopIteration if cursor.to_i.zero?
93
+ end
94
+ end
95
+ end
96
+
97
+ def clear
98
+ with{|redis| redis.del name}
99
+ []
100
+ end
101
+
102
+ alias flush clear
103
+
104
+ def expire seconds
105
+ with{|redis| redis.expire name, seconds}
106
+ end
107
+
108
+ private
109
+
110
+ def attempt_atomic_add_read_count value
111
+ attempt_atomic_write_read lambda { add value }, lambda { |multi, read_result| multi.scard name }
112
+ end
113
+
114
+ def block_on_atomic_attempt
115
+ begin
116
+ success, result = yield
117
+ #puts "success is #{success} and result is #{result}"
118
+ end while !success && result
119
+ result.value
120
+ end
121
+
122
+ def attempt_atomic_write_read write_op, read_op
123
+ success, write_result, read_result = false, nil, nil
124
+
125
+ with do |redis|
126
+ success = redis.watch(name) do
127
+ write_result = write_op.call
128
+ #if write_result
129
+ redis.multi do |multi|
130
+ read_result = read_op.call multi, write_result
131
+ end
132
+ #end
133
+ end
134
+ end
135
+
136
+ [success, read_result]
137
+ end
138
+
139
+ def with(&block)
140
+ if pooled?
141
+ @redis.with(&block)
142
+ else
143
+ block.call(@redis)
144
+ end
145
+ end
146
+
147
+ def pooled?
148
+ !!@pooled
149
+ end
150
+ end
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'redis/set'
4
+ require 'redis_set'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "redis-set"
8
- spec.version = Redis::Set::VERSION
8
+ spec.version = RedisSet::VERSION
9
9
  spec.authors = ["Misha Conway"]
10
10
  spec.email = ["mishaAconway@gmail.com"]
11
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-set
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Misha Conway
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-20 00:00:00.000000000 Z
11
+ date: 2019-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,7 +65,7 @@ files:
65
65
  - Rakefile
66
66
  - bin/console
67
67
  - bin/setup
68
- - lib/redis/set.rb
68
+ - lib/redis_set.rb
69
69
  - redis-set.gemspec
70
70
  homepage: https://github.com/MishaConway/ruby-redis-set
71
71
  licenses:
@@ -87,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
87
  version: '0'
88
88
  requirements: []
89
89
  rubyforge_project:
90
- rubygems_version: 2.6.7
90
+ rubygems_version: 2.6.14
91
91
  signing_key:
92
92
  specification_version: 4
93
93
  summary: Lightweight wrapper over redis sets.
@@ -1,139 +0,0 @@
1
- require "redis"
2
-
3
- class Redis
4
- class Set
5
- attr_reader :name
6
-
7
- VERSION = "0.0.2"
8
-
9
- class InvalidNameException < StandardError; end;
10
- class InvalidRedisConfigException < StandardError; end;
11
-
12
- def initialize(name, redis_or_options = {})
13
- name = name.to_s if name.kind_of? Symbol
14
-
15
- raise InvalidNameException.new unless name.kind_of?(String) && name.size > 0
16
- @name = name
17
- @redis = if redis_or_options.kind_of? Redis
18
- redis_or_options
19
- elsif redis_or_options.kind_of? Hash
20
- Redis.new redis_or_options
21
- else
22
- raise InvalidRedisConfigException.new
23
- end
24
- end
25
-
26
- def add value
27
- @redis.sadd name, value
28
- end
29
-
30
- alias push add
31
-
32
- def add_multi *values
33
- if values.size > 0
34
- values = values.first if 1 == values.size && values.first.kind_of?(Array)
35
- @redis.sadd name, values
36
- end
37
- end
38
-
39
- alias push_multi add_multi
40
-
41
- def add_with_count value
42
- block_on_atomic_attempt{ attempt_atomic_add_read_count value }
43
- end
44
-
45
- alias push_with_count add_with_count
46
-
47
- def remove value
48
- @redis.srem name, value
49
- end
50
-
51
- def remove_multi *values
52
- if values.size > 0
53
- values = values.first if 1 == values.size && values.first.kind_of?(Array)
54
- @redis.srem name, values
55
- end
56
- end
57
-
58
- def pop
59
- @redis.pop name, 1
60
- end
61
-
62
- def pop_multi amount
63
- @redis.pop name, amount
64
- end
65
-
66
- def include? value
67
- @redis.sismember(name, value)
68
- end
69
-
70
- def size
71
- @redis.scard name
72
- end
73
-
74
- alias count size
75
-
76
- def all
77
- @redis.smembers name
78
- end
79
-
80
- def scan cursor = 0, amount=10, match = "*"
81
- @redis.sscan name, cursor, :count => amount, :match => match
82
- end
83
-
84
- def enumerator(slice_size = 10)
85
- cursor = 0
86
- Enumerator.new do |yielder|
87
- loop do
88
- cursor, items = scan cursor, slice_size
89
- items.each do |item|
90
- yielder << item
91
- end
92
- raise StopIteration if cursor.to_i.zero?
93
- end
94
- end
95
- end
96
-
97
- def clear
98
- @redis.del name
99
- []
100
- end
101
-
102
- alias flush clear
103
-
104
- def expire seconds
105
- @redis.expire name, seconds
106
- end
107
-
108
- private
109
-
110
- def attempt_atomic_add_read_count value
111
- attempt_atomic_write_read lambda{ add value }, lambda{ |multi, read_result| multi.scard name}
112
- end
113
-
114
- def block_on_atomic_attempt
115
- begin
116
- success, result = yield
117
- #puts "success is #{success} and result is #{result}"
118
- end while !success && result
119
- result.value
120
- end
121
-
122
- def attempt_atomic_write_read write_op, read_op
123
-
124
- write_result, read_result = nil, nil
125
- success = @redis.watch(name) do
126
- write_result = write_op.call
127
- #if write_result
128
- @redis.multi do |multi|
129
- read_result = read_op.call multi, write_result
130
- end
131
- #end
132
- end
133
-
134
- [success, read_result]
135
- end
136
-
137
-
138
- end
139
- end