redis-set 0.0.2 → 0.0.3

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