libcouchbase 0.0.1

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 (561) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +35 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +24 -0
  8. data/README.md +389 -0
  9. data/Rakefile +75 -0
  10. data/ext/README.md +6 -0
  11. data/ext/Rakefile +20 -0
  12. data/ext/libcouchbase/.gitignore +130 -0
  13. data/ext/libcouchbase/.travis.yml +19 -0
  14. data/ext/libcouchbase/CMakeLists.txt +429 -0
  15. data/ext/libcouchbase/CONTRIBUTING.md +124 -0
  16. data/ext/libcouchbase/LICENSE +202 -0
  17. data/ext/libcouchbase/README.markdown +163 -0
  18. data/ext/libcouchbase/RELEASE_NOTES.markdown +2691 -0
  19. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +27 -0
  20. data/ext/libcouchbase/cmake/Modules/CopyPDB.cmake +42 -0
  21. data/ext/libcouchbase/cmake/Modules/DistScript.cmake +17 -0
  22. data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +20 -0
  23. data/ext/libcouchbase/cmake/Modules/FindCouchbaseHdrHistogram.cmake +15 -0
  24. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibev.cmake +73 -0
  25. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +52 -0
  26. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +56 -0
  27. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +11 -0
  28. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +29 -0
  29. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +133 -0
  30. data/ext/libcouchbase/cmake/Modules/GetPlatformCCInfo.cmake +45 -0
  31. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +70 -0
  32. data/ext/libcouchbase/cmake/config-cmake.h.in +60 -0
  33. data/ext/libcouchbase/cmake/configure +357 -0
  34. data/ext/libcouchbase/cmake/defs.mk.in +8 -0
  35. data/ext/libcouchbase/cmake/dtrace-instr-link.pl +38 -0
  36. data/ext/libcouchbase/cmake/source_files.cmake +73 -0
  37. data/ext/libcouchbase/configure.pl +1 -0
  38. data/ext/libcouchbase/contrib/cJSON/cJSON.c +624 -0
  39. data/ext/libcouchbase/contrib/cJSON/cJSON.h +158 -0
  40. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +9 -0
  41. data/ext/libcouchbase/contrib/cbsasl/COPYING +202 -0
  42. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +217 -0
  43. data/ext/libcouchbase/contrib/cbsasl/src/client.c +205 -0
  44. data/ext/libcouchbase/contrib/cbsasl/src/common.c +46 -0
  45. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.c +67 -0
  46. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.h +33 -0
  47. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.c +296 -0
  48. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.h +45 -0
  49. data/ext/libcouchbase/contrib/cbsasl/src/hash.c +573 -0
  50. data/ext/libcouchbase/contrib/cbsasl/src/hash.h +15 -0
  51. data/ext/libcouchbase/contrib/cbsasl/src/util.h +31 -0
  52. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +2 -0
  53. data/ext/libcouchbase/contrib/cliopts/cliopts.c +747 -0
  54. data/ext/libcouchbase/contrib/cliopts/cliopts.h +493 -0
  55. data/ext/libcouchbase/contrib/genhash/genhash.c +372 -0
  56. data/ext/libcouchbase/contrib/genhash/genhash.h +235 -0
  57. data/ext/libcouchbase/contrib/gtest-1.7.0/CHANGES +157 -0
  58. data/ext/libcouchbase/contrib/gtest-1.7.0/CMakeLists.txt +252 -0
  59. data/ext/libcouchbase/contrib/gtest-1.7.0/CONTRIBUTORS +37 -0
  60. data/ext/libcouchbase/contrib/gtest-1.7.0/LICENSE +28 -0
  61. data/ext/libcouchbase/contrib/gtest-1.7.0/MINIFY.sh +15 -0
  62. data/ext/libcouchbase/contrib/gtest-1.7.0/README +435 -0
  63. data/ext/libcouchbase/contrib/gtest-1.7.0/cmake/internal_utils.cmake +227 -0
  64. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-death-test.h +294 -0
  65. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-message.h +250 -0
  66. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h +1421 -0
  67. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h.pump +487 -0
  68. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-printers.h +855 -0
  69. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-spi.h +232 -0
  70. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-test-part.h +179 -0
  71. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-typed-test.h +259 -0
  72. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest.h +2291 -0
  73. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_pred_impl.h +358 -0
  74. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_prod.h +58 -0
  75. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h +319 -0
  76. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h +206 -0
  77. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-internal.h +1158 -0
  78. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h +233 -0
  79. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h +5143 -0
  80. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
  81. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h +619 -0
  82. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-port.h +1947 -0
  83. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-string.h +167 -0
  84. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h +1012 -0
  85. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump +339 -0
  86. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h +3331 -0
  87. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump +297 -0
  88. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-all.cc +48 -0
  89. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-death-test.cc +1344 -0
  90. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-filepath.cc +382 -0
  91. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-internal-inl.h +1218 -0
  92. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-port.cc +805 -0
  93. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-printers.cc +363 -0
  94. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-test-part.cc +110 -0
  95. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-typed-test.cc +110 -0
  96. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest.cc +5015 -0
  97. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest_main.cc +38 -0
  98. data/ext/libcouchbase/contrib/http_parser/LICENSE-MIT +23 -0
  99. data/ext/libcouchbase/contrib/http_parser/README.md +178 -0
  100. data/ext/libcouchbase/contrib/http_parser/http_parser.c +2060 -0
  101. data/ext/libcouchbase/contrib/http_parser/http_parser.h +321 -0
  102. data/ext/libcouchbase/contrib/jsonsl/LICENSE +20 -0
  103. data/ext/libcouchbase/contrib/jsonsl/jsonsl.c +1452 -0
  104. data/ext/libcouchbase/contrib/jsonsl/jsonsl.h +971 -0
  105. data/ext/libcouchbase/contrib/lcb-jsoncpp/CMakeLists.txt +6 -0
  106. data/ext/libcouchbase/contrib/lcb-jsoncpp/LICENSE +55 -0
  107. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp-forwards.h +255 -0
  108. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4892 -0
  109. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.h +1961 -0
  110. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +8 -0
  111. data/ext/libcouchbase/contrib/snappy/COPYING +28 -0
  112. data/ext/libcouchbase/contrib/snappy/snappy-c.cc +90 -0
  113. data/ext/libcouchbase/contrib/snappy/snappy-c.h +138 -0
  114. data/ext/libcouchbase/contrib/snappy/snappy-internal.h +150 -0
  115. data/ext/libcouchbase/contrib/snappy/snappy-lcb-msvc.h +5 -0
  116. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +71 -0
  117. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.h +137 -0
  118. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.cc +42 -0
  119. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.h +491 -0
  120. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +98 -0
  121. data/ext/libcouchbase/contrib/snappy/snappy.cc +1307 -0
  122. data/ext/libcouchbase/contrib/snappy/snappy.h +184 -0
  123. data/ext/libcouchbase/contrib/win32-defs/iocpdefs.h +133 -0
  124. data/ext/libcouchbase/contrib/win32-defs/mingwdefs.h +4396 -0
  125. data/ext/libcouchbase/contrib/win32-defs/win_stdint.h +258 -0
  126. data/ext/libcouchbase/example/CMakeLists.txt +37 -0
  127. data/ext/libcouchbase/example/README.markdown +47 -0
  128. data/ext/libcouchbase/example/db/db.c +167 -0
  129. data/ext/libcouchbase/example/db/vb.c +227 -0
  130. data/ext/libcouchbase/example/instancepool/main.cc +102 -0
  131. data/ext/libcouchbase/example/instancepool/pool.cc +102 -0
  132. data/ext/libcouchbase/example/instancepool/pool.h +69 -0
  133. data/ext/libcouchbase/example/libeventdirect/main.c +148 -0
  134. data/ext/libcouchbase/example/mcc/mcc.cc +246 -0
  135. data/ext/libcouchbase/example/minimal/minimal.c +130 -0
  136. data/ext/libcouchbase/example/observe/observe.c +146 -0
  137. data/ext/libcouchbase/example/subdoc/subdoc-multi.cc +132 -0
  138. data/ext/libcouchbase/example/subdoc/subdoc-simple.cc +191 -0
  139. data/ext/libcouchbase/example/tick/tick.c +119 -0
  140. data/ext/libcouchbase/example/views/views-example.cc +83 -0
  141. data/ext/libcouchbase/include/libcouchbase/_cxxwrap.h +150 -0
  142. data/ext/libcouchbase/include/libcouchbase/api-legacy.h +1689 -0
  143. data/ext/libcouchbase/include/libcouchbase/api3.h +2 -0
  144. data/ext/libcouchbase/include/libcouchbase/assert.h +44 -0
  145. data/ext/libcouchbase/include/libcouchbase/cbft.h +109 -0
  146. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +356 -0
  147. data/ext/libcouchbase/include/libcouchbase/cntl.h +937 -0
  148. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +23 -0
  149. data/ext/libcouchbase/include/libcouchbase/couchbase.h +3677 -0
  150. data/ext/libcouchbase/include/libcouchbase/deprecated.h +300 -0
  151. data/ext/libcouchbase/include/libcouchbase/error.h +595 -0
  152. data/ext/libcouchbase/include/libcouchbase/http.h +1 -0
  153. data/ext/libcouchbase/include/libcouchbase/iops.h +1050 -0
  154. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +263 -0
  155. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +132 -0
  156. data/ext/libcouchbase/include/libcouchbase/n1ql.h +364 -0
  157. data/ext/libcouchbase/include/libcouchbase/pktfwd.h +270 -0
  158. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +367 -0
  159. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr-inl.c +76 -0
  160. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr.h +199 -0
  161. data/ext/libcouchbase/include/libcouchbase/subdoc.h +312 -0
  162. data/ext/libcouchbase/include/libcouchbase/sysdefs.h +98 -0
  163. data/ext/libcouchbase/include/libcouchbase/vbucket.h +643 -0
  164. data/ext/libcouchbase/include/libcouchbase/views.h +298 -0
  165. data/ext/libcouchbase/include/libcouchbase/visibility.h +65 -0
  166. data/ext/libcouchbase/include/memcached/COPYING +30 -0
  167. data/ext/libcouchbase/include/memcached/README +10 -0
  168. data/ext/libcouchbase/include/memcached/protocol_binary.h +1916 -0
  169. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  170. data/ext/libcouchbase/packaging/README +7 -0
  171. data/ext/libcouchbase/packaging/abicheck/.gitignore +4 -0
  172. data/ext/libcouchbase/packaging/abicheck/Makefile +17 -0
  173. data/ext/libcouchbase/packaging/abicheck/README.md +27 -0
  174. data/ext/libcouchbase/packaging/abicheck/template.xml +3 -0
  175. data/ext/libcouchbase/packaging/deb/compat +1 -0
  176. data/ext/libcouchbase/packaging/deb/control +73 -0
  177. data/ext/libcouchbase/packaging/deb/copyright +10 -0
  178. data/ext/libcouchbase/packaging/deb/libcouchbase-dev.docs +3 -0
  179. data/ext/libcouchbase/packaging/deb/package.mk +31 -0
  180. data/ext/libcouchbase/packaging/deb/rules +46 -0
  181. data/ext/libcouchbase/packaging/deb/source/format +1 -0
  182. data/ext/libcouchbase/packaging/distinfo/README +1 -0
  183. data/ext/libcouchbase/packaging/distinfo/distinfo.cmake.in +4 -0
  184. data/ext/libcouchbase/packaging/dllversion.rc.in +39 -0
  185. data/ext/libcouchbase/packaging/libcouchbase.pc.in +10 -0
  186. data/ext/libcouchbase/packaging/nuget/libcouchbase.autopkg +76 -0
  187. data/ext/libcouchbase/packaging/parse-git-describe.pl +166 -0
  188. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +108 -0
  189. data/ext/libcouchbase/packaging/rpm/package.mk +40 -0
  190. data/ext/libcouchbase/plugins/io/iocp/CMakeLists.txt +9 -0
  191. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.c +466 -0
  192. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.h +217 -0
  193. data/ext/libcouchbase/plugins/io/iocp/iocp_loop.c +295 -0
  194. data/ext/libcouchbase/plugins/io/iocp/iocp_timer.c +79 -0
  195. data/ext/libcouchbase/plugins/io/iocp/iocp_util.c +229 -0
  196. data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +29 -0
  197. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +65 -0
  198. data/ext/libcouchbase/plugins/io/libev/plugin-libev.c +289 -0
  199. data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +29 -0
  200. data/ext/libcouchbase/plugins/io/libevent/libevent_io_opts.h +67 -0
  201. data/ext/libcouchbase/plugins/io/libevent/plugin-libevent.c +292 -0
  202. data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +42 -0
  203. data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +212 -0
  204. data/ext/libcouchbase/plugins/io/libuv/libuv_io_opts.h +118 -0
  205. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +148 -0
  206. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +648 -0
  207. data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +11 -0
  208. data/ext/libcouchbase/plugins/io/select/plugin-select.c +448 -0
  209. data/ext/libcouchbase/plugins/io/select/select_io_opts.h +39 -0
  210. data/ext/libcouchbase/src/README.md +103 -0
  211. data/ext/libcouchbase/src/aspend.h +106 -0
  212. data/ext/libcouchbase/src/auth.cc +74 -0
  213. data/ext/libcouchbase/src/auth.h +54 -0
  214. data/ext/libcouchbase/src/bootstrap.c +269 -0
  215. data/ext/libcouchbase/src/bootstrap.h +129 -0
  216. data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +495 -0
  217. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  218. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  219. data/ext/libcouchbase/src/bucketconfig/bc_http.h +82 -0
  220. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  221. data/ext/libcouchbase/src/bucketconfig/clconfig.h +681 -0
  222. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  223. data/ext/libcouchbase/src/callbacks.c +378 -0
  224. data/ext/libcouchbase/src/cbft.cc +210 -0
  225. data/ext/libcouchbase/src/cntl.cc +847 -0
  226. data/ext/libcouchbase/src/config_static.h +159 -0
  227. data/ext/libcouchbase/src/connspec.cc +462 -0
  228. data/ext/libcouchbase/src/connspec.h +105 -0
  229. data/ext/libcouchbase/src/ctx-log-inl.h +27 -0
  230. data/ext/libcouchbase/src/dump.c +98 -0
  231. data/ext/libcouchbase/src/getconfig.c +100 -0
  232. data/ext/libcouchbase/src/gethrtime.c +109 -0
  233. data/ext/libcouchbase/src/handler.c +922 -0
  234. data/ext/libcouchbase/src/hashset.c +164 -0
  235. data/ext/libcouchbase/src/hashset.h +86 -0
  236. data/ext/libcouchbase/src/hashtable.c +75 -0
  237. data/ext/libcouchbase/src/hdr_timings.c +92 -0
  238. data/ext/libcouchbase/src/hostlist.cc +301 -0
  239. data/ext/libcouchbase/src/hostlist.h +171 -0
  240. data/ext/libcouchbase/src/http/http-priv.h +307 -0
  241. data/ext/libcouchbase/src/http/http.cc +633 -0
  242. data/ext/libcouchbase/src/http/http.h +34 -0
  243. data/ext/libcouchbase/src/http/http_io.cc +307 -0
  244. data/ext/libcouchbase/src/instance.cc +722 -0
  245. data/ext/libcouchbase/src/internal.h +244 -0
  246. data/ext/libcouchbase/src/iofactory.c +575 -0
  247. data/ext/libcouchbase/src/jsparse/parser.cc +519 -0
  248. data/ext/libcouchbase/src/jsparse/parser.h +173 -0
  249. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  250. data/ext/libcouchbase/src/lcbht/lcbht.h +199 -0
  251. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  252. data/ext/libcouchbase/src/lcbio/connect.h +364 -0
  253. data/ext/libcouchbase/src/lcbio/ctx.c +611 -0
  254. data/ext/libcouchbase/src/lcbio/ctx.h +405 -0
  255. data/ext/libcouchbase/src/lcbio/iotable.c +290 -0
  256. data/ext/libcouchbase/src/lcbio/iotable.h +84 -0
  257. data/ext/libcouchbase/src/lcbio/ioutils.c +350 -0
  258. data/ext/libcouchbase/src/lcbio/ioutils.h +203 -0
  259. data/ext/libcouchbase/src/lcbio/lcbio.h +51 -0
  260. data/ext/libcouchbase/src/lcbio/manager.c +584 -0
  261. data/ext/libcouchbase/src/lcbio/manager.h +156 -0
  262. data/ext/libcouchbase/src/lcbio/protoctx.c +84 -0
  263. data/ext/libcouchbase/src/lcbio/rw-inl.h +115 -0
  264. data/ext/libcouchbase/src/lcbio/ssl.h +149 -0
  265. data/ext/libcouchbase/src/lcbio/timer-ng.h +179 -0
  266. data/ext/libcouchbase/src/lcbio/timer.c +132 -0
  267. data/ext/libcouchbase/src/legacy.c +430 -0
  268. data/ext/libcouchbase/src/list.c +144 -0
  269. data/ext/libcouchbase/src/list.h +127 -0
  270. data/ext/libcouchbase/src/logging.c +244 -0
  271. data/ext/libcouchbase/src/logging.h +86 -0
  272. data/ext/libcouchbase/src/mc/compress.c +90 -0
  273. data/ext/libcouchbase/src/mc/compress.h +61 -0
  274. data/ext/libcouchbase/src/mc/forward.c +186 -0
  275. data/ext/libcouchbase/src/mc/forward.h +90 -0
  276. data/ext/libcouchbase/src/mc/iovcursor-inl.h +279 -0
  277. data/ext/libcouchbase/src/mc/iovcursor.h +66 -0
  278. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +111 -0
  279. data/ext/libcouchbase/src/mc/mcreq.c +954 -0
  280. data/ext/libcouchbase/src/mc/mcreq.h +977 -0
  281. data/ext/libcouchbase/src/mcserver/mcserver.c +784 -0
  282. data/ext/libcouchbase/src/mcserver/mcserver.h +121 -0
  283. data/ext/libcouchbase/src/mcserver/negotiate.c +656 -0
  284. data/ext/libcouchbase/src/mcserver/negotiate.h +119 -0
  285. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +860 -0
  286. data/ext/libcouchbase/src/n1ql/n1ql-internal.h +22 -0
  287. data/ext/libcouchbase/src/n1ql/n1ql.cc +729 -0
  288. data/ext/libcouchbase/src/n1ql/params.cc +215 -0
  289. data/ext/libcouchbase/src/netbuf/netbuf-defs.h +89 -0
  290. data/ext/libcouchbase/src/netbuf/netbuf-mblock.h +235 -0
  291. data/ext/libcouchbase/src/netbuf/netbuf.c +929 -0
  292. data/ext/libcouchbase/src/netbuf/netbuf.h +452 -0
  293. data/ext/libcouchbase/src/newconfig.c +385 -0
  294. data/ext/libcouchbase/src/nodeinfo.cc +194 -0
  295. data/ext/libcouchbase/src/operations/cbflush.c +71 -0
  296. data/ext/libcouchbase/src/operations/counter.c +116 -0
  297. data/ext/libcouchbase/src/operations/durability-cas.c +224 -0
  298. data/ext/libcouchbase/src/operations/durability-seqno.c +157 -0
  299. data/ext/libcouchbase/src/operations/durability.c +668 -0
  300. data/ext/libcouchbase/src/operations/durability_internal.h +199 -0
  301. data/ext/libcouchbase/src/operations/get.c +409 -0
  302. data/ext/libcouchbase/src/operations/observe-seqno.c +96 -0
  303. data/ext/libcouchbase/src/operations/observe.c +340 -0
  304. data/ext/libcouchbase/src/operations/pktfwd.c +86 -0
  305. data/ext/libcouchbase/src/operations/remove.c +83 -0
  306. data/ext/libcouchbase/src/operations/stats.c +461 -0
  307. data/ext/libcouchbase/src/operations/store.c +360 -0
  308. data/ext/libcouchbase/src/operations/subdoc.cc +510 -0
  309. data/ext/libcouchbase/src/operations/touch.c +81 -0
  310. data/ext/libcouchbase/src/packetutils.c +60 -0
  311. data/ext/libcouchbase/src/packetutils.h +147 -0
  312. data/ext/libcouchbase/src/probes.d +211 -0
  313. data/ext/libcouchbase/src/rdb/bigalloc.c +225 -0
  314. data/ext/libcouchbase/src/rdb/bigalloc.h +73 -0
  315. data/ext/libcouchbase/src/rdb/chunkalloc.c +174 -0
  316. data/ext/libcouchbase/src/rdb/libcalloc.c +94 -0
  317. data/ext/libcouchbase/src/rdb/rope.c +419 -0
  318. data/ext/libcouchbase/src/rdb/rope.h +488 -0
  319. data/ext/libcouchbase/src/retrychk.c +113 -0
  320. data/ext/libcouchbase/src/retryq.c +424 -0
  321. data/ext/libcouchbase/src/retryq.h +157 -0
  322. data/ext/libcouchbase/src/ringbuffer.c +442 -0
  323. data/ext/libcouchbase/src/ringbuffer.h +100 -0
  324. data/ext/libcouchbase/src/settings.c +95 -0
  325. data/ext/libcouchbase/src/settings.h +188 -0
  326. data/ext/libcouchbase/src/simplestring.c +211 -0
  327. data/ext/libcouchbase/src/simplestring.h +228 -0
  328. data/ext/libcouchbase/src/sllist-inl.h +197 -0
  329. data/ext/libcouchbase/src/sllist.h +76 -0
  330. data/ext/libcouchbase/src/ssl/CMakeLists.txt +23 -0
  331. data/ext/libcouchbase/src/ssl/ssl_c.c +415 -0
  332. data/ext/libcouchbase/src/ssl/ssl_common.c +454 -0
  333. data/ext/libcouchbase/src/ssl/ssl_e.c +408 -0
  334. data/ext/libcouchbase/src/ssl/ssl_iot_common.h +180 -0
  335. data/ext/libcouchbase/src/ssobuf.h +82 -0
  336. data/ext/libcouchbase/src/strcodecs/base64.c +123 -0
  337. data/ext/libcouchbase/src/strcodecs/strcodecs.h +285 -0
  338. data/ext/libcouchbase/src/timings.c +208 -0
  339. data/ext/libcouchbase/src/trace.h +105 -0
  340. data/ext/libcouchbase/src/utilities.c +171 -0
  341. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -0
  342. data/ext/libcouchbase/src/vbucket/aliases.h +35 -0
  343. data/ext/libcouchbase/src/vbucket/crc32.h +83 -0
  344. data/ext/libcouchbase/src/vbucket/hash.h +30 -0
  345. data/ext/libcouchbase/src/vbucket/json-inl.h +112 -0
  346. data/ext/libcouchbase/src/vbucket/ketama.c +66 -0
  347. data/ext/libcouchbase/src/vbucket/rfc1321/global.h +32 -0
  348. data/ext/libcouchbase/src/vbucket/rfc1321/md5.h +35 -0
  349. data/ext/libcouchbase/src/vbucket/rfc1321/md5c-inl.h +335 -0
  350. data/ext/libcouchbase/src/vbucket/vbucket.c +1543 -0
  351. data/ext/libcouchbase/src/views/docreq.c +194 -0
  352. data/ext/libcouchbase/src/views/docreq.h +83 -0
  353. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  354. data/ext/libcouchbase/src/views/viewreq.h +36 -0
  355. data/ext/libcouchbase/src/wait.c +161 -0
  356. data/ext/libcouchbase/tests/CMakeLists.txt +140 -0
  357. data/ext/libcouchbase/tests/basic/t_base64.cc +81 -0
  358. data/ext/libcouchbase/tests/basic/t_ccbc103.cc +95 -0
  359. data/ext/libcouchbase/tests/basic/t_connstr.cc +404 -0
  360. data/ext/libcouchbase/tests/basic/t_creds.cc +32 -0
  361. data/ext/libcouchbase/tests/basic/t_ctlcodes.cc +92 -0
  362. data/ext/libcouchbase/tests/basic/t_hashset.cc +262 -0
  363. data/ext/libcouchbase/tests/basic/t_host.cc +198 -0
  364. data/ext/libcouchbase/tests/basic/t_jsparse.cc +137 -0
  365. data/ext/libcouchbase/tests/basic/t_jsparse.h +589 -0
  366. data/ext/libcouchbase/tests/basic/t_list.cc +155 -0
  367. data/ext/libcouchbase/tests/basic/t_logger.cc +65 -0
  368. data/ext/libcouchbase/tests/basic/t_misc.cc +24 -0
  369. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +18 -0
  370. data/ext/libcouchbase/tests/basic/t_netbuf.cc +446 -0
  371. data/ext/libcouchbase/tests/basic/t_packet.cc +222 -0
  372. data/ext/libcouchbase/tests/basic/t_ringbuffer.cc +278 -0
  373. data/ext/libcouchbase/tests/basic/t_slist.cc +429 -0
  374. data/ext/libcouchbase/tests/basic/t_strerror.cc +64 -0
  375. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  376. data/ext/libcouchbase/tests/basic/t_urlencode.cc +132 -0
  377. data/ext/libcouchbase/tests/check-all.cc +608 -0
  378. data/ext/libcouchbase/tests/htparse/t_basic.cc +193 -0
  379. data/ext/libcouchbase/tests/ioserver/connection.cc +166 -0
  380. data/ext/libcouchbase/tests/ioserver/future.cc +50 -0
  381. data/ext/libcouchbase/tests/ioserver/ioserver.cc +104 -0
  382. data/ext/libcouchbase/tests/ioserver/ioserver.h +478 -0
  383. data/ext/libcouchbase/tests/ioserver/socket.cc +88 -0
  384. data/ext/libcouchbase/tests/ioserver/ssl_connection.cc +145 -0
  385. data/ext/libcouchbase/tests/ioserver/threads-pthreads.cc +119 -0
  386. data/ext/libcouchbase/tests/ioserver/threads-win32.cc +117 -0
  387. data/ext/libcouchbase/tests/ioserver/threads.h +66 -0
  388. data/ext/libcouchbase/tests/iotests/iotests.h +15 -0
  389. data/ext/libcouchbase/tests/iotests/mock-environment.cc +524 -0
  390. data/ext/libcouchbase/tests/iotests/mock-environment.h +385 -0
  391. data/ext/libcouchbase/tests/iotests/mock-unit-test.cc +67 -0
  392. data/ext/libcouchbase/tests/iotests/mock-unit-test.h +61 -0
  393. data/ext/libcouchbase/tests/iotests/serverparams.h +76 -0
  394. data/ext/libcouchbase/tests/iotests/t_arithmetic.cc +143 -0
  395. data/ext/libcouchbase/tests/iotests/t_behavior.cc +226 -0
  396. data/ext/libcouchbase/tests/iotests/t_configcache.cc +117 -0
  397. data/ext/libcouchbase/tests/iotests/t_confmon.cc +241 -0
  398. data/ext/libcouchbase/tests/iotests/t_durability.cc +1059 -0
  399. data/ext/libcouchbase/tests/iotests/t_forward.cc +110 -0
  400. data/ext/libcouchbase/tests/iotests/t_get.cc +512 -0
  401. data/ext/libcouchbase/tests/iotests/t_http.cc +438 -0
  402. data/ext/libcouchbase/tests/iotests/t_iops.cc +175 -0
  403. data/ext/libcouchbase/tests/iotests/t_lock.cc +275 -0
  404. data/ext/libcouchbase/tests/iotests/t_misc.cc +713 -0
  405. data/ext/libcouchbase/tests/iotests/t_mutate.cc +609 -0
  406. data/ext/libcouchbase/tests/iotests/t_n1ql.cc +270 -0
  407. data/ext/libcouchbase/tests/iotests/t_netfail.cc +654 -0
  408. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +157 -0
  409. data/ext/libcouchbase/tests/iotests/t_regression.cc +321 -0
  410. data/ext/libcouchbase/tests/iotests/t_sched.cc +88 -0
  411. data/ext/libcouchbase/tests/iotests/t_serverops.cc +230 -0
  412. data/ext/libcouchbase/tests/iotests/t_smoke.cc +528 -0
  413. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +822 -0
  414. data/ext/libcouchbase/tests/iotests/t_syncmode.cc +64 -0
  415. data/ext/libcouchbase/tests/iotests/t_views.cc +405 -0
  416. data/ext/libcouchbase/tests/iotests/testutil.cc +250 -0
  417. data/ext/libcouchbase/tests/iotests/testutil.h +163 -0
  418. data/ext/libcouchbase/tests/mc/mctest.h +119 -0
  419. data/ext/libcouchbase/tests/mc/pktmaker.h +101 -0
  420. data/ext/libcouchbase/tests/mc/t_alloc.cc +269 -0
  421. data/ext/libcouchbase/tests/mc/t_context.cc +100 -0
  422. data/ext/libcouchbase/tests/mc/t_flush.cc +185 -0
  423. data/ext/libcouchbase/tests/mc/t_forward.cc +239 -0
  424. data/ext/libcouchbase/tests/mc/t_ioflush.cc +102 -0
  425. data/ext/libcouchbase/tests/mc/t_iovcursor.cc +173 -0
  426. data/ext/libcouchbase/tests/mocksupport/procutil.c +305 -0
  427. data/ext/libcouchbase/tests/mocksupport/procutil.h +89 -0
  428. data/ext/libcouchbase/tests/mocksupport/server.c +391 -0
  429. data/ext/libcouchbase/tests/mocksupport/server.h +72 -0
  430. data/ext/libcouchbase/tests/mocksupport/timeout.c +69 -0
  431. data/ext/libcouchbase/tests/nonio_tests.cc +23 -0
  432. data/ext/libcouchbase/tests/rdb/rdbtest.h +133 -0
  433. data/ext/libcouchbase/tests/rdb/t_basic.cc +128 -0
  434. data/ext/libcouchbase/tests/rdb/t_bigalloc.cc +93 -0
  435. data/ext/libcouchbase/tests/rdb/t_refs.cc +112 -0
  436. data/ext/libcouchbase/tests/socktests/socktest.cc +347 -0
  437. data/ext/libcouchbase/tests/socktests/socktest.h +448 -0
  438. data/ext/libcouchbase/tests/socktests/t_basic.cc +143 -0
  439. data/ext/libcouchbase/tests/socktests/t_ctx.cc +73 -0
  440. data/ext/libcouchbase/tests/socktests/t_manager.cc +179 -0
  441. data/ext/libcouchbase/tests/socktests/t_putex.cc +256 -0
  442. data/ext/libcouchbase/tests/socktests/t_read.cc +187 -0
  443. data/ext/libcouchbase/tests/socktests/t_reentrant.cc +143 -0
  444. data/ext/libcouchbase/tests/socktests/t_ssl.cc +80 -0
  445. data/ext/libcouchbase/tests/socktests/t_write.cc +95 -0
  446. data/ext/libcouchbase/tests/start_mock.bat +15 -0
  447. data/ext/libcouchbase/tests/start_mock.sh +42 -0
  448. data/ext/libcouchbase/tests/unit_tests.cc +43 -0
  449. data/ext/libcouchbase/tests/vbucket/confdata/bad.json +101 -0
  450. data/ext/libcouchbase/tests/vbucket/confdata/full_25.json +363 -0
  451. data/ext/libcouchbase/tests/vbucket/confdata/memd_25.json +90 -0
  452. data/ext/libcouchbase/tests/vbucket/confdata/memd_30.json +1 -0
  453. data/ext/libcouchbase/tests/vbucket/confdata/memd_45.json +1 -0
  454. data/ext/libcouchbase/tests/vbucket/confdata/terse_25.json +291 -0
  455. data/ext/libcouchbase/tests/vbucket/confdata/terse_30.json +1 -0
  456. data/ext/libcouchbase/tests/vbucket/t_config.cc +341 -0
  457. data/ext/libcouchbase/tools/CMakeLists.txt +51 -0
  458. data/ext/libcouchbase/tools/cbc-handlers.h +462 -0
  459. data/ext/libcouchbase/tools/cbc-n1qlback.cc +439 -0
  460. data/ext/libcouchbase/tools/cbc-pillowfight.cc +822 -0
  461. data/ext/libcouchbase/tools/cbc.cc +1541 -0
  462. data/ext/libcouchbase/tools/common/histogram.cc +43 -0
  463. data/ext/libcouchbase/tools/common/histogram.h +23 -0
  464. data/ext/libcouchbase/tools/common/my_inttypes.h +22 -0
  465. data/ext/libcouchbase/tools/common/options.cc +420 -0
  466. data/ext/libcouchbase/tools/common/options.h +81 -0
  467. data/ext/libcouchbase/tools/docgen/docgen.h +469 -0
  468. data/ext/libcouchbase/tools/docgen/loc.h +210 -0
  469. data/ext/libcouchbase/tools/docgen/placeholders.h +211 -0
  470. data/ext/libcouchbase/tools/docgen/seqgen.h +94 -0
  471. data/lib/libcouchbase.rb +36 -0
  472. data/lib/libcouchbase/bucket.rb +819 -0
  473. data/lib/libcouchbase/callbacks.rb +72 -0
  474. data/lib/libcouchbase/connection.rb +790 -0
  475. data/lib/libcouchbase/design_docs.rb +86 -0
  476. data/lib/libcouchbase/error.rb +68 -0
  477. data/lib/libcouchbase/ext/libcouchbase.rb +1135 -0
  478. data/lib/libcouchbase/ext/libcouchbase/cmdbase.rb +23 -0
  479. data/lib/libcouchbase/ext/libcouchbase/cmdcounter.rb +36 -0
  480. data/lib/libcouchbase/ext/libcouchbase/cmdendure.rb +26 -0
  481. data/lib/libcouchbase/ext/libcouchbase/cmdfts.rb +24 -0
  482. data/lib/libcouchbase/ext/libcouchbase/cmdget.rb +30 -0
  483. data/lib/libcouchbase/ext/libcouchbase/cmdgetreplica.rb +49 -0
  484. data/lib/libcouchbase/ext/libcouchbase/cmdhttp.rb +58 -0
  485. data/lib/libcouchbase/ext/libcouchbase/cmdn1ql.rb +40 -0
  486. data/lib/libcouchbase/ext/libcouchbase/cmdobseqno.rb +33 -0
  487. data/lib/libcouchbase/ext/libcouchbase/cmdobserve.rb +30 -0
  488. data/lib/libcouchbase/ext/libcouchbase/cmdstore.rb +40 -0
  489. data/lib/libcouchbase/ext/libcouchbase/cmdstoredur.rb +45 -0
  490. data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +49 -0
  491. data/lib/libcouchbase/ext/libcouchbase/cmdverbosity.rb +29 -0
  492. data/lib/libcouchbase/ext/libcouchbase/cmdviewquery.rb +61 -0
  493. data/lib/libcouchbase/ext/libcouchbase/contigbuf.rb +14 -0
  494. data/lib/libcouchbase/ext/libcouchbase/create_st.rb +15 -0
  495. data/lib/libcouchbase/ext/libcouchbase/create_st0.rb +23 -0
  496. data/lib/libcouchbase/ext/libcouchbase/create_st1.rb +26 -0
  497. data/lib/libcouchbase/ext/libcouchbase/create_st2.rb +32 -0
  498. data/lib/libcouchbase/ext/libcouchbase/create_st3.rb +26 -0
  499. data/lib/libcouchbase/ext/libcouchbase/crst_u.rb +20 -0
  500. data/lib/libcouchbase/ext/libcouchbase/durability_opts_st_v.rb +11 -0
  501. data/lib/libcouchbase/ext/libcouchbase/durability_opts_t.rb +14 -0
  502. data/lib/libcouchbase/ext/libcouchbase/durabilityopt_sv0.rb +63 -0
  503. data/lib/libcouchbase/ext/libcouchbase/enums.rb +991 -0
  504. data/lib/libcouchbase/ext/libcouchbase/fragbuf.rb +18 -0
  505. data/lib/libcouchbase/ext/libcouchbase/ftshandle.rb +7 -0
  506. data/lib/libcouchbase/ext/libcouchbase/histogram.rb +34 -0
  507. data/lib/libcouchbase/ext/libcouchbase/http_request_t.rb +7 -0
  508. data/lib/libcouchbase/ext/libcouchbase/keybuf.rb +20 -0
  509. data/lib/libcouchbase/ext/libcouchbase/multicmd_ctx.rb +30 -0
  510. data/lib/libcouchbase/ext/libcouchbase/mutation_token.rb +17 -0
  511. data/lib/libcouchbase/ext/libcouchbase/n1qlhandle.rb +7 -0
  512. data/lib/libcouchbase/ext/libcouchbase/n1qlparams.rb +7 -0
  513. data/lib/libcouchbase/ext/libcouchbase/respbase.rb +29 -0
  514. data/lib/libcouchbase/ext/libcouchbase/respcounter.rb +32 -0
  515. data/lib/libcouchbase/ext/libcouchbase/respendure.rb +49 -0
  516. data/lib/libcouchbase/ext/libcouchbase/respfts.rb +40 -0
  517. data/lib/libcouchbase/ext/libcouchbase/respget.rb +44 -0
  518. data/lib/libcouchbase/ext/libcouchbase/resphttp.rb +48 -0
  519. data/lib/libcouchbase/ext/libcouchbase/respmcversion.rb +38 -0
  520. data/lib/libcouchbase/ext/libcouchbase/respn1ql.rb +41 -0
  521. data/lib/libcouchbase/ext/libcouchbase/respobseqno.rb +52 -0
  522. data/lib/libcouchbase/ext/libcouchbase/respobserve.rb +41 -0
  523. data/lib/libcouchbase/ext/libcouchbase/respserverbase.rb +32 -0
  524. data/lib/libcouchbase/ext/libcouchbase/respstats.rb +38 -0
  525. data/lib/libcouchbase/ext/libcouchbase/respstore.rb +32 -0
  526. data/lib/libcouchbase/ext/libcouchbase/respstoredur.rb +38 -0
  527. data/lib/libcouchbase/ext/libcouchbase/respsubdoc.rb +35 -0
  528. data/lib/libcouchbase/ext/libcouchbase/respviewquery.rb +67 -0
  529. data/lib/libcouchbase/ext/libcouchbase/sdentry.rb +22 -0
  530. data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +26 -0
  531. data/lib/libcouchbase/ext/libcouchbase/t.rb +7 -0
  532. data/lib/libcouchbase/ext/libcouchbase/valbuf.rb +22 -0
  533. data/lib/libcouchbase/ext/libcouchbase/valbuf_u_buf.rb +14 -0
  534. data/lib/libcouchbase/ext/libcouchbase/viewhandle.rb +7 -0
  535. data/lib/libcouchbase/ext/libcouchbase_iocp.rb +26 -0
  536. data/lib/libcouchbase/ext/libcouchbase_libuv.rb +18 -0
  537. data/lib/libcouchbase/ext/tasks.rb +87 -0
  538. data/lib/libcouchbase/n1ql.rb +73 -0
  539. data/lib/libcouchbase/query_full_text.rb +147 -0
  540. data/lib/libcouchbase/query_n1ql.rb +121 -0
  541. data/lib/libcouchbase/query_view.rb +129 -0
  542. data/lib/libcouchbase/results_fiber.rb +262 -0
  543. data/lib/libcouchbase/results_native.rb +211 -0
  544. data/lib/libcouchbase/version.rb +5 -0
  545. data/libcouchbase.gemspec +61 -0
  546. data/spec/bucket_spec.rb +270 -0
  547. data/spec/connection_spec.rb +277 -0
  548. data/spec/design_docs_spec.rb +23 -0
  549. data/spec/error_spec.rb +26 -0
  550. data/spec/fts_spec.rb +129 -0
  551. data/spec/n1ql_spec.rb +201 -0
  552. data/spec/results_libuv_spec.rb +229 -0
  553. data/spec/results_native_spec.rb +259 -0
  554. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/design.json +1 -0
  555. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/data-0000.cbb +0 -0
  556. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/failover.json +1 -0
  557. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/meta.json +1 -0
  558. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/seqno.json +1 -0
  559. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/snapshot_markers.json +1 -0
  560. data/spec/view_spec.rb +195 -0
  561. metadata +775 -0
