libcouchbase 0.3.3 → 1.0.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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -323,16 +323,7 @@ lcb_durability_validate(lcb_t instance,
323
323
 
324
324
  }
325
325
 
326
- static lcb_error_t
327
- dset_ctx_add(lcb_MULTICMD_CTX *mctx, const lcb_CMDBASE *cmd)
328
- {
329
- return static_cast<Durset*>(mctx)->mctx_add(cmd);
330
- }
331
-
332
- lcb_error_t
333
- Durset::mctx_add(const lcb_CMDBASE *cmd)
334
- {
335
-
326
+ lcb_error_t Durset::MCTX_addcmd(const lcb_CMDBASE *cmd) {
336
327
  if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
337
328
  return LCB_EMPTY_KEY;
338
329
  }
@@ -357,14 +348,8 @@ Durset::mctx_add(const lcb_CMDBASE *cmd)
357
348
  return after_add(ent, reinterpret_cast<const lcb_CMDENDURE*>(cmd));
358
349
  }
359
350
 
360
- static lcb_error_t
361
- dset_ctx_schedule(lcb_MULTICMD_CTX *mctx, const void *cookie)
362
- {
363
- return static_cast<Durset*>(mctx)->mctx_schedule(cookie);
364
- }
365
-
366
351
  lcb_error_t
