libcouchbase 0.0.7 → 0.0.8
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 +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
|