@@ -0,0 +1,439 @@
1
+ /*
2
+ * Copyright 2015 Couchbase, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #define LCB_NO_DEPR_CXX_CTORS
18
+
19
+ #include "config.h"
20
+ #include <sys/types.h>
21
+ #include <libcouchbase/couchbase.h>
22
+ #include <libcouchbase/api3.h>
23
+ #include <libcouchbase/n1ql.h>
24
+ #include <libcouchbase/vbucket.h>
25
+ #include <iostream>
26
+ #include <list>
27
+ #include <cassert>
28
+ #include <cstdio>
29
+ #include <cstdlib>
30
+ #include <cerrno>
31
+ #include <fstream>
32
+ #include <algorithm> // random_shuffle
33
+ #include <stdexcept>
34
+ #include <sstream>
35
+ #ifndef WIN32
36
+ #include <pthread.h>
37
+ #include <unistd.h> // isatty()
38
+ #endif
39
+ #include "common/options.h"
40
+ #include "common/histogram.h"
41
+
42
+ using namespace cbc;
43
+ using namespace cliopts;
44
+ using std::vector;
45
+ using std::string;
46
+ using std::cerr;
47
+ using std::endl;
48
+
49
+ #ifndef _WIN32
50
+ static bool use_ansi_codes = true;
51
+ #else
52
+ static bool use_ansi_codes = false;
53
+ #endif
54
+
55
+ static void do_or_die(lcb_error_t rc)
56
+ {
57
+ if (rc != LCB_SUCCESS) {
58
+ std::stringstream ss;
59
+ ss << "[" << std::hex << rc << "] " << lcb_strerror(NULL, rc);
60
+ throw std::runtime_error(ss.str());
61
+ }
62
+ }
63
+
64
+ class Metrics {
65
+ public:
66
+ Metrics()
67
+ : n_rows(0), n_queries(0), n_errors(0), last_update(time(NULL)), hg(NULL)
68
+ {
69
+ #ifndef _WIN32
70
+ if (pthread_mutex_init(&m_lock, NULL) != 0) {
71
+ abort();
72
+ }
73
+ #endif
74
+ start_time = last_update;
75
+ }
76
+
77
+ void update_row(size_t n = 1) { n_rows += n; update_display(); }
78
+ void update_done(size_t n = 1) { n_queries += n; update_display(); }
79
+ void update_error(size_t n = 1) { n_errors += n; update_display(); }
80
+
81
+ void update_timings(lcb_U64 duration) {
82
+ if (hg != NULL) {
83
+ hg->record(duration);
84
+ }
85
+ }
86
+
87
+ #ifndef _WIN32
88
+ bool is_tty() const { return isatty(STDOUT_FILENO); }
89
+ void lock() { pthread_mutex_lock(&m_lock); }
90
+ void unlock() { pthread_mutex_unlock(&m_lock); }
91
+ #else
92
+ void lock(){}
93
+ void unlock(){}
94
+ bool is_tty() const { return false; }
95
+ #endif
96
+ void prepare_screen()
97
+ {
98
+ if (is_tty() && use_ansi_codes) {
99
+ printf("\n\n\n");
100
+ }
101
+ }
102
+
103
+ void prepare_timings()
104
+ {
105
+ if (hg == NULL) {
106
+ hg = new Histogram();
107
+ hg->installStandalone(stdout);
108
+ }
109
+ }
110
+
111
+ private:
112
+ void update_display()
113
+ {
114
+ time_t now = time(NULL);
115
+ time_t duration = now - last_update;
116
+
117
+ if (!duration) {
118
+ return;
119
+ }
120
+
121
+ last_update = now;
122
+
123
+ const char *prefix = use_ansi_codes ? "\x1B[K" : "";
124
+ const char *final_suffix;
125
+
126
+ // Only use "ticker" style updates if we're a TTY and we have no
127
+ // following timings.
128
+ if (use_ansi_codes && is_tty() && hg == NULL) {
129
+ // Move up 3 cursors
130
+ printf("\x1B[2A");
131
+ prefix = "\x1B[K";
132
+ final_suffix = "\r";
133
+ } else {
134
+ // Determine the total number of time
135
+ unsigned total_duration = now - start_time;
136
+ printf("\n"); // Clear line..
137
+ printf("+%us\n", total_duration);
138
+ prefix = "";
139
+ final_suffix = "\n";
140
+ }
141
+
142
+ printf("%sQUERIES/SEC: %lu\n", prefix, n_queries / duration);
143
+ printf("%sROWS/SEC: %lu\n", prefix, n_rows / duration);
144
+ printf("%sERRORS: %lu%s", prefix, n_errors, final_suffix);
145
+
146
+ if (hg != NULL) {
147
+ hg->write();
148
+ }
149
+ fflush(stdout);
150
+
151
+ n_queries = 0;
152
+ n_rows = 0;
153
+ }
154
+
155
+ size_t n_rows;
156
+ size_t n_queries;
157
+ size_t n_errors;
158
+ time_t last_update;
159
+ time_t start_time;
160
+ cbc::Histogram *hg;
161
+ #ifndef _WIN32
162
+ pthread_mutex_t m_lock;
163
+ #endif
164
+ };
165
+
166
+ Metrics GlobalMetrics;
167
+
168
+ class Configuration
169
+ {
170
+ public:
171
+ Configuration() : o_file("queryfile"), o_threads("num-threads") {
172
+ o_file.mandatory(true);
173
+ o_file.description(
174
+ "Path to a file containing all the queries to execute. "
175
+ "Each line should contain the full query body");
176
+ o_file.abbrev('f');
177
+
178
+ o_threads.description("Number of threads to run");
179
+ o_threads.abbrev('t');
180
+ o_threads.setDefault(1);
181
+ }
182
+
183
+ void addToParser(Parser& parser)
184
+ {
185
+ parser.addOption(o_file);
186
+ parser.addOption(o_threads);
187
+ m_params.addToParser(parser);
188
+ }
189
+
190
+ void processOptions()
191
+ {
192
+ std::ifstream ifs(o_file.const_result().c_str());
193
+ if (!ifs.is_open()) {
194
+ int ec_save = errno;
195
+ string errstr(o_file.const_result());
196
+ errstr += ": ";
197
+ errstr += strerror(ec_save);
198
+ throw std::runtime_error(errstr);
199
+ }
200
+
201
+ string curline;
202
+ while (std::getline(ifs, curline).good() && !ifs.eof()) {
203
+ m_queries.push_back(curline);
204
+ }
205
+ if (m_params.useTimings()) {
206
+ GlobalMetrics.prepare_timings();
207
+ }
208
+ }
209
+
210
+ void set_cropts(lcb_create_st &opts) { m_params.fillCropts(opts); }
211
+ const vector<string>& queries() const { return m_queries; }
212
+ size_t nthreads() { return o_threads.result(); }
213
+
214
+ private:
215
+ vector<string> m_queries;
216
+ StringOption o_file;
217
+ UIntOption o_threads;
218
+ ConnParams m_params;
219
+ };
220
+
221
+ extern "C" { static void n1qlcb(lcb_t, int, const lcb_RESPN1QL *resp); }
222
+ extern "C" { static void* pthrfunc(void*); }
223
+
224
+ class ThreadContext;
225
+ struct QueryContext {
226
+ lcb_U64 begin;
227
+ bool received; // whether any row was received
228
+ ThreadContext *ctx; // Parent
229
+
230
+ QueryContext(ThreadContext *tctx)
231
+ : begin(lcb_nstime()), received(false), ctx(tctx) {}
232
+ };
233
+
234
+ class ThreadContext {
235
+ public:
236
+ void run()
237
+ {
238
+ while (!m_cancelled) {
239
+ vector<string>::const_iterator ii = m_queries.begin();
240
+ for (; ii != m_queries.end(); ++ii) {
241
+ run_one_query(*ii);
242
+ }
243
+ }
244
+ }
245
+
246
+ #ifndef _WIN32
247
+ void start()
248
+ {
249
+ assert(m_thr == NULL);
250
+ m_thr = new pthread_t;
251
+ int rc = pthread_create(m_thr, NULL, pthrfunc, this);
252
+ if (rc != 0) {
253
+ throw std::runtime_error(strerror(rc));
254
+ }
255
+ }
256
+
257
+ void join()
258
+ {
259
+ assert(m_thr != NULL);
260
+ void *arg = NULL;
261
+ pthread_join(*m_thr, &arg);
262
+ }
263
+
264
+ ~ThreadContext()
265
+ {
266
+ if (m_thr != NULL) {
267
+ join();
268
+ delete m_thr;
269
+ m_thr = NULL;
270
+ }
271
+ }
272
+ #else
273
+ void start() { run(); }
274
+ void join() {}
275
+ #endif
276
+
277
+ void handle_response(const lcb_RESPN1QL *resp, QueryContext *ctx)
278
+ {
279
+ if (!ctx->received) {
280
+ lcb_U64 duration = lcb_nstime() - ctx->begin;
281
+ m_metrics->lock();
282
+ m_metrics->update_timings(duration);
283
+ m_metrics->unlock();
284
+
285
+ ctx->received = true;
286
+ }
287
+
288
+ if (resp->rflags & LCB_RESP_F_FINAL) {
289
+ if (resp->rc != LCB_SUCCESS) {
290
+ log_error(resp->rc);
291
+ }
292
+ } else {
293
+ last_nrow++;
294
+ }
295
+ }
296
+
297
+ ThreadContext(lcb_t instance, const vector<string>& initial_queries)
298
+ : m_instance(instance), last_nerr(0), last_nrow(0),
299
+ m_metrics(&GlobalMetrics), m_cancelled(false), m_thr(NULL)
300
+ {
301
+ memset(&m_cmd, 0, sizeof m_cmd);
302
+ m_cmd.content_type = "application/json";
303
+ m_cmd.callback = n1qlcb;
304
+
305
+ // Shuffle the list
306
+ m_queries = initial_queries;
307
+ std::random_shuffle(m_queries.begin(), m_queries.end());
308
+ }
309
+
310
+ private:
311
+
312
+ void log_error(lcb_error_t)
313
+ {
314
+ m_metrics->lock();
315
+ m_metrics->update_error();
316
+ m_metrics->unlock();
317
+ }
318
+
319
+ void run_one_query(const string& txt)
320
+ {
321
+ // Reset counters
322
+ last_nrow = 0;
323
+ last_nerr = 0;
324
+
325
+ m_cmd.query = txt.c_str();
326
+ m_cmd.nquery = txt.size();
327
+
328
+ // Set up our context
329
+ QueryContext qctx(this);
330
+
331
+ lcb_error_t rc = lcb_n1ql_query(m_instance, &qctx, &m_cmd);
332
+ if (rc != LCB_SUCCESS) {
333
+ log_error(rc);
334
+ } else {
335
+ lcb_wait(m_instance);
336
+ m_metrics->lock();
337
+ m_metrics->update_row(last_nrow);
338
+ m_metrics->update_done(1);
339
+ m_metrics->unlock();
340
+ }
341
+ }
342
+
343
+ lcb_t m_instance;
344
+ vector<string> m_queries;
345
+ size_t last_nerr;
346
+ size_t last_nrow;
347
+ lcb_CMDN1QL m_cmd;
348
+ Metrics *m_metrics;
349
+ volatile bool m_cancelled;
350
+ #ifndef _WIN32
351
+ pthread_t *m_thr;
352
+ #else
353
+ void *m_thr;
354
+ #endif
355
+ };
356
+
357
+ static void n1qlcb(lcb_t, int, const lcb_RESPN1QL *resp)
358
+ {
359
+ QueryContext *qctx = reinterpret_cast<QueryContext*>(resp->cookie);
360
+ qctx->ctx->handle_response(resp, qctx);
361
+ }
362
+
363
+ static void* pthrfunc(void *arg)
364
+ {
365
+ reinterpret_cast<ThreadContext*>(arg)->run();
366
+ return NULL;
367
+ }
368
+
369
+ static bool
370
+ instance_has_n1ql(lcb_t instance) {
371
+ // Check that the instance supports N1QL
372
+ lcbvb_CONFIG *vbc;
373
+ do_or_die(lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_VBCONFIG, &vbc));
374
+
375
+ int sslmode = 0;
376
+ lcbvb_SVCMODE svcmode = LCBVB_SVCMODE_PLAIN;
377
+
378
+ do_or_die(lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_SSL_MODE, &sslmode));
379
+
380
+ if (sslmode & LCB_SSL_ENABLED) {
381
+ svcmode = LCBVB_SVCMODE_SSL;
382
+ }
383
+
384
+ int hix = lcbvb_get_randhost(vbc, LCBVB_SVCTYPE_N1QL, svcmode);
385
+ return hix > -1;
386
+ }
387
+
388
+ static void real_main(int argc, char **argv) {
389
+ Configuration config;
390
+ Parser parser;
391
+ config.addToParser(parser);
392
+ parser.parse(argc, argv);
393
+
394
+ vector<ThreadContext*> threads;
395
+ vector<lcb_t> instances;
396
+
397
+ lcb_create_st cropts = { 0 };
398
+ config.set_cropts(cropts);
399
+ config.processOptions();
400
+
401
+ for (size_t ii = 0; ii < config.nthreads(); ii++) {
402
+ lcb_t instance;
403
+ do_or_die(lcb_create(&instance, &cropts));
404
+ do_or_die(lcb_connect(instance));
405
+ lcb_wait(instance);
406
+ do_or_die(lcb_get_bootstrap_status(instance));
407
+
408
+ if (ii == 0 && !instance_has_n1ql(instance)) {
409
+ throw std::runtime_error("Cluster does not support N1QL!");
410
+ }
411
+
412
+ ThreadContext* cx = new ThreadContext(instance, config.queries());
413
+ threads.push_back(cx);
414
+ instances.push_back(instance);
415
+ }
416
+
417
+ GlobalMetrics.prepare_screen();
418
+
419
+ for (size_t ii = 0; ii < threads.size(); ++ii) {
420
+ threads[ii]->start();
421
+ }
422
+ for (size_t ii = 0; ii < threads.size(); ++ii) {
423
+ threads[ii]->join();
424
+ }
425
+ for (size_t ii = 0; ii < instances.size(); ++ii) {
426
+ lcb_destroy(instances[ii]);
427
+ }
428
+ }
429
+
430
+ int main(int argc, char **argv)
431
+ {
432
+ try {
433
+ real_main(argc, argv);
434
+ return 0;
435
+ } catch (std::exception& exc) {
436
+ cerr << exc.what() << endl;
437
+ exit(EXIT_FAILURE);
438
+ }
439
+ }
@@ -0,0 +1,822 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2011-2012 Couchbase, Inc.
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
+ #define NOMINMAX // Because MS' CRT headers #define min and max :(
18
+ #include "config.h"
19
+ #include <sys/types.h>
20
+ #include <libcouchbase/couchbase.h>
21
+ #include <errno.h>
22
+ #include <iostream>
23
+ #include <map>
24
+ #include <sstream>
25
+ #include <queue>
26
+ #include <list>
27
+ #include <cstring>
28
+ #include <cassert>
29
+ #include <cstdio>
30
+ #include <cstdlib>
31
+ #include <fstream>
32
+ #include <signal.h>
33
+ #ifndef WIN32
34
+ #include <pthread.h>
35
+ #else
36
+ #define usleep(n) Sleep(n/1000)
37
+ #endif
38
+ #include <cstdarg>
39
+ #include <exception>
40
+ #include <stdexcept>
41
+ #include "common/options.h"
42
+ #include "common/histogram.h"
43
+ #include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
44
+
45
+ #include "docgen/seqgen.h"
46
+ #include "docgen/docgen.h"
47
+
48
+ using namespace std;
49
+ using namespace cbc;
50
+ using namespace cliopts;
51
+ using namespace Pillowfight;
52
+ using std::vector;
53
+ using std::string;
54
+
55
+ // Deprecated options which still exist from previous versions.
56
+ struct DeprecatedOptions {
57
+ UIntOption iterations;
58
+ UIntOption instances;
59
+ BoolOption loop;
60
+
61
+ DeprecatedOptions() :
62
+ iterations("iterations"), instances("num-instances"), loop("loop")
63
+ {
64
+ iterations.abbrev('i').hide().setDefault(1000);
65
+ instances.abbrev('Q').hide().setDefault(1);
66
+ loop.abbrev('l').hide().setDefault(false);
67
+ }
68
+
69
+ void addOptions(Parser &p) {
70
+ p.addOption(instances);
71
+ p.addOption(loop);
72
+ p.addOption(iterations);
73
+ }
74
+ };
75
+
76
+ static TemplateSpec
77
+ parseTemplateSpec(const string& input)
78
+ {
79
+ TemplateSpec spec;
80
+ // Just need to find the path
81
+ size_t endpos = input.find(',');
82
+ if (endpos == string::npos) {
83
+ throw std::runtime_error("invalid template spec: need field,min,max");
84
+ }
85
+ spec.term = input.substr(0, endpos);
86
+ unsigned is_sequential = 0;
87
+ int rv = sscanf(input.c_str() + endpos + 1, "%u,%u,%u",
88
+ &spec.minval, &spec.maxval, &is_sequential);
89
+ if (rv < 2) {
90
+ throw std::runtime_error("invalid template spec: need field,min,max");
91
+ }
92
+ spec.sequential = is_sequential;
93
+ if (spec.minval > spec.maxval) {
94
+ throw std::runtime_error("min cannot be higher than max");
95
+ }
96
+ return spec;
97
+ }
98
+
99
+ class Configuration
100
+ {
101
+ public:
102
+ Configuration() :
103
+ o_multiSize("batch-size"),
104
+ o_numItems("num-items"),
105
+ o_keyPrefix("key-prefix"),
106
+ o_numThreads("num-threads"),
107
+ o_randSeed("random-seed"),
108
+ o_setPercent("set-pct"),
109
+ o_minSize("min-size"),
110
+ o_maxSize("max-size"),
111
+ o_noPopulate("no-population"),
112
+ o_pauseAtEnd("pause-at-end"),
113
+ o_numCycles("num-cycles"),
114
+ o_sequential("sequential"),
115
+ o_startAt("start-at"),
116
+ o_rateLimit("rate-limit"),
117
+ o_userdocs("docs"),
118
+ o_writeJson("json"),
119
+ o_templatePairs("template"),
120
+ o_subdoc("subdoc"),
121
+ o_sdPathCount("pathcount"),
122
+ o_populateOnly("populate-only"),
123
+ o_exptime("expiry")
124
+ {
125
+ o_multiSize.setDefault(100).abbrev('B').description("Number of operations to batch");
126
+ o_numItems.setDefault(1000).abbrev('I').description("Number of items to operate on");
127
+ o_keyPrefix.abbrev('p').description("key prefix to use");
128
+ o_numThreads.setDefault(1).abbrev('t').description("The number of threads to use");
129
+ o_randSeed.setDefault(0).abbrev('s').description("Specify random seed").hide();
130
+ o_setPercent.setDefault(33).abbrev('r').description("The percentage of operations which should be mutations");
131
+ o_minSize.setDefault(50).abbrev('m').description("Set minimum payload size");
132
+ o_maxSize.setDefault(5120).abbrev('M').description("Set maximum payload size");
133
+ o_noPopulate.setDefault(false).abbrev('n').description("Skip population");
134
+ o_pauseAtEnd.setDefault(false).abbrev('E').description("Pause at end of run (holding connections open) until user input");
135
+ o_numCycles.setDefault(-1).abbrev('c').description("Number of cycles to be run until exiting. Set to -1 to loop infinitely");
136
+ o_sequential.setDefault(false).description("Use sequential access (instead of random)");
137
+ o_startAt.setDefault(0).description("For sequential access, set the first item");
138
+ o_rateLimit.setDefault(0).description("Set operations per second limit (per thread)");
139
+ o_userdocs.description("User documents to load (overrides --min-size and --max-size");
140
+ o_writeJson.description("Enable writing JSON values (rather than bytes)");
141
+ o_templatePairs.description("Values for templates to be inserted into user documents");
142
+ o_templatePairs.argdesc("FIELD,MIN,MAX[,SEQUENTIAL]").hide();
143
+ o_subdoc.description("Use subdoc instead of fulldoc operations");
144
+ o_sdPathCount.description("Number of subdoc paths per command").setDefault(1);
145
+ o_populateOnly.description("Exit after documents have been populated");
146
+ o_exptime.description("Set TTL for items").abbrev('e');
147
+ }
148
+
149
+ void processOptions() {
150
+ opsPerCycle = o_multiSize.result();
151
+ prefix = o_keyPrefix.result();
152
+ setprc = o_setPercent.result();
153
+ shouldPopulate = !o_noPopulate.result();
154
+
155
+ if (depr.loop.passed()) {
156
+ fprintf(stderr, "The --loop/-l option is deprecated. Use --num-cycles\n");
157
+ maxCycles = -1;
158
+ } else {
159
+ maxCycles = o_numCycles.result();
160
+ }
161
+
162
+ if (o_populateOnly.passed()) {
163
+ // Determine how many iterations are required.
164
+ if (o_numCycles.passed()) {
165
+ throw std::runtime_error("--num-cycles incompatible with --populate-only");
166
+ }
167
+ size_t est = (o_numItems / o_numThreads) / o_multiSize;
168
+ while (est * o_numThreads * o_multiSize < o_numItems) {
169
+ est++;
170
+ }
171
+ maxCycles = est;
172
+ o_sequential.setDefault(true);
173
+ fprintf(stderr, "Populating using %lu cycles\n", maxCycles);
174
+ }
175
+
176
+ if (depr.iterations.passed()) {
177
+ fprintf(stderr, "The --num-iterations/-I option is deprecated. Use --batch-size\n");
178
+ opsPerCycle = depr.iterations.result();
179
+ }
180
+
181
+ vector<TemplateSpec> specs;
182
+ vector<string> userdocs;
183
+
184
+ if (o_templatePairs.passed()) {
185
+ vector<string> specs_str = o_templatePairs.result();
186
+ for (size_t ii = 0; ii < specs_str.size(); ii++) {
187
+ specs.push_back(parseTemplateSpec(specs_str[ii]));
188
+ }
189
+ }
190
+
191
+ // Set the document sizes..
192
+ if (o_userdocs.passed()) {
193
+ if (o_minSize.passed() || o_maxSize.passed()) {
194
+ fprintf(stderr, "--min-size/--max-size invalid with userdocs\n");
195
+ }
196
+
197
+ vector<string> filenames = o_userdocs.result();
198
+ for (size_t ii = 0; ii < filenames.size(); ii++) {
199
+ std::stringstream ss;
200
+ std::ifstream ifs(filenames[ii].c_str());
201
+ if (!ifs.is_open()) {
202
+ perror(filenames[ii].c_str());
203
+ exit(EXIT_FAILURE);
204
+ }
205
+ ss << ifs.rdbuf();
206
+ userdocs.push_back(ss.str());
207
+ }
208
+ }
209
+
210
+ if (specs.empty()) {
211
+ if (o_writeJson.result()) {
212
+ docgen = new JsonDocGenerator(o_minSize.result(), o_maxSize.result());
213
+ } else if (!userdocs.empty()) {
214
+ docgen = new PresetDocGenerator(userdocs);
215
+ } else {
216
+ docgen = new RawDocGenerator(o_minSize.result(), o_maxSize.result());
217
+ }
218
+ } else {
219
+ if (o_writeJson.result()) {
220
+ if (userdocs.empty()) {
221
+ docgen = new PlaceholderJsonGenerator(
222
+ o_minSize.result(), o_maxSize.result(), specs);
223
+ } else {
224
+ docgen = new PlaceholderJsonGenerator(userdocs, specs);
225
+ }
226
+ } else {
227
+ if (userdocs.empty()) {
228
+ throw std::runtime_error("Must provide documents with placeholders!");
229
+ }
230
+ docgen = new PlaceholderDocGenerator(userdocs, specs);
231
+ }
232
+ }
233
+
234
+ sdOpsPerCmd = o_sdPathCount.result();
235
+ if (o_sdPathCount.passed()) {
236
+ o_subdoc.setDefault(true);
237
+ }
238
+ }
239
+
240
+ void addOptions(Parser& parser) {
241
+ parser.addOption(o_multiSize);
242
+ parser.addOption(o_numItems);
243
+ parser.addOption(o_keyPrefix);
244
+ parser.addOption(o_numThreads);
245
+ parser.addOption(o_randSeed);
246
+ parser.addOption(o_setPercent);
247
+ parser.addOption(o_noPopulate);
248
+ parser.addOption(o_minSize);
249
+ parser.addOption(o_maxSize);
250
+ parser.addOption(o_pauseAtEnd);
251
+ parser.addOption(o_numCycles);
252
+ parser.addOption(o_sequential);
253
+ parser.addOption(o_startAt);
254
+ parser.addOption(o_rateLimit);
255
+ parser.addOption(o_userdocs);
256
+ parser.addOption(o_writeJson);
257
+ parser.addOption(o_templatePairs);
258
+ parser.addOption(o_subdoc);
259
+ parser.addOption(o_sdPathCount);
260
+ parser.addOption(o_populateOnly);
261
+ parser.addOption(o_exptime);
262
+ params.addToParser(parser);
263
+ depr.addOptions(parser);
264
+ }
265
+
266
+ bool isTimings(void) { return params.useTimings(); }
267
+
268
+ bool isLoopDone(size_t niter) {
269
+ if (maxCycles == -1) {
270
+ return false;
271
+ }
272
+ return niter >= (size_t)maxCycles;
273
+ }
274
+
275
+ uint32_t getRandomSeed() { return o_randSeed; }
276
+ uint32_t getNumThreads() { return o_numThreads; }
277
+ string& getKeyPrefix() { return prefix; }
278
+ bool shouldPauseAtEnd() { return o_pauseAtEnd; }
279
+ bool sequentialAccess() { return o_sequential; }
280
+ bool isSubdoc() { return o_subdoc; }
281
+ unsigned firstKeyOffset() { return o_startAt; }
282
+ uint32_t getNumItems() { return o_numItems; }
283
+ uint32_t getRateLimit() { return o_rateLimit; }
284
+ unsigned getExptime() { return o_exptime; }
285
+
286
+ uint32_t opsPerCycle;
287
+ uint32_t sdOpsPerCmd;
288
+ unsigned setprc;
289
+ string prefix;
290
+ volatile int maxCycles;
291
+ bool shouldPopulate;
292
+ bool hasTemplates;
293
+ ConnParams params;
294
+ const DocGeneratorBase *docgen;
295
+
296
+ private:
297
+ UIntOption o_multiSize;
298
+ UIntOption o_numItems;
299
+ StringOption o_keyPrefix;
300
+ UIntOption o_numThreads;
301
+ UIntOption o_randSeed;
302
+ UIntOption o_setPercent;
303
+ UIntOption o_minSize;
304
+ UIntOption o_maxSize;
305
+ BoolOption o_noPopulate;
306
+ BoolOption o_pauseAtEnd; // Should pillowfight pause execution (with
307
+ // connections open) before exiting?
308
+ IntOption o_numCycles;
309
+ BoolOption o_sequential;
310
+ UIntOption o_startAt;
311
+ UIntOption o_rateLimit;
312
+
313
+ // List of paths to user documents to load.. They should all be valid JSON
314
+ ListOption o_userdocs;
315
+
316
+ // Whether generated values should be JSON
317
+ BoolOption o_writeJson;
318
+
319
+ // List of template ranges for value generation
320
+ ListOption o_templatePairs;
321
+ BoolOption o_subdoc;
322
+ UIntOption o_sdPathCount;
323
+
324
+ // Compound option
325
+ BoolOption o_populateOnly;
326
+
327
+ UIntOption o_exptime;
328
+
329
+ DeprecatedOptions depr;
330
+ } config;
331
+
332
+ void log(const char *format, ...)
333
+ {
334
+ char buffer[512];
335
+ va_list args;
336
+
337
+ va_start(args, format);
338
+ vsprintf(buffer, format, args);
339
+ if (config.isTimings()) {
340
+ std::cerr << "[" << std::fixed << lcb_nstime() / 1000000000.0 << "] ";
341
+ }
342
+ std::cerr << buffer << std::endl;
343
+ va_end(args);
344
+ }
345
+
346
+
347
+
348
+ extern "C" {
349
+ static void operationCallback(lcb_t, int, const lcb_RESPBASE*);
350
+ }
351
+
352
+ class InstanceCookie {
353
+ public:
354
+ InstanceCookie(lcb_t instance) {
355
+ lcb_set_cookie(instance, this);
356
+ lastPrint = 0;
357
+ if (config.isTimings()) {
358
+ hg.install(instance, stdout);
359
+ }
360
+ }
361
+
362
+ static InstanceCookie* get(lcb_t instance) {
363
+ return (InstanceCookie *)lcb_get_cookie(instance);
364
+ }
365
+
366
+
367
+ static void dumpTimings(lcb_t instance, const char *header, bool force=false) {
368
+ time_t now = time(NULL);
369
+ InstanceCookie *ic = get(instance);
370
+
371
+ if (now - ic->lastPrint > 0) {
372
+ ic->lastPrint = now;
373
+ } else if (!force) {
374
+ return;
375
+ }
376
+
377
+ Histogram &h = ic->hg;
378
+ printf("[%f %s]\n", lcb_nstime() / 1000000000.0, header);
379
+ printf(" +---------+---------+---------+---------+\n");
380
+ h.write();
381
+ printf(" +----------------------------------------\n");
382
+ }
383
+
384
+ private:
385
+ time_t lastPrint;
386
+ Histogram hg;
387
+ };
388
+
389
+ struct NextOp {
390
+ NextOp() : m_seqno(0), m_mode(GET) {}
391
+
392
+ string m_key;
393
+ uint32_t m_seqno;
394
+ vector<lcb_IOV> m_valuefrags;
395
+ vector<lcb_SDSPEC> m_specs;
396
+ // The mode here is for future use with subdoc
397
+ enum Mode { STORE, GET, SDSTORE, SDGET };
398
+ Mode m_mode;
399
+ };
400
+
401
+ /** Stateful, per-thread generator */
402
+ class KeyGenerator {
403
+ public:
404
+ KeyGenerator(int ix)
405
+ : m_gencount(0), m_force_sequential(false),
406
+ m_in_population(config.shouldPopulate)
407
+ {
408
+ srand(config.getRandomSeed());
409
+
410
+ m_genrandom = new SeqGenerator(
411
+ config.firstKeyOffset(),
412
+ config.getNumItems() + config.firstKeyOffset());
413
+
414
+ m_gensequence = new SeqGenerator(
415
+ config.firstKeyOffset(),
416
+ config.getNumItems() + config.firstKeyOffset(),
417
+ config.getNumThreads(),
418
+ ix);
419
+
420
+ if (m_in_population) {
421
+ m_force_sequential = true;
422
+ } else {
423
+ m_force_sequential = config.sequentialAccess();
424
+ }
425
+
426
+ m_id = ix;
427
+ m_local_genstate = config.docgen->createState(config.getNumThreads(), ix);
428
+ if (config.isSubdoc()) {
429
+ m_mode_read = NextOp::SDGET;
430
+ m_mode_write = NextOp::SDSTORE;
431
+ m_sdgenstate = config.docgen->createSubdocState(config.getNumThreads(), ix);
432
+ if (!m_sdgenstate) {
433
+ std::cerr << "Current generator does not support subdoc. Did you try --json?" << std::endl;
434
+ exit(EXIT_FAILURE);
435
+ }
436
+ } else {
437
+ m_mode_read = NextOp::GET;
438
+ m_mode_write = NextOp::STORE;
439
+ }
440
+ }
441
+
442
+ void setNextOp(NextOp& op) {
443
+ bool store_override = false;
444
+
445
+ if (m_in_population) {
446
+ if (m_gencount++ < m_gensequence->maxItems()) {
447
+ store_override = true;
448
+ } else {
449
+ printf("Thread %d has finished populating.\n", m_id);
450
+ m_in_population = false;
451
+ m_force_sequential = config.sequentialAccess();
452
+ }
453
+ }
454
+
455
+ if (m_force_sequential) {
456
+ op.m_seqno = m_gensequence->next();
457
+ } else {
458
+ op.m_seqno = m_genrandom->next();
459
+ }
460
+
461
+ if (store_override) {
462
+ // Populate
463
+ op.m_mode = NextOp::STORE;
464
+ m_local_genstate->populateIov(op.m_seqno, op.m_valuefrags);
465
+
466
+ } else if (shouldStore(op.m_seqno)) {
467
+ op.m_mode = m_mode_write;
468
+ if (op.m_mode == NextOp::STORE) {
469
+ m_local_genstate->populateIov(op.m_seqno, op.m_valuefrags);
470
+ } else if (op.m_mode == NextOp::SDSTORE) {
471
+ op.m_specs.resize(config.sdOpsPerCmd);
472
+ m_sdgenstate->populateMutate(op.m_seqno, op.m_specs);
473
+ } else {
474
+ fprintf(stderr, "Invalid mode for op: %d\n", op.m_mode);
475
+ abort();
476
+ }
477
+ } else {
478
+ op.m_mode = m_mode_read;
479
+ if (op.m_mode == NextOp::SDGET) {
480
+ op.m_specs.resize(config.sdOpsPerCmd);
481
+ m_sdgenstate->populateLookup(op.m_seqno, op.m_specs);
482
+ }
483
+ }
484
+
485
+ generateKey(op);
486
+ }
487
+
488
+ bool shouldStore(uint32_t seqno) {
489
+ if (config.setprc == 0) {
490
+ return false;
491
+ }
492
+
493
+ float seqno_f = seqno % 100;
494
+ float pct_f = seqno_f / config.setprc;
495
+ return pct_f < 1;
496
+ }
497
+
498
+ void generateKey(NextOp& op) {
499
+ uint32_t seqno = op.m_seqno;
500
+ char buffer[21];
501
+ snprintf(buffer, sizeof(buffer), "%020d", seqno);
502
+ op.m_key.assign(config.getKeyPrefix() + buffer);
503
+ }
504
+
505
+ const char *getStageString() const {
506
+ if (m_in_population) {
507
+ return "Populate";
508
+ } else {
509
+ return "Run";
510
+ }
511
+ }
512
+
513
+ private:
514
+ SeqGenerator *m_genrandom;
515
+ SeqGenerator *m_gensequence;
516
+ size_t m_gencount;
517
+ int m_id;
518
+
519
+ bool m_force_sequential;
520
+ bool m_in_population;
521
+ NextOp::Mode m_mode_read;
522
+ NextOp::Mode m_mode_write;
523
+ GeneratorState *m_local_genstate;
524
+ SubdocGeneratorState *m_sdgenstate;
525
+ };
526
+
527
+ class ThreadContext
528
+ {
529
+ public:
530
+ ThreadContext(lcb_t handle, int ix) : kgen(ix), niter(0), instance(handle) {
531
+
532
+ }
533
+
534
+ void singleLoop() {
535
+ bool hasItems = false;
536
+ lcb_sched_enter(instance);
537
+ NextOp opinfo;
538
+ unsigned exptime = config.getExptime();
539
+
540
+ for (size_t ii = 0; ii < config.opsPerCycle; ++ii) {
541
+ kgen.setNextOp(opinfo);
542
+
543
+ switch (opinfo.m_mode) {
544
+ case NextOp::STORE: {
545
+ lcb_CMDSTORE scmd = { 0 };
546
+ scmd.operation = LCB_SET;
547
+ scmd.exptime = exptime;
548
+ LCB_CMD_SET_KEY(&scmd, opinfo.m_key.c_str(), opinfo.m_key.size());
549
+ LCB_CMD_SET_VALUEIOV(&scmd, &opinfo.m_valuefrags[0], opinfo.m_valuefrags.size());
550
+ error = lcb_store3(instance, this, &scmd);
551
+ break;
552
+ }
553
+ case NextOp::GET: {
554
+ lcb_CMDGET gcmd = { 0 };
555
+ LCB_CMD_SET_KEY(&gcmd, opinfo.m_key.c_str(), opinfo.m_key.size());
556
+ gcmd.exptime = exptime;
557
+ error = lcb_get3(instance, this, &gcmd);
558
+ break;
559
+ }
560
+ case NextOp::SDSTORE:
561
+ case NextOp::SDGET: {
562
+ lcb_CMDSUBDOC sdcmd = { 0 };
563
+ if (opinfo.m_mode == NextOp::SDSTORE) {
564
+ sdcmd.exptime = exptime;
565
+ }
566
+ LCB_CMD_SET_KEY(&sdcmd, opinfo.m_key.c_str(), opinfo.m_key.size());
567
+ sdcmd.specs = &opinfo.m_specs[0];
568
+ sdcmd.nspecs = opinfo.m_specs.size();
569
+ error = lcb_subdoc3(instance, this, &sdcmd);
570
+ break;
571
+ }
572
+ }
573
+
574
+ if (error != LCB_SUCCESS) {
575
+ hasItems = false;
576
+ log("Failed to schedule operation: [0x%x] %s", error, lcb_strerror(instance, error));
577
+ } else {
578
+ hasItems = true;
579
+ }
580
+ }
581
+ if (hasItems) {
582
+ lcb_sched_leave(instance);
583
+ lcb_wait(instance);
584
+ if (error != LCB_SUCCESS) {
585
+ log("Operation(s) failed: [0x%x] %s", error, lcb_strerror(instance, error));
586
+ }
587
+ } else {
588
+ lcb_sched_fail(instance);
589
+ }
590
+ }
591
+
592
+ bool run() {
593
+ do {
594
+ singleLoop();
595
+
596
+ if (config.isTimings()) {
597
+ InstanceCookie::dumpTimings(instance, kgen.getStageString());
598
+ }
599
+ if (config.params.shouldDump()) {
600
+ lcb_dump(instance, stderr, LCB_DUMP_ALL);
601
+ }
602
+ if (config.getRateLimit() > 0) {
603
+ rateLimitThrottle();
604
+ }
605
+
606
+ } while (!config.isLoopDone(++niter));
607
+
608
+ if (config.isTimings()) {
609
+ InstanceCookie::dumpTimings(instance, kgen.getStageString(), true);
610
+ }
611
+ return true;
612
+ }
613
+
614
+ #ifndef WIN32
615
+ pthread_t thr;
616
+ #endif
617
+
618
+ protected:
619
+ // the callback methods needs to be able to set the error handler..
620
+ friend void operationCallback(lcb_t, int, const lcb_RESPBASE*);
621
+ Histogram histogram;
622
+
623
+ void setError(lcb_error_t e) { error = e; }
624
+
625
+ private:
626
+
627
+ void rateLimitThrottle() {
628
+ lcb_U64 now = lcb_nstime();
629
+ static lcb_U64 previous_time = now;
630
+
631
+ const lcb_U64 elapsed_ns = now - previous_time;
632
+ const lcb_U64 wanted_duration_ns =
633
+ config.opsPerCycle * 1e9 / config.getRateLimit();
634
+ // On first invocation no previous_time, so skip attempting to sleep.
635
+ if (elapsed_ns > 0 && elapsed_ns < wanted_duration_ns) {
636
+ // Dampen the sleep time by averaging with the previous
637
+ // sleep time.
638
+ static lcb_U64 last_sleep_ns = 0;
639
+ const lcb_U64 sleep_ns =
640
+ (last_sleep_ns + wanted_duration_ns - elapsed_ns) / 2;
641
+ usleep(sleep_ns / 1000);
642
+ now += sleep_ns;
643
+ last_sleep_ns = sleep_ns;
644
+ }
645
+ previous_time = now;
646
+ }
647
+
648
+ KeyGenerator kgen;
649
+ size_t niter;
650
+ lcb_error_t error;
651
+ lcb_t instance;
652
+ };
653
+
654
+ static void operationCallback(lcb_t, int, const lcb_RESPBASE *resp)
655
+ {
656
+ ThreadContext *tc;
657
+
658
+ tc = const_cast<ThreadContext *>(reinterpret_cast<const ThreadContext *>(resp->cookie));
659
+ tc->setError(resp->rc);
660
+
661
+ #ifndef WIN32
662
+ static volatile unsigned long nops = 1;
663
+ static time_t start_time = time(NULL);
664
+ static int is_tty = isatty(STDOUT_FILENO);
665
+ if (is_tty) {
666
+ if (++nops % 1000 == 0) {
667
+ time_t now = time(NULL);
668
+ time_t nsecs = now - start_time;
669
+ if (!nsecs) { nsecs = 1; }
670
+ unsigned long ops_sec = nops / nsecs;
671
+ printf("OPS/SEC: %10lu\r", ops_sec);
672
+ fflush(stdout);
673
+ }
674
+ }
675
+ #endif
676
+ }
677
+
678
+
679
+ std::list<ThreadContext *> contexts;
680
+
681
+ extern "C" {
682
+ typedef void (*handler_t)(int);
683
+ }
684
+
685
+ #ifndef WIN32
686
+ static void sigint_handler(int)
687
+ {
688
+ static int ncalled = 0;
689
+ ncalled++;
690
+
691
+ if (ncalled < 2) {
692
+ log("Termination requested. Waiting threads to finish. Ctrl-C to force termination.");
693
+ signal(SIGINT, sigint_handler); // Reinstall
694
+ config.maxCycles = 0;
695
+ return;
696
+ }
697
+
698
+ std::list<ThreadContext *>::iterator it;
699
+ for (it = contexts.begin(); it != contexts.end(); ++it) {
700
+ delete *it;
701
+ }
702
+ contexts.clear();
703
+ exit(EXIT_FAILURE);
704
+ }
705
+
706
+ static void setup_sigint_handler()
707
+ {
708
+ struct sigaction action;
709
+ sigemptyset(&action.sa_mask);
710
+ action.sa_handler = sigint_handler;
711
+ action.sa_flags = 0;
712
+ sigaction(SIGINT, &action, NULL);
713
+ }
714
+
715
+ extern "C" {
716
+ static void* thread_worker(void*);
717
+ }
718
+
719
+ static void start_worker(ThreadContext *ctx)
720
+ {
721
+ pthread_attr_t attr;
722
+ pthread_attr_init(&attr);
723
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
724
+ int rc = pthread_create(&ctx->thr, &attr, thread_worker, ctx);
725
+ if (rc != 0) {
726
+ log("Couldn't create thread: (%d)", errno);
727
+ exit(EXIT_FAILURE);
728
+ }
729
+ }
730
+ static void join_worker(ThreadContext *ctx)
731
+ {
732
+ void *arg = NULL;
733
+ int rc = pthread_join(ctx->thr, &arg);
734
+ if (rc != 0) {
735
+ log("Couldn't join thread (%d)", errno);
736
+ exit(EXIT_FAILURE);
737
+ }
738
+ }
739
+
740
+ #else
741
+ static void setup_sigint_handler() {}
742
+ static void start_worker(ThreadContext *ctx) { ctx->run(); }
743
+ static void join_worker(ThreadContext *ctx) { (void)ctx; }
744
+ #endif
745
+
746
+ extern "C" {
747
+ static void *thread_worker(void *arg)
748
+ {
749
+ ThreadContext *ctx = static_cast<ThreadContext *>(arg);
750
+ ctx->run();
751
+ return NULL;
752
+ }
753
+ }
754
+
755
+ int main(int argc, char **argv)
756
+ {
757
+ int exit_code = EXIT_SUCCESS;
758
+ setup_sigint_handler();
759
+
760
+ Parser parser("cbc-pillowfight");
761
+ config.addOptions(parser);
762
+ try {
763
+ parser.parse(argc, argv, false);
764
+ config.processOptions();
765
+ } catch (std::string& e) {
766
+ std::cerr << e << std::endl;
767
+ exit(EXIT_FAILURE);
768
+ } catch (std::exception& e) {
769
+ std::cerr << e.what() << std::endl;
770
+ exit(EXIT_FAILURE);
771
+ }
772
+ size_t nthreads = config.getNumThreads();
773
+ log("Running. Press Ctrl-C to terminate...");
774
+
775
+ #ifdef WIN32
776
+ if (nthreads > 1) {
777
+ log("WARNING: More than a single thread on Windows not supported. Forcing 1");
778
+ nthreads = 1;
779
+ }
780
+ #endif
781
+
782
+ struct lcb_create_st options;
783
+ ConnParams& cp = config.params;
784
+ lcb_error_t error;
785
+
786
+ for (uint32_t ii = 0; ii < nthreads; ++ii) {
787
+ cp.fillCropts(options);
788
+ lcb_t instance = NULL;
789
+ error = lcb_create(&instance, &options);
790
+ if (error != LCB_SUCCESS) {
791
+ log("Failed to create instance: %s", lcb_strerror(NULL, error));
792
+ exit(EXIT_FAILURE);
793
+ }
794
+ lcb_install_callback3(instance, LCB_CALLBACK_STORE, operationCallback);
795
+ lcb_install_callback3(instance, LCB_CALLBACK_GET, operationCallback);
796
+ lcb_install_callback3(instance, LCB_CALLBACK_SDMUTATE, operationCallback);
797
+ lcb_install_callback3(instance, LCB_CALLBACK_SDLOOKUP, operationCallback);
798
+ cp.doCtls(instance);
799
+
800
+ new InstanceCookie(instance);
801
+
802
+ lcb_connect(instance);
803
+ lcb_wait(instance);
804
+ error = lcb_get_bootstrap_status(instance);
805
+
806
+ if (error != LCB_SUCCESS) {
807
+ std::cout << std::endl;
808
+ log("Failed to connect: %s", lcb_strerror(instance, error));
809
+ exit(EXIT_FAILURE);
810
+ }
811
+
812
+ ThreadContext *ctx = new ThreadContext(instance, ii);
813
+ contexts.push_back(ctx);
814
+ start_worker(ctx);
815
+ }
816
+
817
+ for (std::list<ThreadContext *>::iterator it = contexts.begin();
818
+ it != contexts.end(); ++it) {
819
+ join_worker(*it);
820
+ }
821
+ return exit_code;
822
+ }