protocol-redis 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Rakefile +2 -0
- data/benchmark/call.rb +55 -0
- data/lib/protocol/redis/connection.rb +3 -3
- data/lib/protocol/redis/methods.rb +2 -0
- data/lib/protocol/redis/methods/geospatial.rb +60 -19
- data/lib/protocol/redis/methods/sorted_sets.rb +82 -0
- data/lib/protocol/redis/methods/strings.rb +10 -12
- data/lib/protocol/redis/version.rb +1 -1
- data/tasks/generate.rake +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9a0af74e1d169a5d9f8b712a1211deb9c2ab510c969043073e685b5a4d4a99a
|
4
|
+
data.tar.gz: 7961d5412651f7969160e5b3844be5ab7db064b5b1f2ff6833ca17e12cc42233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fdf6ab96249d724ea77949cd073cb581f8ad58b96e3d54058e5f2e466ae2de7a947f327b44367a38d65939c2b8d8ed7a72f3e24a408f15871d25c35e45f271a
|
7
|
+
data.tar.gz: 27ca946edfed62633623d6876a04cdd36da92b95fbf0e21d5086b493580b1988d4d1a68e9f3ff1f99c1e9da4bc71b812688941b10d799c6dd6060a107c24427a
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/benchmark/call.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
|
24
|
+
require 'benchmark/ips'
|
25
|
+
|
26
|
+
GC.disable
|
27
|
+
|
28
|
+
def call(*arguments)
|
29
|
+
arguments.size
|
30
|
+
end
|
31
|
+
|
32
|
+
Benchmark.ips do |benchmark|
|
33
|
+
benchmark.time = 5
|
34
|
+
benchmark.warmup = 1
|
35
|
+
|
36
|
+
benchmark.report("*arguments") do |count|
|
37
|
+
while count > 0
|
38
|
+
arguments = ["foo", "bar", "baz"]
|
39
|
+
call(*arguments)
|
40
|
+
|
41
|
+
count -= 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
benchmark.report("argument, *arguments") do |count|
|
46
|
+
while count > 0
|
47
|
+
arguments = ["bar", "baz"]
|
48
|
+
call("foo", *arguments)
|
49
|
+
|
50
|
+
count -= 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
benchmark.compare!
|
55
|
+
end
|
@@ -139,11 +139,11 @@ module Protocol
|
|
139
139
|
# because each Redis command contains several lines. Flushing once per
|
140
140
|
# command is more efficient because it avoids unnecessary writes to the
|
141
141
|
# socket.
|
142
|
-
def write_lines(*
|
143
|
-
if
|
142
|
+
def write_lines(*arguments)
|
143
|
+
if arguments.empty?
|
144
144
|
@stream.write(CRLF)
|
145
145
|
else
|
146
|
-
|
146
|
+
arguments.each do |arg|
|
147
147
|
@stream.write(arg)
|
148
148
|
@stream.write(CRLF)
|
149
149
|
end
|
@@ -30,6 +30,7 @@ require_relative 'methods/counting'
|
|
30
30
|
require_relative 'methods/hashes'
|
31
31
|
require_relative 'methods/lists'
|
32
32
|
require_relative 'methods/strings'
|
33
|
+
require_relative 'methods/sorted_sets'
|
33
34
|
|
34
35
|
module Protocol
|
35
36
|
module Redis
|
@@ -44,6 +45,7 @@ module Protocol
|
|
44
45
|
|
45
46
|
klass.include Methods::Hashes
|
46
47
|
klass.include Methods::Lists
|
48
|
+
klass.include Methods::SortedSets
|
47
49
|
klass.include Methods::Strings
|
48
50
|
end
|
49
51
|
end
|
@@ -64,21 +64,25 @@ module Protocol
|
|
64
64
|
# @param latitude [Double]
|
65
65
|
# @param radius [Double]
|
66
66
|
# @param unit [Enum]
|
67
|
-
# @param
|
68
|
-
# @param
|
69
|
-
# @param
|
70
|
-
|
67
|
+
# @param count [Integer] Limit the number of results to at most this many.
|
68
|
+
# @param order [Symbol] `:ASC` Sort returned items from the nearest to the farthest, relative to the center. `:DESC` Sort returned items from the farthest to the nearest, relative to the center.
|
69
|
+
# @param with_coordinates [Boolean] Also return the longitude,latitude coordinates of the matching items.
|
70
|
+
# @param with_distance [Boolean] Also return the distance of the returned items from the specified center. The distance is returned in the same unit as the unit specified as the radius argument of the command.
|
71
|
+
# @param with_hash [Boolean] Also return the raw geohash-encoded sorted set score of the item, in the form of a 52 bit unsigned integer. This is only useful for low level hacks or debugging and is otherwise of little interest for the general user.
|
72
|
+
# @param store [Key]
|
73
|
+
# @param store_distance [Key]
|
74
|
+
def georadius(key, longitude, latitude, radius, unit = "m", with_coordinates: false, with_distance: false, with_hash: false, count: nil, order: nil, store: nil, store_distance: nil)
|
71
75
|
arguments = [key, longitude, latitude, radius, unit]
|
72
76
|
|
73
|
-
if
|
77
|
+
if with_coordinates
|
74
78
|
arguments.append("WITHCOORD")
|
75
79
|
end
|
76
80
|
|
77
|
-
if
|
81
|
+
if with_distance
|
78
82
|
arguments.append("WITHDIST")
|
79
83
|
end
|
80
84
|
|
81
|
-
if
|
85
|
+
if with_hash
|
82
86
|
arguments.append("WITHHASH")
|
83
87
|
end
|
84
88
|
|
@@ -86,15 +90,28 @@ module Protocol
|
|
86
90
|
arguments.append("COUNT", count)
|
87
91
|
end
|
88
92
|
|
93
|
+
if order
|
94
|
+
arguments.append(order)
|
95
|
+
end
|
96
|
+
|
97
|
+
readonly = true
|
98
|
+
|
89
99
|
if store
|
90
100
|
arguments.append("STORE", store)
|
101
|
+
readonly = false
|
91
102
|
end
|
92
103
|
|
93
|
-
if
|
104
|
+
if store_distance
|
94
105
|
arguments.append("STOREDIST", storedist)
|
106
|
+
readonly = false
|
95
107
|
end
|
96
108
|
|
97
|
-
|
109
|
+
# https://redis.io/commands/georadius#read-only-variants
|
110
|
+
if readonly
|
111
|
+
call("GEORADIUS_RO", *arguments)
|
112
|
+
else
|
113
|
+
call("GEORADIUS", *arguments)
|
114
|
+
end
|
98
115
|
end
|
99
116
|
|
100
117
|
# Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member. O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.
|
@@ -103,22 +120,25 @@ module Protocol
|
|
103
120
|
# @param member [String]
|
104
121
|
# @param radius [Double]
|
105
122
|
# @param unit [Enum]
|
106
|
-
# @param
|
107
|
-
# @param
|
108
|
-
# @param
|
109
|
-
# @param
|
110
|
-
|
123
|
+
# @param count [Integer] Limit the number of results to at most this many.
|
124
|
+
# @param order [Symbol] `:ASC` Sort returned items from the nearest to the farthest, relative to the center. `:DESC` Sort returned items from the farthest to the nearest, relative to the center.
|
125
|
+
# @param with_coordinates [Boolean] Also return the longitude,latitude coordinates of the matching items.
|
126
|
+
# @param with_distance [Boolean] Also return the distance of the returned items from the specified center. The distance is returned in the same unit as the unit specified as the radius argument of the command.
|
127
|
+
# @param with_hash [Boolean] Also return the raw geohash-encoded sorted set score of the item, in the form of a 52 bit unsigned integer. This is only useful for low level hacks or debugging and is otherwise of little interest for the general user.
|
128
|
+
# @param store [Key]
|
129
|
+
# @param store_distance [Key]
|
130
|
+
def georadiusbymember(key, member, radius, unit = "m", with_coordinates: false, with_distance: false, with_hash: false, count: nil, order: nil, store: nil, store_distance: nil)
|
111
131
|
arguments = [key, member, radius, unit]
|
112
132
|
|
113
|
-
if
|
133
|
+
if with_coordinates
|
114
134
|
arguments.append("WITHCOORD")
|
115
135
|
end
|
116
136
|
|
117
|
-
if
|
137
|
+
if with_distance
|
118
138
|
arguments.append("WITHDIST")
|
119
139
|
end
|
120
140
|
|
121
|
-
if
|
141
|
+
if with_hash
|
122
142
|
arguments.append("WITHHASH")
|
123
143
|
end
|
124
144
|
|
@@ -126,15 +146,36 @@ module Protocol
|
|
126
146
|
arguments.append("COUNT", count)
|
127
147
|
end
|
128
148
|
|
149
|
+
if order
|
150
|
+
arguments.append(order)
|
151
|
+
end
|
152
|
+
|
129
153
|
if store
|
130
154
|
arguments.append("STORE", store)
|
131
155
|
end
|
132
156
|
|
133
|
-
if
|
157
|
+
if store_distance
|
134
158
|
arguments.append("STOREDIST", storedist)
|
135
159
|
end
|
136
160
|
|
137
|
-
|
161
|
+
readonly = true
|
162
|
+
|
163
|
+
if store
|
164
|
+
arguments.append("STORE", store)
|
165
|
+
readonly = false
|
166
|
+
end
|
167
|
+
|
168
|
+
if store_distance
|
169
|
+
arguments.append("STOREDIST", storedist)
|
170
|
+
readonly = false
|
171
|
+
end
|
172
|
+
|
173
|
+
# https://redis.io/commands/georadius#read-only-variants
|
174
|
+
if readonly
|
175
|
+
call("GEORADIUSBYMEMBER_RO", *arguments)
|
176
|
+
else
|
177
|
+
call("GEORADIUSBYMEMBER", *arguments)
|
178
|
+
end
|
138
179
|
end
|
139
180
|
end
|
140
181
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Dimitry Chopey.
|
4
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
|
24
|
+
module Protocol
|
25
|
+
module Redis
|
26
|
+
module Methods
|
27
|
+
module SortedSets
|
28
|
+
# Add one or more members to a sorted set, or update its score if it already exists. O(log(N)) for each item added, where N is the number of elements in the sorted set.
|
29
|
+
# @see https://redis.io/commands/zadd
|
30
|
+
# @param key [Key]
|
31
|
+
# @param score [Double]
|
32
|
+
# @param member [String]
|
33
|
+
# @param others [Array] an array of `score`, `member` elements.
|
34
|
+
# @param update [Boolean, nil] If true, only update elements that already exist (never add elements). If false, don't update existing elements (only add new elements).
|
35
|
+
# @param change [Boolean] Modify the return value from the number of new elements added,
|
36
|
+
# to the total number of elements changed; changed elements are new elements added
|
37
|
+
# and elements already existing for which the score was updated.
|
38
|
+
# @param increment [Boolean] When this option is specified ZADD acts like ZINCRBY;
|
39
|
+
# only one score-element pair can be specified in this mode.
|
40
|
+
def zadd(key, score, member, *others, update: nil, change: false, increment: false)
|
41
|
+
arguments = ["ZADD", key]
|
42
|
+
|
43
|
+
if update == true
|
44
|
+
arguments << "XX"
|
45
|
+
elsif update == false
|
46
|
+
arguments << "NX"
|
47
|
+
end
|
48
|
+
|
49
|
+
arguments << "CH" if change
|
50
|
+
arguments << "INCR" if increment
|
51
|
+
|
52
|
+
arguments << score << member
|
53
|
+
arguments.concat(others)
|
54
|
+
|
55
|
+
call(*arguments)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return a range of members in a sorted set, by index. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.
|
59
|
+
# @see https://redis.io/commands/zrange
|
60
|
+
# @param key [Key]
|
61
|
+
# @param start [Integer]
|
62
|
+
# @param stop [Integer]
|
63
|
+
# @param with_scores [Boolean] Return the scores of the elements together with the elements.
|
64
|
+
def zrange(key, start, stop, with_scores: false)
|
65
|
+
arguments = [start, stop]
|
66
|
+
|
67
|
+
arguments << "WITHSCORES" if with_scores
|
68
|
+
|
69
|
+
call("ZRANGE", key, *arguments)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Remove one or more members from a sorted set. O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.
|
73
|
+
# @see https://redis.io/commands/zrem
|
74
|
+
# @param key [Key]
|
75
|
+
# @param member [String]
|
76
|
+
def zrem(key, member)
|
77
|
+
call("ZREM", key, member)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -145,24 +145,22 @@ module Protocol
|
|
145
145
|
# @param key [Key]
|
146
146
|
# @param value [String]
|
147
147
|
# @param expiration [Enum]
|
148
|
-
# @param
|
149
|
-
def set(key, value,
|
148
|
+
# @param update [Boolean, nil] If true, only update elements that already exist (never add elements). If false, don't update existing elements (only add new elements).
|
149
|
+
def set(key, value, update: nil, seconds: nil, milliseconds: nil)
|
150
150
|
arguments = []
|
151
151
|
|
152
|
-
if
|
153
|
-
arguments << 'EX'
|
154
|
-
arguments << options[:seconds]
|
152
|
+
if seconds
|
153
|
+
arguments << 'EX' << seconds
|
155
154
|
end
|
156
155
|
|
157
|
-
if
|
158
|
-
arguments << 'PX'
|
159
|
-
arguments << options[:milliseconds]
|
156
|
+
if milliseconds
|
157
|
+
arguments << 'PX' << milliseconds
|
160
158
|
end
|
161
159
|
|
162
|
-
if
|
163
|
-
arguments <<
|
164
|
-
elsif
|
165
|
-
arguments <<
|
160
|
+
if update == true
|
161
|
+
arguments << "XX"
|
162
|
+
elsif update == false
|
163
|
+
arguments << "NX"
|
166
164
|
end
|
167
165
|
|
168
166
|
return call('SET', key, value, *arguments)
|
data/tasks/generate.rake
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-02-
|
12
|
+
date: 2020-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: async-http
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- Gemfile
|
125
125
|
- README.md
|
126
126
|
- Rakefile
|
127
|
+
- benchmark/call.rb
|
127
128
|
- lib/protocol/redis.rb
|
128
129
|
- lib/protocol/redis/connection.rb
|
129
130
|
- lib/protocol/redis/error.rb
|
@@ -135,6 +136,7 @@ files:
|
|
135
136
|
- lib/protocol/redis/methods/hashes.rb
|
136
137
|
- lib/protocol/redis/methods/lists.rb
|
137
138
|
- lib/protocol/redis/methods/server.rb
|
139
|
+
- lib/protocol/redis/methods/sorted_sets.rb
|
138
140
|
- lib/protocol/redis/methods/strings.rb
|
139
141
|
- lib/protocol/redis/version.rb
|
140
142
|
- protocol-redis.gemspec
|