libcouchbase 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libcouchbase/.gitignore +2 -0
- data/ext/libcouchbase/CMakeLists.txt +5 -7
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +34 -14
- data/ext/libcouchbase/configure.pl +1 -1
- data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +1 -0
- data/ext/libcouchbase/src/auth.cc +10 -0
- data/ext/libcouchbase/src/bootstrap.cc +216 -0
- data/ext/libcouchbase/src/bootstrap.h +50 -39
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +24 -24
- data/ext/libcouchbase/src/connspec.cc +30 -1
- data/ext/libcouchbase/src/connspec.h +17 -0
- data/ext/libcouchbase/src/dns-srv.cc +143 -0
- data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
- data/ext/libcouchbase/src/getconfig.cc +73 -0
- data/ext/libcouchbase/src/handler.cc +84 -85
- data/ext/libcouchbase/src/hostlist.cc +0 -1
- data/ext/libcouchbase/src/hostlist.h +6 -1
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +9 -29
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +22 -26
- data/ext/libcouchbase/src/instance.cc +102 -28
- data/ext/libcouchbase/src/internal.h +47 -29
- data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
- data/ext/libcouchbase/src/jsparse/parser.h +91 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
- data/ext/libcouchbase/src/lcbio/connect.h +9 -2
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
- data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
- data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
- data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
- data/ext/libcouchbase/src/nodeinfo.cc +4 -8
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
- data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
- data/ext/libcouchbase/src/operations/durability.cc +643 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +200 -137
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
- data/ext/libcouchbase/src/retryq.cc +394 -0
- data/ext/libcouchbase/src/retryq.h +116 -104
- data/ext/libcouchbase/src/settings.h +2 -1
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/trace.h +8 -8
- data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
- data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
- data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
- data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- metadata +36 -39
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/getconfig.c +0 -100
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
- data/ext/libcouchbase/src/operations/durability.c +0 -668
- data/ext/libcouchbase/src/packetutils.c +0 -60
- data/ext/libcouchbase/src/retryq.c +0 -424
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -19,23 +19,30 @@
|
|
19
19
|
#include "trace.h"
|
20
20
|
#include "durability_internal.h"
|
21
21
|
|
22
|
-
|
23
|
-
mc_REQDATAEX base;
|
22
|
+
struct DurStoreCtx : mc_REQDATAEX {
|
24
23
|
lcb_t instance;
|
25
24
|
lcb_U16 persist_to;
|
26
25
|
lcb_U16 replicate_to;
|
27
|
-
|
26
|
+
|
27
|
+
static mc_REQDATAPROCS proctable;
|
28
|
+
|
29
|
+
DurStoreCtx(lcb_t instance_, lcb_U16 persist_, lcb_U16 replicate_,
|
30
|
+
const void *cookie_)
|
31
|
+
: mc_REQDATAEX(cookie_, proctable, gethrtime()),
|
32
|
+
instance(instance_), persist_to(persist_), replicate_to(replicate_) {
|
33
|
+
}
|
34
|
+
};
|
28
35
|
|
29
36
|
/** Observe stuff */
|
30
37
|
static void
|
31
|
-
handle_dur_storecb(mc_PIPELINE
|
38
|
+
handle_dur_storecb(mc_PIPELINE *, mc_PACKET *pkt,
|
32
39
|
lcb_error_t err, const void *arg)
|
33
40
|
{
|
34
41
|
lcb_RESPCALLBACK cb;
|
35
42
|
lcb_RESPSTOREDUR resp = { 0 };
|
36
43
|
lcb_CMDENDURE dcmd = { 0 };
|
37
44
|
const lcb_MUTATION_TOKEN *mt;
|
38
|
-
|
45
|
+
DurStoreCtx *dctx = static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
|
39
46
|
lcb_MULTICMD_CTX *mctx;
|
40
47
|
lcb_durability_opts_t opts = { 0 };
|
41
48
|
const lcb_RESPSTORE *sresp = (const lcb_RESPSTORE *)arg;
|
@@ -78,7 +85,7 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
|
|
78
85
|
|
79
86
|
if (err == LCB_SUCCESS) {
|
80
87
|
/* Everything OK? */
|
81
|
-
|
88
|
+
delete dctx;
|
82
89
|
return;
|
83
90
|
}
|
84
91
|
|
@@ -92,20 +99,15 @@ handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
|
|
92
99
|
resp.dur_resp = &dresp;
|
93
100
|
cb = lcb_find_callback(dctx->instance, LCB_CALLBACK_STOREDUR);
|
94
101
|
cb(dctx->instance, LCB_CALLBACK_STOREDUR, (const lcb_RESPBASE*)&resp);
|
95
|
-
|
102
|
+
delete dctx;
|
96
103
|
}
|
97
|
-
|
98
|
-
(void)pl;
|
99
104
|
}
|
100
105
|
|
101
|
-
static void
|
102
|
-
|
103
|
-
{
|
104
|
-
DURSTORECTX *dctx = (void *)pkt->u_rdata.exdata;
|
105
|
-
free(dctx);
|
106
|
+
static void handle_dur_schedfail(mc_PACKET *pkt) {
|
107
|
+
delete static_cast<DurStoreCtx*>(pkt->u_rdata.exdata);
|
106
108
|
}
|
107
109
|
|
108
|
-
mc_REQDATAPROCS
|
110
|
+
mc_REQDATAPROCS DurStoreCtx::proctable = {
|
109
111
|
handle_dur_storecb,
|
110
112
|
handle_dur_schedfail
|
111
113
|
};
|
@@ -150,7 +152,7 @@ static int
|
|
150
152
|
can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
|
151
153
|
const lcb_VALBUF *vbuf, lcb_datatype_t datatype)
|
152
154
|
{
|
153
|
-
|
155
|
+
const lcb::Server *server = static_cast<const lcb::Server*>(pipeline);
|
154
156
|
int compressopts = LCBT_SETTING(instance, compressopts);
|
155
157
|
|
156
158
|
if (mcreq_compression_supported() == 0) {
|
@@ -163,7 +165,8 @@ can_compress(lcb_t instance, const mc_PIPELINE *pipeline,
|
|
163
165
|
if ((compressopts & LCB_COMPRESS_OUT) == 0) {
|
164
166
|
return 0;
|
165
167
|
}
|
166
|
-
if (server->
|
168
|
+
if (server->supports_compression() == false &&
|
169
|
+
(compressopts & LCB_COMPRESS_FORCE) == 0) {
|
167
170
|
return 0;
|
168
171
|
}
|
169
172
|
if (datatype & LCB_VALUE_F_SNAPPYCOMP) {
|
@@ -178,7 +181,6 @@ do_store3(lcb_t instance, const void *cookie,
|
|
178
181
|
{
|
179
182
|
mc_PIPELINE *pipeline;
|
180
183
|
mc_PACKET *packet;
|
181
|
-
mc_REQDATA *rdata;
|
182
184
|
mc_CMDQUEUE *cq = &instance->cmdq;
|
183
185
|
int hsize;
|
184
186
|
int should_compress = 0;
|
@@ -256,8 +258,6 @@ do_store3(lcb_t instance, const void *cookie,
|
|
256
258
|
int duropts = 0;
|
257
259
|
lcb_U16 persist_u , replicate_u;
|
258
260
|
const lcb_CMDSTOREDUR *dcmd = (const lcb_CMDSTOREDUR *)cmd;
|
259
|
-
DURSTORECTX *dctx = calloc(1, sizeof(*dctx));
|
260
|
-
|
261
261
|
persist_u = dcmd->persist_to;
|
262
262
|
replicate_u = dcmd->replicate_to;
|
263
263
|
if (dcmd->replicate_to == -1 || dcmd->persist_to == -1) {
|
@@ -268,24 +268,19 @@ do_store3(lcb_t instance, const void *cookie,
|
|
268
268
|
if (err != LCB_SUCCESS) {
|
269
269
|
mcreq_wipe_packet(pipeline, packet);
|
270
270
|
mcreq_release_packet(pipeline, packet);
|
271
|
-
free(dctx);
|
272
271
|
return err;
|
273
272
|
}
|
274
273
|
|
275
|
-
dctx
|
276
|
-
|
277
|
-
|
278
|
-
packet->u_rdata.exdata = &dctx->base;
|
274
|
+
DurStoreCtx *dctx = new DurStoreCtx(instance, persist_u, replicate_u,
|
275
|
+
cookie);
|
276
|
+
packet->u_rdata.exdata = dctx;
|
279
277
|
packet->flags |= MCREQ_F_REQEXT;
|
280
|
-
|
281
|
-
|
282
|
-
|
278
|
+
} else {
|
279
|
+
mc_REQDATA *rdata = MCREQ_PKT_RDATA(packet);
|
280
|
+
rdata->cookie = cookie;
|
281
|
+
rdata->start = gethrtime();
|
283
282
|
}
|
284
283
|
|
285
|
-
rdata = MCREQ_PKT_RDATA(packet);
|
286
|
-
rdata->cookie = cookie;
|
287
|
-
rdata->start = gethrtime();
|
288
|
-
|
289
284
|
scmd.message.body.expiration = htonl(cmd->exptime);
|
290
285
|
scmd.message.body.flags = htonl(flags);
|
291
286
|
hdr->request.magic = PROTOCOL_BINARY_REQ;
|
@@ -58,6 +58,17 @@ struct Traits {
|
|
58
58
|
return is_lookup ? LCB_SDMULTI_MODE_LOOKUP : LCB_SDMULTI_MODE_MUTATE;
|
59
59
|
}
|
60
60
|
|
61
|
+
inline bool chk_allow_empty_path(uint32_t options) const {
|
62
|
+
if (allow_empty_path) {
|
63
|
+
return true;
|
64
|
+
}
|
65
|
+
if (!is_lookup) {
|
66
|
+
return false;
|
67
|
+
}
|
68
|
+
|
69
|
+
return (options & LCB_SDSPEC_F_XATTRPATH) != 0;
|
70
|
+
}
|
71
|
+
|
61
72
|
inline Traits(uint8_t op, unsigned options) :
|
62
73
|
allow_empty_path(options & EMPTY_PATH),
|
63
74
|
allow_expiry(options & ALLOW_EXPIRY),
|
@@ -163,6 +174,28 @@ get_valbuf_size(const lcb_VALBUF& vb)
|
|
163
174
|
}
|
164
175
|
}
|
165
176
|
|
177
|
+
static uint8_t
|
178
|
+
make_subdoc_flags(const uint32_t user)
|
179
|
+
{
|
180
|
+
uint8_t subdoc_flags = 0;
|
181
|
+
if (user & LCB_SDSPEC_F_MKINTERMEDIATES) {
|
182
|
+
subdoc_flags |= SUBDOC_FLAG_MKDIR_P;
|
183
|
+
}
|
184
|
+
if (user & LCB_SDSPEC_F_MKDOCUMENT) {
|
185
|
+
subdoc_flags |= SUBDOC_FLAG_MKDOC;
|
186
|
+
}
|
187
|
+
if (user & LCB_SDSPEC_F_XATTRPATH) {
|
188
|
+
subdoc_flags |= SUBDOC_FLAG_XATTR_PATH;
|
189
|
+
}
|
190
|
+
if (user & LCB_SDSPEC_F_XATTR_MACROVALUES) {
|
191
|
+
subdoc_flags |= (SUBDOC_FLAG_EXPAND_MACROS | SUBDOC_FLAG_XATTR_PATH);
|
192
|
+
}
|
193
|
+
if (user & LCB_SDSPEC_F_XATTR_DELETED_OK) {
|
194
|
+
subdoc_flags |= (SUBDOC_FLAG_XATTR_PATH|SUBDOC_FLAG_ACCESS_DELETED);
|
195
|
+
}
|
196
|
+
return subdoc_flags;
|
197
|
+
}
|
198
|
+
|
166
199
|
struct MultiBuilder {
|
167
200
|
MultiBuilder(const lcb_CMDSUBDOC *cmd_)
|
168
201
|
: cmd(cmd_), payload_size(0), mode(0) {
|
@@ -266,17 +299,10 @@ MultiBuilder::add_spec(const lcb_SDSPEC *spec)
|
|
266
299
|
// opcode
|
267
300
|
add_field(trait.opcode, 1);
|
268
301
|
// flags
|
269
|
-
|
270
|
-
if (spec->options & LCB_SDSPEC_F_MKINTERMEDIATES) {
|
271
|
-
sdflags = SUBDOC_FLAG_MKDIR_P;
|
272
|
-
}
|
273
|
-
if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
|
274
|
-
sdflags |= SUBDOC_FLAG_MKDOC;
|
275
|
-
}
|
276
|
-
add_field(sdflags, 1);
|
302
|
+
add_field(make_subdoc_flags(spec->options), 1);
|
277
303
|
|
278
304
|
uint16_t npath = static_cast<uint16_t>(spec->path.contig.nbytes);
|
279
|
-
if (!npath && !trait.
|
305
|
+
if (!npath && !trait.chk_allow_empty_path(spec->options)) {
|
280
306
|
return LCB_EMPTY_PATH;
|
281
307
|
}
|
282
308
|
|
@@ -329,7 +355,8 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
329
355
|
if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
|
330
356
|
return LCB_EMPTY_KEY;
|
331
357
|
}
|
332
|
-
if (LCB_KEYBUF_IS_EMPTY(&spec->path) &&
|
358
|
+
if (LCB_KEYBUF_IS_EMPTY(&spec->path) &&
|
359
|
+
!traits.chk_allow_empty_path(spec->options)) {
|
333
360
|
return LCB_EMPTY_PATH;
|
334
361
|
}
|
335
362
|
|
@@ -399,14 +426,7 @@ sd3_single(lcb_t instance, const void *cookie, const lcb_CMDSUBDOC *cmd)
|
|
399
426
|
ntohs(hdr->request.keylen) + get_value_size(packet));
|
400
427
|
|
401
428
|
request.message.extras.pathlen = htons(spec->path.contig.nbytes);
|
402
|
-
request.message.extras.subdoc_flags =
|
403
|
-
|
404
|
-
if (spec->options & LCB_SDSPEC_F_MKINTERMEDIATES) {
|
405
|
-
request.message.extras.subdoc_flags |= SUBDOC_FLAG_MKDIR_P;
|
406
|
-
}
|
407
|
-
if (spec->options & LCB_SDSPEC_F_MKDOCUMENT) {
|
408
|
-
request.message.extras.subdoc_flags |= SUBDOC_FLAG_MKDOC;
|
409
|
-
}
|
429
|
+
request.message.extras.subdoc_flags = make_subdoc_flags(spec->options);
|
410
430
|
|
411
431
|
hdr->request.opcode = traits.opcode;
|
412
432
|
memcpy(SPAN_BUFFER(&packet->kh_span), request.bytes, sizeof request.bytes);
|
File without changes
|
@@ -24,128 +24,209 @@
|
|
24
24
|
#include <memcached/protocol_binary.h>
|
25
25
|
#include "rdb/rope.h"
|
26
26
|
|
27
|
-
#
|
28
|
-
|
29
|
-
#
|
27
|
+
#ifndef __cplusplus
|
28
|
+
typedef struct packet_info_st packet_info;
|
29
|
+
#else
|
30
|
+
namespace lcb {
|
31
|
+
class Server;
|
32
|
+
|
30
33
|
/**
|
31
34
|
* Response packet informational structure.
|
32
35
|
*
|
33
36
|
* This contains information regarding the response packet which is used by
|
34
37
|
* the response processors.
|
35
38
|
*/
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
/** Segment for payload */
|
42
|
-
void *bufh;
|
43
|
-
} packet_info;
|
39
|
+
class MemcachedResponse {
|
40
|
+
public:
|
41
|
+
MemcachedResponse() : payload(NULL), bufh(NULL) {
|
42
|
+
// Bodyless. Members are initialized via load!
|
43
|
+
}
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
MemcachedResponse(protocol_binary_command cmd, uint32_t opaque_,
|
46
|
+
protocol_binary_response_status code)
|
47
|
+
: res(), payload(NULL), bufh(NULL) {
|
48
|
+
res.response.opcode = cmd;
|
49
|
+
res.response.opaque = opaque_;
|
50
|
+
res.response.status = htons(code);
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* Read from an 'IOR' structure to parse the packet information. This will
|
54
|
+
* always load a full packet.
|
55
|
+
*
|
56
|
+
* @param ior the rope structure to read from
|
57
|
+
* @param[out] required how much total bytes must remain in the buffer for the
|
58
|
+
* parse to complete.
|
59
|
+
*
|
60
|
+
* @return false if more data is needed, true otherwise
|
61
|
+
*/
|
62
|
+
bool load(rdb_IOROPE *ior, unsigned *required) {
|
63
|
+
unsigned total = rdb_get_nused(ior);
|
64
|
+
unsigned wanted = sizeof(res.bytes);
|
65
|
+
|
66
|
+
if (total < wanted) {
|
67
|
+
*required = wanted;
|
68
|
+
return false;
|
69
|
+
}
|
70
|
+
|
71
|
+
rdb_copyread(ior, res.bytes, sizeof(res.bytes));
|
72
|
+
if (!bodylen()) {
|
73
|
+
rdb_consumed(ior, sizeof(res.bytes));
|
74
|
+
return true;
|
75
|
+
}
|
76
|
+
|
77
|
+
wanted += bodylen();
|
78
|
+
if (total < wanted) {
|
79
|
+
*required = wanted;
|
80
|
+
return false;
|
81
|
+
}
|
82
|
+
|
83
|
+
rdb_consumed(ior, sizeof(res.bytes));
|
84
|
+
payload = rdb_get_consolidated(ior, bodylen());
|
85
|
+
return true;
|
86
|
+
}
|
50
87
|
|
51
|
-
|
88
|
+
template <typename T>
|
89
|
+
bool load(T ctx, unsigned *required) {
|
90
|
+
return load(&ctx->ior, required);
|
91
|
+
}
|
52
92
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
93
|
+
void release(rdb_IOROPE *ior) {
|
94
|
+
if (!bodylen()) {
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
rdb_consumed(ior, bodylen());
|
98
|
+
}
|
57
99
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
100
|
+
template <typename T>
|
101
|
+
void release(T ctx) {
|
102
|
+
release(&ctx->ior);
|
103
|
+
}
|
62
104
|
|
63
|
-
/**
|
64
|
-
|
65
|
-
|
66
|
-
|
105
|
+
/**
|
106
|
+
* Gets the command for the packet
|
107
|
+
*/
|
108
|
+
uint8_t opcode() const {
|
109
|
+
return res.response.opcode;
|
110
|
+
}
|
67
111
|
|
68
|
-
/**
|
69
|
-
|
70
|
-
|
71
|
-
|
112
|
+
/**
|
113
|
+
* Gets the CAS for the packet
|
114
|
+
*/
|
115
|
+
uint64_t cas() const {
|
116
|
+
return lcb_ntohll(res.response.cas);
|
117
|
+
}
|
72
118
|
|
73
|
-
/**
|
74
|
-
|
75
|
-
|
76
|
-
|
119
|
+
/**
|
120
|
+
* Gets the 'datatype' field for the packet.
|
121
|
+
*/
|
122
|
+
uint8_t datatype() const {
|
123
|
+
return res.response.datatype;
|
124
|
+
}
|
77
125
|
|
78
|
-
/**
|
79
|
-
|
80
|
-
|
81
|
-
|
126
|
+
/**
|
127
|
+
* Gets a pointer starting at the packet's key field. Only use if NKEY is 0
|
128
|
+
*/
|
129
|
+
const char *key() const {
|
130
|
+
return body<const char*>() + extlen();
|
131
|
+
}
|
82
132
|
|
83
|
-
/**
|
84
|
-
|
85
|
-
|
86
|
-
|
133
|
+
/**
|
134
|
+
* Gets a pointer starting at the packet's value field. Only use if NVALUE is 0
|
135
|
+
*/
|
136
|
+
const char *value() const {
|
137
|
+
return body<const char*>() + keylen() + extlen();
|
138
|
+
}
|
87
139
|
|
88
|
-
/**
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
140
|
+
/**
|
141
|
+
* Gets the size of the packet value. The value is the part of the payload
|
142
|
+
* which is after the key (if applicable) and extras (if applicable).
|
143
|
+
*/
|
144
|
+
uint32_t vallen() const {
|
145
|
+
return bodylen() - (keylen() + extlen());
|
146
|
+
}
|
93
147
|
|
94
|
-
#define PACKET_REQUEST(pkt) \
|
95
|
-
( (protocol_binary_request_header *) &(pkt)->res)
|
96
148
|
|
97
|
-
|
98
|
-
|
149
|
+
/**
|
150
|
+
* Gets the status of the packet
|
151
|
+
*/
|
152
|
+
uint16_t status() const {
|
153
|
+
return ntohs(res.response.status);
|
154
|
+
}
|
99
155
|
|
100
|
-
/**
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
156
|
+
/**
|
157
|
+
* Gets the payload
|
158
|
+
*/
|
159
|
+
template <typename T>
|
160
|
+
const T body() const {
|
161
|
+
return reinterpret_cast<const T>(payload);
|
162
|
+
}
|
105
163
|
|
106
|
-
/**
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
164
|
+
/**
|
165
|
+
* Map a command 'subclass' so that its body field starts at the payload. Note
|
166
|
+
* that the return value is actually an ephemeral pointer starting 24 bytes
|
167
|
+
* _before_ the actual memory block, so only use the non-header part.
|
168
|
+
*/
|
169
|
+
const char *ephemeral_start() const {
|
170
|
+
return body<const char*>() - 24;
|
171
|
+
}
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Gets the size of the _total_ non-header part of the packet. This data is
|
175
|
+
* also featured inside the payload field itself.
|
176
|
+
*/
|
177
|
+
uint32_t bodylen() const {
|
178
|
+
return ntohl(res.response.bodylen);
|
179
|
+
}
|
112
180
|
|
181
|
+
/**
|
182
|
+
* Gets the key size, if included in the packet.
|
183
|
+
*/
|
184
|
+
uint16_t keylen() const {
|
185
|
+
return ntohs(res.response.keylen);
|
186
|
+
}
|
113
187
|
|
114
|
-
/**
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
(const void *)(( ((const char *)(pkt)->payload) - 24 ))
|
188
|
+
/**
|
189
|
+
* Gets the length of the 'extras' in the body
|
190
|
+
*/
|
191
|
+
uint8_t extlen() const {
|
192
|
+
return (res.response.extlen);
|
193
|
+
}
|
121
194
|
|
122
|
-
/**
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
* @param[out] required how much total bytes must remain in the buffer for the
|
129
|
-
* parse to complete.
|
130
|
-
*
|
131
|
-
* @return zero if more data is needed, a true value otherwise
|
132
|
-
*/
|
133
|
-
int
|
134
|
-
lcb_pktinfo_ior_get(packet_info *info, rdb_IOROPE *ior, unsigned *required);
|
195
|
+
/**
|
196
|
+
* Gets the raw unconverted 'opaque' 32 bit field
|
197
|
+
*/
|
198
|
+
uint32_t opaque() const {
|
199
|
+
return (res.response.opaque);
|
200
|
+
}
|
135
201
|
|
136
|
-
|
137
|
-
|
202
|
+
size_t hdrsize() const {
|
203
|
+
return sizeof (res.bytes);
|
204
|
+
}
|
138
205
|
|
139
|
-
|
140
|
-
|
206
|
+
uint8_t *hdrbytes() {
|
207
|
+
return res.bytes;
|
208
|
+
}
|
141
209
|
|
210
|
+
void *bufseg() const {
|
211
|
+
return bufh;
|
212
|
+
}
|
142
213
|
|
214
|
+
protected:
|
215
|
+
/** The response header */
|
216
|
+
protocol_binary_response_header res;
|
217
|
+
/** The payload of the response. This should only be used if there is a body */
|
218
|
+
void *payload;
|
219
|
+
/** Segment for payload */
|
220
|
+
void *bufh;
|
143
221
|
|
144
|
-
|
145
|
-
}
|
222
|
+
friend class lcb::Server;
|
223
|
+
};
|
146
224
|
|
225
|
+
#define PACKET_REQUEST(pkt) \
|
226
|
+
( (protocol_binary_request_header *) &(pkt)->res)
|
147
227
|
|
148
|
-
|
228
|
+
#define PACKET_REQ_VBID(pkt) \
|
229
|
+
(ntohs(PACKET_REQUEST(pkt)->request.vbucket))
|
149
230
|
|
150
231
|
class MemcachedRequest {
|
151
232
|
public:
|
@@ -169,65 +250,47 @@ public:
|
|
169
250
|
hdr.request.opaque = opaque_;
|
170
251
|
}
|
171
252
|
|
172
|
-
|
173
|
-
hdr.request.
|
174
|
-
hdr.request.magic = PROTOCOL_BINARY_REQ;
|
175
|
-
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
176
|
-
hdr.request.cas = 0;
|
177
|
-
hdr.request.vbucket = 0;
|
178
|
-
hdr.request.opaque = 0;
|
179
|
-
hdr.request.bodylen = 0;
|
180
|
-
hdr.request.extlen = 0;
|
181
|
-
hdr.request.keylen = 0;
|
182
|
-
hdr.request.opaque = 0;
|
183
|
-
}
|
184
|
-
|
185
|
-
const void *data() const { return hdr.bytes; }
|
186
|
-
size_t size() const { return sizeof hdr.bytes; }
|
187
|
-
|
188
|
-
private:
|
189
|
-
protocol_binary_request_header hdr;
|
190
|
-
};
|
191
|
-
|
192
|
-
class MemcachedResponse : private packet_info {
|
193
|
-
public:
|
194
|
-
bool load(rdb_IOROPE *ior, unsigned *required) {
|
195
|
-
return lcb_pktinfo_ior_get(this, ior, required) != 0;
|
253
|
+
uint32_t opaque() const {
|
254
|
+
return hdr.request.opaque;
|
196
255
|
}
|
197
256
|
|
198
|
-
|
199
|
-
|
200
|
-
return lcb_pktinfo_ectx_get(this, ctx, required);
|
257
|
+
uint8_t opcode() const {
|
258
|
+
return hdr.request.opcode;
|
201
259
|
}
|
202
260
|
|
203
|
-
|
204
|
-
|
261
|
+
MemcachedRequest(uint8_t opcode_) {
|
262
|
+
assign(opcode_);
|
205
263
|
}
|
206
264
|
|
207
|
-
|
208
|
-
|
209
|
-
|
265
|
+
MemcachedRequest(uint8_t opcode_, uint32_t opaque_) {
|
266
|
+
assign(opcode_);
|
267
|
+
hdr.request.opaque = opaque_;
|
210
268
|
}
|
211
269
|
|
212
|
-
|
213
|
-
|
270
|
+
MemcachedRequest(const void *buf) {
|
271
|
+
memcpy(hdr.bytes, buf, sizeof hdr.bytes);
|
214
272
|
}
|
215
273
|
|
216
|
-
|
217
|
-
|
218
|
-
}
|
274
|
+
const void *data() const { return hdr.bytes; }
|
275
|
+
size_t size() const { return sizeof hdr.bytes; }
|
219
276
|
|
220
|
-
|
221
|
-
|
222
|
-
return reinterpret_cast<const T>(packet_info::payload);
|
223
|
-
}
|
277
|
+
private:
|
278
|
+
protocol_binary_request_header hdr;
|
224
279
|
|
225
|
-
|
226
|
-
|
280
|
+
void assign(uint8_t opcode_) {
|
281
|
+
hdr.request.opcode = opcode_;
|
282
|
+
hdr.request.magic = PROTOCOL_BINARY_REQ;
|
283
|
+
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
284
|
+
hdr.request.cas = 0;
|
285
|
+
hdr.request.vbucket = 0;
|
286
|
+
hdr.request.opaque = 0;
|
287
|
+
hdr.request.bodylen = 0;
|
288
|
+
hdr.request.extlen = 0;
|
289
|
+
hdr.request.keylen = 0;
|
290
|
+
hdr.request.opaque = 0;
|
227
291
|
}
|
228
292
|
};
|
229
|
-
|
230
293
|
}
|
294
|
+
typedef lcb::MemcachedResponse packet_info;
|
231
295
|
#endif
|
232
|
-
|
233
296
|
#endif
|