367
- Durset::mctx_schedule(const void *cookie_) {
352
+ Durset::MCTX_done(const void *cookie_) {
368
353
  lcb_error_t err;
369
354
  const char *kptr = kvbufs.c_str();
370
355
 
@@ -395,10 +380,8 @@ Durset::mctx_schedule(const void *cookie_) {
395
380
  return LCB_SUCCESS;
396
381
  }
397
382
 
398
- static void
399
- dset_ctx_fail(lcb_MULTICMD_CTX *mctx)
400
- {
401
- delete static_cast<Durset*>(mctx);
383
+ void Durset::MCTX_fail() {
384
+ delete this;
402
385
  }
403
386
 
404
387
  void lcbdurctx_set_durstore(lcb_MULTICMD_CTX *mctx, int enabled)
@@ -436,14 +419,11 @@ get_poll_meth(lcb_t instance, const lcb_durability_opts_t *options)
436
419
  }
437
420
 
438
421
  Durset::Durset(lcb_t instance_, const lcb_durability_opts_t *options)
439
- : nremaining(0), waiting(0), refcnt(0), next_state(STATE_OBSPOLL),
422
+ : MultiCmdContext(),
423
+ nremaining(0), waiting(0), refcnt(0), next_state(STATE_OBSPOLL),
440
424
  lasterr(LCB_SUCCESS), is_durstore(false), cookie(NULL),
441
425
  ns_timeout(0), timer(NULL), instance(instance_)
442
426
  {
443
- lcb_MULTICMD_CTX::addcmd = dset_ctx_add;
444
- lcb_MULTICMD_CTX::done = dset_ctx_schedule;
445
- lcb_MULTICMD_CTX::fail = dset_ctx_fail;
446
-
447
427
  const lcb_DURABILITYOPTSv0 *opts_in = &options->v.v0;
448
428
 
449
429
  std::memset(&opts, 0, sizeof opts);
@@ -19,6 +19,8 @@
19
19
  #define LCB_DURABILITY_INTERNAL_H
20
20
 
21
21
  #ifdef __cplusplus
22
+ #include "mctx-helper.h"
23
+
22
24
  extern "C" {
23
25
  #endif
24
26
 
@@ -191,7 +193,7 @@ struct Item : public CallbackCookie {
191
193
  * A collection encompassing one or more entries which are to be checked for
192
194
  * persistence
193
195
  */
194
- struct Durset : public lcb_MULTICMD_CTX {
196
+ struct Durset : public MultiCmdContext {
195
197
  /**
196
198
  * Call this when the polling method (poll_impl()) has completed. This will
197
199
  * trigger a new poll after the interval.
@@ -248,8 +250,9 @@ struct Durset : public lcb_MULTICMD_CTX {
248
250
  Durset(lcb_t instance, const lcb_durability_opts_t* options);
249
251
 
250
252
  // Implementation for MULTICMD_CTX
251
- inline lcb_error_t mctx_schedule(const void *cookie);
252
- inline lcb_error_t mctx_add(const lcb_CMDBASE *cmd);
253
+ lcb_error_t MCTX_done(const void *cookie);
254
+ lcb_error_t MCTX_addcmd(const lcb_CMDBASE *cmd);
255
+ void MCTX_fail();
253
256
 
254
257
  /**
255
258
  * This function calls poll_impl(). The implementation should then call
@@ -181,28 +181,31 @@ lcb_unlock(lcb_t instance, const void *cookie, lcb_size_t num,
181
181
  }
182
182
  }
183
183
 
184
- typedef struct {
185
- mc_REQDATAEX base;
184
+ struct RGetCookie : mc_REQDATAEX {
185
+ RGetCookie(const void *cookie, lcb_t instance, lcb_replica_t, int vb);
186
+ void decref() {
187
+ if (!--remaining) {
188
+ delete this;
189
+ }
190
+ }
191
+
186
192
  unsigned r_cur;
187
193
  unsigned r_max;
188
194
  int remaining;
189
195
  int vbucket;
190
196
  lcb_replica_t strategy;
191
197
  lcb_t instance;
192
- } rget_cookie;
198
+ };
193
199
 
194
200
  static void rget_dtor(mc_PACKET *pkt) {
195
- rget_cookie *rck = (rget_cookie *)pkt->u_rdata.exdata;
196
- if (! --rck->remaining) {
197
- free(rck);
198
- }
201
+ static_cast<RGetCookie*>(pkt->u_rdata.exdata)->decref();
199
202
  }
200
203
 
201
204
  static void
202
- rget_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg)
205
+ rget_callback(mc_PIPELINE *, mc_PACKET *pkt, lcb_error_t err, const void *arg)
203
206
  {
204
- rget_cookie *rck = (rget_cookie *)pkt->u_rdata.exdata;
205
- lcb_RESPGET *resp = (void *)arg;
207
+ RGetCookie *rck = static_cast<RGetCookie*>(pkt->u_rdata.exdata);
208
+ lcb_RESPGET *resp = reinterpret_cast<lcb_RESPGET*>(const_cast<void*>(arg));
206
209
  lcb_RESPCALLBACK callback;
207
210
  lcb_t instance = rck->instance;
208
211
 
@@ -247,11 +250,7 @@ rget_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg)
247
250
  rck->remaining = 2;
248
251
  }
249
252
  }
250
-
251
- if (!--rck->remaining) {
252
- free(rck);
253
- }
254
- (void)pl;
253
+ rck->decref();
255
254
  }
256
255
 
257
256
  static mc_REQDATAPROCS rget_procs = {
@@ -259,6 +258,13 @@ static mc_REQDATAPROCS rget_procs = {
259
258
  rget_dtor
260
259
  };
261
260
 
261
+ RGetCookie::RGetCookie(const void *cookie_, lcb_t instance_,
262
+ lcb_replica_t strategy_, int vbucket_)
263
+ : mc_REQDATAEX(cookie_, rget_procs, gethrtime()),
264
+ r_cur(0), r_max(LCBT_NREPLICAS(instance_)), remaining(0),
265
+ vbucket(vbucket_), strategy(strategy_), instance(instance_) {
266
+ }
267
+
262
268
  LIBCOUCHBASE_API
263
269
  lcb_error_t
264
270
  lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd)
@@ -271,7 +277,6 @@ lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd)
271
277
  int vbid, ixtmp;
272
278
  protocol_binary_request_header req;
273
279
  unsigned r0, r1 = 0;
274
- rget_cookie *rck = NULL;
275
280
 
276
281
  if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
277
282
  return LCB_EMPTY_KEY;
@@ -323,15 +328,7 @@ lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd)
323
328
  }
324
329
 
325
330
  /* Initialize the cookie */
326
- rck = calloc(1, sizeof(*rck));
327
- rck->base.cookie = cookie;
328
- rck->base.start = gethrtime();
329
- rck->base.procs = &rget_procs;
330
- rck->strategy = cmd->strategy;
331
- rck->r_cur = r0;
332
- rck->r_max = LCBT_NREPLICAS(instance);
333
- rck->instance = instance;
334
- rck->vbucket = vbid;
331
+ RGetCookie *rck = new RGetCookie(cookie, instance, cmd->strategy, vbid);
335
332
 
336
333
  /* Initialize the packet */
337
334
  req.request.magic = PROTOCOL_BINARY_REQ;
@@ -343,6 +340,7 @@ lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd)
343
340
  req.request.keylen = htons((lcb_uint16_t)cmd->key.contig.nbytes);
344
341
  req.request.bodylen = htonl((lcb_uint32_t)cmd->key.contig.nbytes);
345
342
 
343
+ rck->r_cur = r0;
346
344
  do {
347
345
  int curix;
348
346
  mc_PIPELINE *pl;
@@ -359,7 +357,7 @@ lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd)
359
357
  return LCB_CLIENT_ENOMEM;
360
358
  }
361
359
 
362
- pkt->u_rdata.exdata = &rck->base;
360
+ pkt->u_rdata.exdata = rck;
363
361
  pkt->flags |= MCREQ_F_REQEXT;
364
362
 
365
363
  mcreq_reserve_key(pl, pkt, sizeof(req.bytes), &cmd->key);
@@ -16,23 +16,28 @@
16
16
  */
17
17
 
18
18
  #include "internal.h"
19
- #include "simplestring.h"
20
19
  #include "durability_internal.h"
21
20
  #include "trace.h"
21
+ #include "mctx-helper.h"
22
22
 
23
- typedef struct {
24
- mc_REQDATAEX base;
25
- lcb_MULTICMD_CTX mctx;
26
- lcb_t instance;
23
+ struct ObserveCtx : mc_REQDATAEX, lcb::MultiCmdContext {
24
+ void clear_requests() { requests.clear(); }
25
+ ObserveCtx(lcb_t instance_);
26
+
27
+ // Overrides
28
+ lcb_error_t MCTX_addcmd(const lcb_CMDBASE*);
29
+ lcb_error_t MCTX_done(const void *);
30
+ void MCTX_fail();
27
31
 
32
+ lcb_t instance;
28
33
  size_t remaining;
29
34
  unsigned oflags;
30
35
 
36
+ typedef std::vector<uint8_t> ServerBuf;
31
37
  /* requests array contains one buffer per server. nrequest essentially
32
38
  * says how many elements (and thus how many servers) */
33
- size_t nrequests;
34
- lcb_string requests[1];
35
- } OBSERVECTX;
39
+ std::vector<ServerBuf> requests;
40
+ };
36
41
 
37
42
  typedef enum {
38
43
  F_DURABILITY = 0x01,
@@ -40,12 +45,20 @@ typedef enum {
40
45
  F_SCHEDFAILED = 0x04
41
46
  } obs_flags;
42
47
 
48
+ // TODO: Move this to a common file
49
+ template <typename ContainerType, typename ValueType>
50
+ void add_to_buf(ContainerType& c, ValueType v) {
51
+ typename ContainerType::value_type *p =
52
+ reinterpret_cast<typename ContainerType::value_type*>(&v);
53
+ c.insert(c.end(), p, p + sizeof(ValueType));
54
+ }
55
+
43
56
  static void
44
57
  handle_observe_callback(mc_PIPELINE *pl,
45
58
  mc_PACKET *pkt, lcb_error_t err, const void *arg)
46
59
  {
47
- OBSERVECTX *oc = (void *)pkt->u_rdata.exdata;
48
- lcb_RESPOBSERVE *resp = (void *)arg;
60
+ ObserveCtx *oc = static_cast<ObserveCtx*>(pkt->u_rdata.exdata);
61
+ lcb_RESPOBSERVE *resp = reinterpret_cast<lcb_RESPOBSERVE*>(const_cast<void*>(arg));
49
62
  lcb_t instance = oc->instance;
50
63
 
51
64
  (void)pl;
@@ -68,7 +81,7 @@ handle_observe_callback(mc_PIPELINE *pl,
68
81
  memset(&cur, 0, sizeof(cur));
69
82
  cur.key = ptr;
70
83
  cur.nkey = nkey;
71
- cur.cookie = (void *)oc->base.cookie;
84
+ cur.cookie = (void *)oc->cookie;
72
85
  cur.rc = err;
73
86
  handle_observe_callback(NULL, pkt, err, &cur);
74
87
  ptr += nkey;
@@ -78,7 +91,7 @@ handle_observe_callback(mc_PIPELINE *pl,
78
91
  return;
79
92
  }
80
93
 
81
- resp->cookie = (void *)oc->base.cookie;
94
+ resp->cookie = (void *)oc->cookie;
82
95
  resp->rc = err;
83
96
  if (oc->oflags & F_DURABILITY) {
84
97
  resp->ttp = pl ? pl->index : -1;
@@ -101,36 +114,23 @@ handle_observe_callback(mc_PIPELINE *pl,
101
114
  resp2.rflags = LCB_RESP_F_CLIENTGEN|LCB_RESP_F_FINAL;
102
115
  oc->oflags |= F_DESTROY;
103
116
  handle_observe_callback(NULL, pkt, err, &resp2);
104
- free(oc);
117
+ delete oc;
105
118
  }
106
119
  }
107
120
 
108
121
  static void
109
122
  handle_schedfail(mc_PACKET *pkt)
110
123
  {
111
- OBSERVECTX *oc = (void *)pkt->u_rdata.exdata;
124
+ ObserveCtx *oc = static_cast<ObserveCtx*>(pkt->u_rdata.exdata);
112
125
  oc->oflags |= F_SCHEDFAILED;
113
126
  handle_observe_callback(NULL, pkt, LCB_SCHEDFAIL_INTERNAL, NULL);
114
127
  }
115
128
 
116
- static void destroy_requests(OBSERVECTX *reqs)
117
- {
118
- size_t ii;
119
- for (ii = 0; ii < reqs->nrequests; ii++) {
120
- lcb_string_release(reqs->requests + ii);
121
- }
122
- }
123
-
124
- #define CTX_FROM_MULTI(mcmd) (void *) ((((char *) (mcmd))) - offsetof(OBSERVECTX, mctx))
125
-
126
- static lcb_error_t
127
- obs_ctxadd(lcb_MULTICMD_CTX *mctx, const lcb_CMDBASE *cmdbase)
129
+ lcb_error_t ObserveCtx::MCTX_addcmd(const lcb_CMDBASE *cmdbase)
128
130
  {
129
131
  int vbid, srvix_dummy;
130
132
  unsigned ii;
131
133
  const lcb_CMDOBSERVE *cmd = (const lcb_CMDOBSERVE *)cmdbase;
132
- OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
133
- lcb_t instance = ctx->instance;
134
134
  mc_CMDQUEUE *cq = &instance->cmdq;
135
135
  lcb_U16 servers_s[4];
136
136
  const lcb_U16 *servers;
@@ -178,23 +178,18 @@ obs_ctxadd(lcb_MULTICMD_CTX *mctx, const lcb_CMDBASE *cmdbase)
178
178
  }
179
179
 
180
180
  for (ii = 0; ii < nservers; ii++) {
181
- lcb_string *rr;
182
- lcb_U16 vb16, klen16;
183
181
  lcb_U16 ix = servers[ii];
184
182
 
185
- lcb_assert(ix < ctx->nrequests);
186
- rr = ctx->requests + ix;
187
- if (0 != lcb_string_reserve(rr, 4 + cmd->key.contig.nbytes)) {
188
- return LCB_CLIENT_ENOMEM;
189
- }
190
-
191
- vb16 = htons((lcb_U16)vbid);
192
- klen16 = htons((lcb_U16)cmd->key.contig.nbytes);
193
- lcb_string_append(rr, &vb16, sizeof vb16);
194
- lcb_string_append(rr, &klen16, sizeof klen16);
195
- lcb_string_append(rr, cmd->key.contig.bytes, cmd->key.contig.nbytes);
183
+ lcb_assert(ix < requests.size());
196
184
 
197
- ctx->remaining++;
185
+ ServerBuf& rr = requests[ix];
186
+ add_to_buf(rr, uint16_t(htons(vbid)));
187
+ add_to_buf(rr, uint16_t(htons(cmd->key.contig.nbytes)));
188
+ rr.insert(rr.end(),
189
+ reinterpret_cast<const uint8_t*>(cmd->key.contig.bytes),
190
+ reinterpret_cast<const uint8_t*>(cmd->key.contig.bytes) +
191
+ cmd->key.contig.nbytes);
192
+ remaining++;
198
193
  }
199
194
  return LCB_SUCCESS;
200
195
  }
@@ -204,21 +199,19 @@ static mc_REQDATAPROCS obs_procs = {
204
199
  handle_schedfail
205
200
  };
206
201
 
207
- static lcb_error_t
208
- obs_ctxdone(lcb_MULTICMD_CTX *mctx, const void *cookie)
202
+ lcb_error_t ObserveCtx::MCTX_done(const void *cookie_)
209
203
  {
210
204
  unsigned ii;
211
- OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
212
- mc_CMDQUEUE *cq = &ctx->instance->cmdq;
205
+ mc_CMDQUEUE *cq = &instance->cmdq;
213
206
 
214
- for (ii = 0; ii < ctx->nrequests; ii++) {
207
+ for (ii = 0; ii < requests.size(); ii++) {
215
208
  protocol_binary_request_header hdr;
216
209
  mc_PACKET *pkt;
217
210
  mc_PIPELINE *pipeline;
218
- lcb_string *rr = ctx->requests + ii;
211
+ ServerBuf& rr = requests[ii];
219
212
  pipeline = cq->pipelines[ii];
220
213
 
221
- if (!rr->nused) {
214
+ if (rr.empty()) {
222
215
  continue;
223
216
  }
224
217
 
@@ -226,7 +219,7 @@ obs_ctxdone(lcb_MULTICMD_CTX *mctx, const void *cookie)
226
219
  lcb_assert(pkt);
227
220
 
228
221
  mcreq_reserve_header(pipeline, pkt, MCREQ_PKT_BASESIZE);
229
- mcreq_reserve_value2(pipeline, pkt, rr->nused);
222
+ mcreq_reserve_value2(pipeline, pkt, rr.size());
230
223
 
231
224
  hdr.request.magic = PROTOCOL_BINARY_REQ;
232
225
  hdr.request.opcode = PROTOCOL_BINARY_CMD_OBSERVE;
@@ -236,70 +229,52 @@ obs_ctxdone(lcb_MULTICMD_CTX *mctx, const void *cookie)
236
229
  hdr.request.vbucket = 0;
237
230
  hdr.request.extlen = 0;
238
231
  hdr.request.opaque = pkt->opaque;
239
- hdr.request.bodylen = htonl((lcb_uint32_t)rr->nused);
232
+ hdr.request.bodylen = htonl((lcb_uint32_t)rr.size());
240
233
 
241
234
  memcpy(SPAN_BUFFER(&pkt->kh_span), hdr.bytes, sizeof(hdr.bytes));
242
- memcpy(SPAN_BUFFER(&pkt->u_value.single), rr->base, rr->nused);
235
+ memcpy(SPAN_BUFFER(&pkt->u_value.single), &rr[0], rr.size());
243
236
 
244
237
  pkt->flags |= MCREQ_F_REQEXT;
245
- pkt->u_rdata.exdata = (mc_REQDATAEX *)ctx;
238
+ pkt->u_rdata.exdata = this;
246
239
  mcreq_sched_add(pipeline, pkt);
247
240
  TRACE_OBSERVE_BEGIN(&hdr, SPAN_BUFFER(&pkt->u_value.single));
248
241
  }
249
242
 
250
- destroy_requests(ctx);
251
- ctx->base.start = gethrtime();
252
- ctx->base.cookie = cookie;
253
- ctx->base.procs = &obs_procs;
243
+ start = gethrtime();
244
+ cookie = cookie_;
254
245
 
255
- if (ctx->nrequests == 0 || ctx->remaining == 0) {
256
- free(ctx);
246
+ if (requests.size() == 0 || remaining == 0) {
247
+ delete this;
257
248
  return LCB_EINVAL;
258
249
  } else {
259
- MAYBE_SCHEDLEAVE(ctx->instance);
250
+ MAYBE_SCHEDLEAVE(instance);
260
251
  return LCB_SUCCESS;
261
252
  }
262
253
  }
263
254
 
264
- static void
265
- obs_ctxfail(lcb_MULTICMD_CTX *mctx)
266
- {
267
- OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
268
- destroy_requests(ctx);
269
- free(ctx);
255
+ void ObserveCtx::MCTX_fail() {
256
+ delete this;
270
257
  }
271
258
 
272
- LIBCOUCHBASE_API
273
- lcb_MULTICMD_CTX *
274
- lcb_observe3_ctxnew(lcb_t instance)
275
- {
276
- OBSERVECTX *ctx;
277
- size_t ii, n_extra = LCBT_NSERVERS(instance)-1;
278
- ctx = calloc(1, sizeof(*ctx) + sizeof(ctx->requests) * n_extra);
279
- ctx->instance = instance;
280
- ctx->nrequests = n_extra + 1;
281
- ctx->mctx.addcmd = obs_ctxadd;
282
- ctx->mctx.done = obs_ctxdone;
283
- ctx->mctx.fail = obs_ctxfail;
284
-
285
- /* note this block doesn't do anything not done with calloc, but makes for
286
- * easier reading/tracking */
287
- for (ii = 0; ii < ctx->nrequests; ii++) {
288
- lcb_string_init(ctx->requests + ii);
289
- }
259
+ ObserveCtx::ObserveCtx(lcb_t instance_)
260
+ : mc_REQDATAEX(NULL, obs_procs, 0),
261
+ instance(instance_),
262
+ remaining(0),
263
+ oflags(0) {
264
+
265
+ requests.resize(LCBT_NSERVERS(instance));
266
+ }
290
267
 
291
- return &ctx->mctx;
268
+ LIBCOUCHBASE_API
269
+ lcb_MULTICMD_CTX * lcb_observe3_ctxnew(lcb_t instance) {
270
+ return new ObserveCtx(instance);
292
271
  }
293
272
 
294
273
  lcb_MULTICMD_CTX *
295
- lcb_observe_ctx_dur_new(lcb_t instance)
296
- {
297
- lcb_MULTICMD_CTX *mctx = lcb_observe3_ctxnew(instance);
298
- if (mctx) {
299
- OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
300
- ctx->oflags |= F_DURABILITY;
301
- }
302
- return mctx;
274
+ lcb_observe_ctx_dur_new(lcb_t instance) {
275
+ ObserveCtx *ctx = new ObserveCtx(instance);
276
+ ctx->oflags |= F_DURABILITY;
277
+ return ctx;
303
278
  }
304
279
 
305
280
  LIBCOUCHBASE_API