em-couchbase 0.1.0
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.
- data/.gitignore +5 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/HISTORY.markdown +7 -0
- data/LICENSE +201 -0
- data/README.markdown +17 -0
- data/Rakefile +22 -0
- data/em-couchbase.gemspec +48 -0
- data/lib/em-couchbase/client.rb +183 -0
- data/lib/em-couchbase/configuration.rb +139 -0
- data/lib/em-couchbase/error.rb +147 -0
- data/lib/em-couchbase/node.rb +116 -0
- data/lib/em-couchbase/packet.rb +208 -0
- data/lib/em-couchbase/result.rb +48 -0
- data/lib/em-couchbase/util.rb +97 -0
- data/lib/em-couchbase/version.rb +26 -0
- data/lib/em-couchbase.rb +46 -0
- data/tasks/doc.rake +25 -0
- data/tasks/package.rake +28 -0
- data/tasks/test.rake +35 -0
- data/tasks/util.rake +21 -0
- metadata +195 -0
@@ -0,0 +1,147 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module Protocols
|
20
|
+
|
21
|
+
module Couchbase
|
22
|
+
|
23
|
+
module Error
|
24
|
+
|
25
|
+
# @return [Couchbase::Error::Base]
|
26
|
+
def self.map_error_code(code)
|
27
|
+
case code
|
28
|
+
when 0x00 # PROTOCOL_BINARY_RESPONSE_SUCCESS
|
29
|
+
nil
|
30
|
+
when 0x01 # PROTOCOL_BINARY_RESPONSE_KEY_ENOENT
|
31
|
+
NotFound
|
32
|
+
when 0x02 # PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS
|
33
|
+
KeyExists
|
34
|
+
when 0x03 # PROTOCOL_BINARY_RESPONSE_E2BIG
|
35
|
+
TooBig
|
36
|
+
when 0x04 # PROTOCOL_BINARY_RESPONSE_EINVAL
|
37
|
+
Invalid
|
38
|
+
when 0x05 # PROTOCOL_BINARY_RESPONSE_NOT_STORED
|
39
|
+
NotStored
|
40
|
+
when 0x06 # PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL
|
41
|
+
DeltaBadval
|
42
|
+
when 0x07 # PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET
|
43
|
+
NotMyVbucket
|
44
|
+
when 0x20 # PROTOCOL_BINARY_RESPONSE_AUTH_ERROR
|
45
|
+
Auth
|
46
|
+
when 0x22 # PROTOCOL_BINARY_RESPONSE_ERANGE
|
47
|
+
Range
|
48
|
+
when 0x81 # PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND
|
49
|
+
UnknownCommand
|
50
|
+
when 0x82 # PROTOCOL_BINARY_RESPONSE_ENOMEM
|
51
|
+
NoMemory
|
52
|
+
when 0x83 # PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED
|
53
|
+
NotSupported
|
54
|
+
when 0x84 # PROTOCOL_BINARY_RESPONSE_EINTERNAL
|
55
|
+
Internal
|
56
|
+
when 0x85 # PROTOCOL_BINARY_RESPONSE_EBUSY
|
57
|
+
Busy
|
58
|
+
else
|
59
|
+
Base
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Base < ::RuntimeError
|
64
|
+
# @return [Fixnum] the error code from libcouchbase
|
65
|
+
attr_accessor :error
|
66
|
+
# @return [String] the key which generated error */
|
67
|
+
attr_accessor :key
|
68
|
+
# @return [Fixnum] the version of the key (+nil+ unless accessible)
|
69
|
+
attr_accessor :cas
|
70
|
+
# @return [Symbol] the operation (+nil+ unless accessible)
|
71
|
+
attr_accessor :operation
|
72
|
+
end
|
73
|
+
|
74
|
+
# Authentication error
|
75
|
+
class Auth < Base; end
|
76
|
+
|
77
|
+
# The given bucket not found in the cluster */
|
78
|
+
class BucketNotFound < Base; end
|
79
|
+
|
80
|
+
# The cluster is too busy now. Try again later */
|
81
|
+
class Busy < Base; end
|
82
|
+
|
83
|
+
# The given value is not a number */
|
84
|
+
class DeltaBadval < Base; end
|
85
|
+
|
86
|
+
# Internal error */
|
87
|
+
class Internal < Base; end
|
88
|
+
|
89
|
+
# Invalid arguments */
|
90
|
+
class Invalid < Base; end
|
91
|
+
|
92
|
+
# Key already exists */
|
93
|
+
class KeyExists < Base; end
|
94
|
+
|
95
|
+
# Network error */
|
96
|
+
class Network < Base; end
|
97
|
+
|
98
|
+
# Out of memory error */
|
99
|
+
class NoMemory < Base; end
|
100
|
+
|
101
|
+
# No such key */
|
102
|
+
class NotFound < Base; end
|
103
|
+
|
104
|
+
# The vbucket is not located on this server */
|
105
|
+
class NotMyVbucket < Base; end
|
106
|
+
|
107
|
+
# Not stored */
|
108
|
+
class NotStored < Base; end
|
109
|
+
|
110
|
+
# Not supported */
|
111
|
+
class NotSupported < Base; end
|
112
|
+
|
113
|
+
# Invalid range */
|
114
|
+
class Range < Base; end
|
115
|
+
|
116
|
+
# Temporary failure. Try again later */
|
117
|
+
class TemporaryFail < Base; end
|
118
|
+
|
119
|
+
# Object too big */
|
120
|
+
class TooBig < Base; end
|
121
|
+
|
122
|
+
# Unknown command */
|
123
|
+
class UnknownCommand < Base; end
|
124
|
+
|
125
|
+
# Unknown host */
|
126
|
+
class UnknownHost < Base; end
|
127
|
+
|
128
|
+
# Failed to decode or encode value */
|
129
|
+
class ValueFormat < Base; end
|
130
|
+
|
131
|
+
# Protocol error */
|
132
|
+
class Protocol < Base; end
|
133
|
+
|
134
|
+
# Timeout error */
|
135
|
+
class Timeout < Base; end
|
136
|
+
|
137
|
+
# Connect error */
|
138
|
+
class Connect < Base; end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module Protocols
|
20
|
+
|
21
|
+
module Couchbase
|
22
|
+
|
23
|
+
class Node < EventMachine::Connection
|
24
|
+
include EM::Deferrable
|
25
|
+
|
26
|
+
attr_reader :client
|
27
|
+
|
28
|
+
attr_reader :proxy
|
29
|
+
attr_reader :direct
|
30
|
+
attr_reader :couch
|
31
|
+
attr_reader :admin
|
32
|
+
attr_reader :status
|
33
|
+
attr_reader :version
|
34
|
+
|
35
|
+
def initialize(options = {})
|
36
|
+
@data = "" # naive buffer implementation
|
37
|
+
options.each do |k, v|
|
38
|
+
if respond_to?(k)
|
39
|
+
instance_variable_set("@#{k}", v)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.connect(options)
|
45
|
+
host, port = options[:direct].split(':')
|
46
|
+
EventMachine.connect(host, port, self, options)
|
47
|
+
end
|
48
|
+
|
49
|
+
def receive_data(data)
|
50
|
+
@data << data
|
51
|
+
Packet.parse(@data) do |op, opaque, result|
|
52
|
+
if result.error.class == Error::NotMyVbucket
|
53
|
+
client.retry(:not_my_vbucket, opaque)
|
54
|
+
else
|
55
|
+
if op == :sasl_auth
|
56
|
+
raise result.error unless result.success?
|
57
|
+
else
|
58
|
+
client.run_callback(opaque, result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def set(opaque, vbucket, key, value, options = {})
|
65
|
+
packet = Packet.build(opaque, vbucket, :set,
|
66
|
+
key, value,
|
67
|
+
options[:flags],
|
68
|
+
options[:expiration],
|
69
|
+
options[:cas])
|
70
|
+
client.register_packet(opaque, packet)
|
71
|
+
send_data(packet)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param opaque [Fixnum]
|
75
|
+
# @param pairs [Array] array of tuples +[opaque, vbucket, key]+
|
76
|
+
# @param options [Hash]
|
77
|
+
def get(tuples, options = {})
|
78
|
+
packets = ""
|
79
|
+
tuples.each do |opaque, vbucket, key|
|
80
|
+
packet = Packet.build(opaque, vbucket, :get, key)
|
81
|
+
client.register_packet(opaque, packet)
|
82
|
+
packets << packet
|
83
|
+
end
|
84
|
+
send_data(packets)
|
85
|
+
end
|
86
|
+
|
87
|
+
def ==(other)
|
88
|
+
other = Node.new(other) if other.is_a?(Hash)
|
89
|
+
self.class == other.class &&
|
90
|
+
self.direct == other.direct &&
|
91
|
+
self.couch == other.couch &&
|
92
|
+
self.status == other.status
|
93
|
+
end
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
def authenticate
|
98
|
+
if client.config.sasl_password
|
99
|
+
# currently Couchbase supports PLAIN only authentication
|
100
|
+
# this is why it doesn't ask list of mechanisms
|
101
|
+
packet = Packet.build(0, 0, :sasl_auth, "PLAIN",
|
102
|
+
client.config.bucket_name,
|
103
|
+
client.config.sasl_password)
|
104
|
+
send_data(packet)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def connection_completed
|
109
|
+
authenticate
|
110
|
+
succeed
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module Protocols
|
20
|
+
|
21
|
+
module Couchbase
|
22
|
+
|
23
|
+
module Packet
|
24
|
+
|
25
|
+
# uint8_t magic
|
26
|
+
# uint8_t opcode
|
27
|
+
# uint16_t keylen
|
28
|
+
# uint8_t extlen
|
29
|
+
# uint8_t datatype
|
30
|
+
# uint16_t vbucket
|
31
|
+
# uint32_t bodylen
|
32
|
+
# uint32_t opaque
|
33
|
+
# uint64_t cas
|
34
|
+
REQUEST_HEADER_FMT = "CCnCCnNNQ"
|
35
|
+
REQUEST_HEADER_SIZE = 24 # bytes
|
36
|
+
|
37
|
+
# Sum of lengths of fields below
|
38
|
+
# uint8_t magic
|
39
|
+
# uint8_t opcode
|
40
|
+
# uint16_t keylen
|
41
|
+
# uint8_t extlen
|
42
|
+
# uint8_t datatype
|
43
|
+
# uint16_t status
|
44
|
+
# uint32_t bodylen
|
45
|
+
# uint32_t opaque
|
46
|
+
# uint64_t cas
|
47
|
+
RESPONSE_HEADER_FMT = "CCnCCnNNQ"
|
48
|
+
RESPONSE_HEADER_SIZE = 24 # bytes
|
49
|
+
|
50
|
+
CMD_GET = 0x00
|
51
|
+
CMD_SET = 0x01
|
52
|
+
CMD_ADD = 0x02
|
53
|
+
CMD_REPLACE = 0x03
|
54
|
+
CMD_DELETE = 0x04
|
55
|
+
CMD_INCREMENT = 0x05
|
56
|
+
CMD_DECREMENT = 0x06
|
57
|
+
CMD_QUIT = 0x07
|
58
|
+
CMD_FLUSH = 0x08
|
59
|
+
CMD_GETQ = 0x09
|
60
|
+
CMD_NOOP = 0x0a
|
61
|
+
CMD_VERSION = 0x0b
|
62
|
+
CMD_GETK = 0x0c
|
63
|
+
CMD_GETKQ = 0x0d
|
64
|
+
CMD_APPEND = 0x0e
|
65
|
+
CMD_PREPEND = 0x0f
|
66
|
+
CMD_STAT = 0x10
|
67
|
+
CMD_SETQ = 0x11
|
68
|
+
CMD_ADDQ = 0x12
|
69
|
+
CMD_REPLACEQ = 0x13
|
70
|
+
CMD_DELETEQ = 0x14
|
71
|
+
CMD_INCREMENTQ = 0x15
|
72
|
+
CMD_DECREMENTQ = 0x16
|
73
|
+
CMD_QUITQ = 0x17
|
74
|
+
CMD_FLUSHQ = 0x18
|
75
|
+
CMD_APPENDQ = 0x19
|
76
|
+
CMD_PREPENDQ = 0x1a
|
77
|
+
CMD_VERBOSITY = 0x1b
|
78
|
+
CMD_TOUCH = 0x1c
|
79
|
+
CMD_GAT = 0x1d
|
80
|
+
CMD_GATQ = 0x1e
|
81
|
+
CMD_SASL_LIST_MECHS = 0x20
|
82
|
+
CMD_SASL_AUTH = 0x21
|
83
|
+
CMD_SASL_STEP = 0x22
|
84
|
+
|
85
|
+
def self.build(opaque, vbucket, opcode, *args)
|
86
|
+
case opcode
|
87
|
+
when :set
|
88
|
+
key, value, flags, expiration, cas = args.shift(5)
|
89
|
+
bodylen = key.size + value.size + 8
|
90
|
+
[
|
91
|
+
0x80, # uint8_t magic
|
92
|
+
CMD_SET, # uint8_t opcode
|
93
|
+
key.size, # uint16_t keylen
|
94
|
+
8, # uint8_t extlen (flags + expiration)
|
95
|
+
0, # uint8_t datatype
|
96
|
+
vbucket, # uint16_t vbucket
|
97
|
+
bodylen, # uint32_t bodylen
|
98
|
+
opaque || 0, # uint32_t opaque
|
99
|
+
cas || 0, # uint64_t cas
|
100
|
+
flags || 0, # uint32_t flags
|
101
|
+
expiration || 0, # uint32_t expiration
|
102
|
+
key,
|
103
|
+
value
|
104
|
+
].pack("#{REQUEST_HEADER_FMT}NNa*a*")
|
105
|
+
when :get
|
106
|
+
key = args.shift
|
107
|
+
bodylen = key.size
|
108
|
+
[
|
109
|
+
0x80, # uint8_t magic
|
110
|
+
CMD_GET, # uint8_t opcode
|
111
|
+
key.size, # uint16_t keylen
|
112
|
+
0, # uint8_t extlen
|
113
|
+
0, # uint8_t datatype
|
114
|
+
vbucket, # uint16_t vbucket
|
115
|
+
bodylen, # uint32_t bodylen
|
116
|
+
opaque || 0, # uint32_t opaque
|
117
|
+
0, # uint64_t cas
|
118
|
+
key
|
119
|
+
].pack("#{REQUEST_HEADER_FMT}a*")
|
120
|
+
when :sasl_auth
|
121
|
+
mech, username, password = args.shift(3)
|
122
|
+
value = "\0#{username}\0#{password}"
|
123
|
+
bodylen = mech.size + value.size
|
124
|
+
[
|
125
|
+
0x80, # uint8_t magic
|
126
|
+
CMD_SASL_AUTH, # uint8_t opcode
|
127
|
+
mech.size, # uint16_t keylen
|
128
|
+
0, # uint8_t extlen
|
129
|
+
0, # uint8_t datatype
|
130
|
+
0, # uint16_t vbucket
|
131
|
+
bodylen, # uint32_t bodylen
|
132
|
+
0, # uint32_t opaque
|
133
|
+
0, # uint64_t cas
|
134
|
+
mech,
|
135
|
+
value
|
136
|
+
].pack("#{REQUEST_HEADER_FMT}a*a*")
|
137
|
+
else
|
138
|
+
raise Couchbase::Error::UnknownCommand, [opcode, *args].inspect
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.parse(data)
|
143
|
+
while data.length >= RESPONSE_HEADER_SIZE
|
144
|
+
header = data[0...RESPONSE_HEADER_SIZE]
|
145
|
+
( magic,
|
146
|
+
opcode,
|
147
|
+
keylen,
|
148
|
+
extlen,
|
149
|
+
datatype,
|
150
|
+
status,
|
151
|
+
bodylen,
|
152
|
+
opaque,
|
153
|
+
cas ) = header.unpack(RESPONSE_HEADER_FMT)
|
154
|
+
|
155
|
+
if magic != 0x81
|
156
|
+
fail Couchbase::Error::Protocol.new "Broken packet: #{header.inspect}"
|
157
|
+
end
|
158
|
+
|
159
|
+
if data.size < bodylen + RESPONSE_HEADER_SIZE
|
160
|
+
return # need moar data
|
161
|
+
else
|
162
|
+
data[0...RESPONSE_HEADER_SIZE] = ""
|
163
|
+
end
|
164
|
+
|
165
|
+
ext = data[0...extlen]
|
166
|
+
data[0...extlen] = ""
|
167
|
+
|
168
|
+
key = data[0...keylen]
|
169
|
+
data[0...keylen] = ""
|
170
|
+
|
171
|
+
vallen = bodylen - extlen - keylen
|
172
|
+
body = data[0...vallen]
|
173
|
+
data[0...vallen] = ""
|
174
|
+
|
175
|
+
result = Result.new(:key => key,
|
176
|
+
:value => body,
|
177
|
+
:status => status,
|
178
|
+
:cas => cas)
|
179
|
+
|
180
|
+
case opcode
|
181
|
+
when CMD_SET
|
182
|
+
result.operation = :set
|
183
|
+
when CMD_SASL_AUTH
|
184
|
+
result.operation = :sasl_auth
|
185
|
+
when CMD_GET
|
186
|
+
result.operation = :get
|
187
|
+
result.flags, _ = ext.unpack("N")
|
188
|
+
else
|
189
|
+
raise Couchbase::Error::UnknownCommand, header.inspect
|
190
|
+
end
|
191
|
+
|
192
|
+
if error_class = Couchbase::Error.map_error_code(status)
|
193
|
+
result.error = error_class.new(body)
|
194
|
+
result.error.error = status
|
195
|
+
result.error.key = key
|
196
|
+
result.error.cas = cas
|
197
|
+
result.error.operation = result.operation
|
198
|
+
end
|
199
|
+
yield(result.operation, opaque, result)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module Protocols
|
20
|
+
|
21
|
+
module Couchbase
|
22
|
+
|
23
|
+
class Result
|
24
|
+
attr_accessor :cas
|
25
|
+
attr_accessor :error
|
26
|
+
attr_accessor :flags
|
27
|
+
attr_accessor :key
|
28
|
+
attr_accessor :node
|
29
|
+
attr_accessor :operation
|
30
|
+
attr_accessor :value
|
31
|
+
|
32
|
+
def initialize(attributes = {})
|
33
|
+
attributes.each do |k, v|
|
34
|
+
if respond_to?(k)
|
35
|
+
instance_variable_set("@#{k}", v)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def success?
|
41
|
+
!@error
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#/* The crc32 functions and data was originally written by Spencer
|
2
|
+
# * Garrett <srg@quick.com> and was gleaned from the PostgreSQL source
|
3
|
+
# * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at
|
4
|
+
# * src/usr.bin/cksum/crc32.c.
|
5
|
+
# */
|
6
|
+
|
7
|
+
|
8
|
+
module EventMachine
|
9
|
+
module Protocols
|
10
|
+
|
11
|
+
module Couchbase
|
12
|
+
|
13
|
+
module Util
|
14
|
+
|
15
|
+
CRC32TAB = [
|
16
|
+
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
17
|
+
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
18
|
+
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
19
|
+
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
20
|
+
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
21
|
+
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
22
|
+
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
23
|
+
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
24
|
+
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
25
|
+
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
26
|
+
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
27
|
+
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
28
|
+
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
29
|
+
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
30
|
+
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
31
|
+
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
32
|
+
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
33
|
+
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
34
|
+
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
35
|
+
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
36
|
+
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
37
|
+
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
38
|
+
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
39
|
+
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
40
|
+
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
41
|
+
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
42
|
+
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
43
|
+
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
44
|
+
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
45
|
+
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
46
|
+
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
47
|
+
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
48
|
+
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
49
|
+
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
50
|
+
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
51
|
+
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
52
|
+
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
53
|
+
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
54
|
+
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
55
|
+
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
56
|
+
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
57
|
+
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
58
|
+
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
59
|
+
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
60
|
+
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
61
|
+
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
62
|
+
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
63
|
+
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
64
|
+
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
65
|
+
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
66
|
+
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
67
|
+
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
68
|
+
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
69
|
+
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
70
|
+
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
71
|
+
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
72
|
+
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
73
|
+
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
74
|
+
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
75
|
+
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
76
|
+
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
77
|
+
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
78
|
+
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
79
|
+
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
80
|
+
]
|
81
|
+
|
82
|
+
|
83
|
+
def self.crc32_hash(key)
|
84
|
+
crc = 2 ** 32 - 1
|
85
|
+
key.bytes.each do |ch|
|
86
|
+
crc = (crc >> 8) ^ CRC32TAB[(crc ^ ch) & 0xff]
|
87
|
+
end
|
88
|
+
return ((~crc) >> 16) & 0x7fff
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2011, 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module Protocols
|
20
|
+
|
21
|
+
module Couchbase
|
22
|
+
VERSION = "0.1.0"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/em-couchbase.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2012 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'em-couchbase/version'
|
19
|
+
require 'yajl/json_gem'
|
20
|
+
# to use fixes from eventmachine master branch
|
21
|
+
require 'eventmachine-le'
|
22
|
+
require 'em-http'
|
23
|
+
require 'uri'
|
24
|
+
require 'em-couchbase/util'
|
25
|
+
require 'em-couchbase/error'
|
26
|
+
require 'em-couchbase/result'
|
27
|
+
require 'em-couchbase/packet'
|
28
|
+
require 'em-couchbase/node'
|
29
|
+
require 'em-couchbase/configuration'
|
30
|
+
require 'em-couchbase/client'
|
31
|
+
|
32
|
+
module EventMachine
|
33
|
+
module Protocols
|
34
|
+
|
35
|
+
module Couchbase
|
36
|
+
|
37
|
+
def self.connect(options = {})
|
38
|
+
client = Client.new
|
39
|
+
client.connect(options)
|
40
|
+
client
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|