mt-libcouchbase 1.4.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 (707) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +38 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +24 -0
  8. data/README.md +445 -0
  9. data/Rakefile +76 -0
  10. data/ext/README.md +6 -0
  11. data/ext/Rakefile +19 -0
  12. data/ext/libcouchbase/.gitignore +132 -0
  13. data/ext/libcouchbase/CMakeLists.txt +455 -0
  14. data/ext/libcouchbase/CONTRIBUTING.md +105 -0
  15. data/ext/libcouchbase/LICENSE +202 -0
  16. data/ext/libcouchbase/README.markdown +195 -0
  17. data/ext/libcouchbase/RELEASE_NOTES.markdown +3523 -0
  18. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +52 -0
  19. data/ext/libcouchbase/cmake/Modules/CopyPDB.cmake +42 -0
  20. data/ext/libcouchbase/cmake/Modules/DistScript.cmake +17 -0
  21. data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +18 -0
  22. data/ext/libcouchbase/cmake/Modules/FindCouchbaseHdrHistogram.cmake +15 -0
  23. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibev.cmake +73 -0
  24. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +54 -0
  25. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +57 -0
  26. data/ext/libcouchbase/cmake/Modules/FindProfiler.cmake +16 -0
  27. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +49 -0
  28. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +142 -0
  29. data/ext/libcouchbase/cmake/Modules/GetPlatformCCInfo.cmake +45 -0
  30. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +70 -0
  31. data/ext/libcouchbase/cmake/config-cmake.h.in +80 -0
  32. data/ext/libcouchbase/cmake/configure +355 -0
  33. data/ext/libcouchbase/cmake/defs.mk.in +6 -0
  34. data/ext/libcouchbase/cmake/dtrace-instr-link.pl +51 -0
  35. data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
  36. data/ext/libcouchbase/cmake/source_files.cmake +104 -0
  37. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1022 -0
  38. data/ext/libcouchbase/contrib/cJSON/cJSON.h +158 -0
  39. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +25 -0
  40. data/ext/libcouchbase/contrib/cbsasl/COPYING +202 -0
  41. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +259 -0
  42. data/ext/libcouchbase/contrib/cbsasl/src/client.c +419 -0
  43. data/ext/libcouchbase/contrib/cbsasl/src/common.c +50 -0
  44. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.c +67 -0
  45. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.h +33 -0
  46. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.c +296 -0
  47. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.h +45 -0
  48. data/ext/libcouchbase/contrib/cbsasl/src/hash.c +573 -0
  49. data/ext/libcouchbase/contrib/cbsasl/src/hash.h +15 -0
  50. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
  51. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
  52. data/ext/libcouchbase/contrib/cbsasl/src/util.h +31 -0
  53. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +2 -0
  54. data/ext/libcouchbase/contrib/cliopts/cliopts.c +938 -0
  55. data/ext/libcouchbase/contrib/cliopts/cliopts.h +610 -0
  56. data/ext/libcouchbase/contrib/genhash/genhash.c +371 -0
  57. data/ext/libcouchbase/contrib/genhash/genhash.h +241 -0
  58. data/ext/libcouchbase/contrib/gtest-1.7.0/CHANGES +157 -0
  59. data/ext/libcouchbase/contrib/gtest-1.7.0/CMakeLists.txt +252 -0
  60. data/ext/libcouchbase/contrib/gtest-1.7.0/CONTRIBUTORS +37 -0
  61. data/ext/libcouchbase/contrib/gtest-1.7.0/LICENSE +28 -0
  62. data/ext/libcouchbase/contrib/gtest-1.7.0/MINIFY.sh +15 -0
  63. data/ext/libcouchbase/contrib/gtest-1.7.0/README +435 -0
  64. data/ext/libcouchbase/contrib/gtest-1.7.0/cmake/internal_utils.cmake +227 -0
  65. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-death-test.h +294 -0
  66. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-message.h +250 -0
  67. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h +1421 -0
  68. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h.pump +487 -0
  69. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-printers.h +855 -0
  70. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-spi.h +232 -0
  71. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-test-part.h +179 -0
  72. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-typed-test.h +259 -0
  73. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest.h +2291 -0
  74. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_pred_impl.h +358 -0
  75. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_prod.h +58 -0
  76. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h +319 -0
  77. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h +206 -0
  78. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-internal.h +1158 -0
  79. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h +233 -0
  80. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h +5143 -0
  81. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
  82. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h +619 -0
  83. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-port.h +1947 -0
  84. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-string.h +167 -0
  85. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h +1012 -0
  86. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump +339 -0
  87. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h +3331 -0
  88. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump +297 -0
  89. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-all.cc +48 -0
  90. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-death-test.cc +1344 -0
  91. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-filepath.cc +382 -0
  92. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-internal-inl.h +1218 -0
  93. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-port.cc +805 -0
  94. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-printers.cc +363 -0
  95. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-test-part.cc +110 -0
  96. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-typed-test.cc +110 -0
  97. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest.cc +5015 -0
  98. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest_main.cc +38 -0
  99. data/ext/libcouchbase/contrib/http_parser/LICENSE-MIT +23 -0
  100. data/ext/libcouchbase/contrib/http_parser/README.md +178 -0
  101. data/ext/libcouchbase/contrib/http_parser/http_parser.c +2060 -0
  102. data/ext/libcouchbase/contrib/http_parser/http_parser.h +321 -0
  103. data/ext/libcouchbase/contrib/jsonsl/LICENSE +20 -0
  104. data/ext/libcouchbase/contrib/jsonsl/jsonsl.c +1452 -0
  105. data/ext/libcouchbase/contrib/jsonsl/jsonsl.h +971 -0
  106. data/ext/libcouchbase/contrib/lcb-jsoncpp/CMakeLists.txt +6 -0
  107. data/ext/libcouchbase/contrib/lcb-jsoncpp/LICENSE +55 -0
  108. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp-forwards.h +255 -0
  109. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4893 -0
  110. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.h +1961 -0
  111. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +7 -0
  112. data/ext/libcouchbase/contrib/snappy/COPYING +28 -0
  113. data/ext/libcouchbase/contrib/snappy/snappy-c.cc +90 -0
  114. data/ext/libcouchbase/contrib/snappy/snappy-c.h +138 -0
  115. data/ext/libcouchbase/contrib/snappy/snappy-internal.h +150 -0
  116. data/ext/libcouchbase/contrib/snappy/snappy-lcb-msvc.h +5 -0
  117. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +75 -0
  118. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.h +137 -0
  119. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.cc +42 -0
  120. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.h +491 -0
  121. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +100 -0
  122. data/ext/libcouchbase/contrib/snappy/snappy.cc +1312 -0
  123. data/ext/libcouchbase/contrib/snappy/snappy.h +184 -0
  124. data/ext/libcouchbase/contrib/win32-defs/iocpdefs.h +133 -0
  125. data/ext/libcouchbase/contrib/win32-defs/mingwdefs.h +4396 -0
  126. data/ext/libcouchbase/contrib/win32-defs/win_stdint.h +258 -0
  127. data/ext/libcouchbase/doc/Doxyfile +2495 -0
  128. data/ext/libcouchbase/doc/DoxygenLayout.xml +109 -0
  129. data/ext/libcouchbase/doc/Makefile +44 -0
  130. data/ext/libcouchbase/doc/apiattr.h +117 -0
  131. data/ext/libcouchbase/doc/cbc-n1qlback.markdown +88 -0
  132. data/ext/libcouchbase/doc/cbc-pillowfight.markdown +296 -0
  133. data/ext/libcouchbase/doc/cbc-subdoc.markdown +299 -0
  134. data/ext/libcouchbase/doc/cbc.markdown +763 -0
  135. data/ext/libcouchbase/doc/cbcrc.markdown +52 -0
  136. data/ext/libcouchbase/doc/common-additional-options.markdown +82 -0
  137. data/ext/libcouchbase/doc/common-options.markdown +71 -0
  138. data/ext/libcouchbase/doc/environment.h +93 -0
  139. data/ext/libcouchbase/doc/example/threads.c +77 -0
  140. data/ext/libcouchbase/doc/footer.html +22 -0
  141. data/ext/libcouchbase/doc/genman.sh +25 -0
  142. data/ext/libcouchbase/doc/header.html +52 -0
  143. data/ext/libcouchbase/doc/intro.h +130 -0
  144. data/ext/libcouchbase/doc/mainpage.h +136 -0
  145. data/ext/libcouchbase/doc/man/cbc-admin.1 +1 -0
  146. data/ext/libcouchbase/doc/man/cbc-bucket-create.1 +1 -0
  147. data/ext/libcouchbase/doc/man/cbc-bucket-delete.1 +1 -0
  148. data/ext/libcouchbase/doc/man/cbc-cat.1 +1 -0
  149. data/ext/libcouchbase/doc/man/cbc-connstr.1 +1 -0
  150. data/ext/libcouchbase/doc/man/cbc-cp.1 +1 -0
  151. data/ext/libcouchbase/doc/man/cbc-create.1 +1 -0
  152. data/ext/libcouchbase/doc/man/cbc-decr.1 +1 -0
  153. data/ext/libcouchbase/doc/man/cbc-flush.1 +1 -0
  154. data/ext/libcouchbase/doc/man/cbc-hash.1 +1 -0
  155. data/ext/libcouchbase/doc/man/cbc-incr.1 +1 -0
  156. data/ext/libcouchbase/doc/man/cbc-lock.1 +1 -0
  157. data/ext/libcouchbase/doc/man/cbc-mcflush.1 +1 -0
  158. data/ext/libcouchbase/doc/man/cbc-mcversion.1 +1 -0
  159. data/ext/libcouchbase/doc/man/cbc-n1ql.1 +1 -0
  160. data/ext/libcouchbase/doc/man/cbc-n1qlback.1 +198 -0
  161. data/ext/libcouchbase/doc/man/cbc-observe.1 +1 -0
  162. data/ext/libcouchbase/doc/man/cbc-pillowfight.1 +499 -0
  163. data/ext/libcouchbase/doc/man/cbc-ping.1 +1 -0
  164. data/ext/libcouchbase/doc/man/cbc-rm.1 +1 -0
  165. data/ext/libcouchbase/doc/man/cbc-role-list.1 +1 -0
  166. data/ext/libcouchbase/doc/man/cbc-stats.1 +1 -0
  167. data/ext/libcouchbase/doc/man/cbc-subdoc.1 +494 -0
  168. data/ext/libcouchbase/doc/man/cbc-unlock.1 +1 -0
  169. data/ext/libcouchbase/doc/man/cbc-user-delete.1 +1 -0
  170. data/ext/libcouchbase/doc/man/cbc-user-list.1 +1 -0
  171. data/ext/libcouchbase/doc/man/cbc-user-upsert.1 +1 -0
  172. data/ext/libcouchbase/doc/man/cbc-verbosity.1 +1 -0
  173. data/ext/libcouchbase/doc/man/cbc-version.1 +1 -0
  174. data/ext/libcouchbase/doc/man/cbc-view.1 +1 -0
  175. data/ext/libcouchbase/doc/man/cbc-watch.1 +1 -0
  176. data/ext/libcouchbase/doc/man/cbc.1 +1035 -0
  177. data/ext/libcouchbase/doc/man/cbcrc.4 +71 -0
  178. data/ext/libcouchbase/doc/style.css +1162 -0
  179. data/ext/libcouchbase/example/CMakeLists.txt +52 -0
  180. data/ext/libcouchbase/example/README.markdown +47 -0
  181. data/ext/libcouchbase/example/analytics/.gitignore +1 -0
  182. data/ext/libcouchbase/example/analytics/analytics.c +158 -0
  183. data/ext/libcouchbase/example/analytics/build-queries.rb +34 -0
  184. data/ext/libcouchbase/example/analytics/cJSON.c +1 -0
  185. data/ext/libcouchbase/example/analytics/cJSON.h +1 -0
  186. data/ext/libcouchbase/example/analytics/queries/00-show-dataverse.json +5 -0
  187. data/ext/libcouchbase/example/analytics/queries/01-setup-dataset-breweries.json +6 -0
  188. data/ext/libcouchbase/example/analytics/queries/02-setup-dataset-beers.json +6 -0
  189. data/ext/libcouchbase/example/analytics/queries/03-initiate-shadow.json +6 -0
  190. data/ext/libcouchbase/example/analytics/queries/04-list-datasets.json +7 -0
  191. data/ext/libcouchbase/example/analytics/queries/05-count-breweries.json +5 -0
  192. data/ext/libcouchbase/example/analytics/queries/06-first-brewery.json +6 -0
  193. data/ext/libcouchbase/example/analytics/queries/07-key-based-lookup.json +6 -0
  194. data/ext/libcouchbase/example/analytics/queries/08-exact-match-lookup.json +7 -0
  195. data/ext/libcouchbase/example/analytics/queries/09-exact-match-lookup-different-shape.json +6 -0
  196. data/ext/libcouchbase/example/analytics/queries/10-other-query-filters.json +6 -0
  197. data/ext/libcouchbase/example/analytics/queries/11-equijoin.json +9 -0
  198. data/ext/libcouchbase/example/analytics/queries/12-equijoin-select-star.json +10 -0
  199. data/ext/libcouchbase/example/analytics/queries/13-ansi-join.json +8 -0
  200. data/ext/libcouchbase/example/analytics/queries/14-join-select-values.json +8 -0
  201. data/ext/libcouchbase/example/analytics/queries/15-nested-outer-join.json +7 -0
  202. data/ext/libcouchbase/example/analytics/queries/16-theta-join.json +8 -0
  203. data/ext/libcouchbase/example/analytics/queries/17-existential-quantification.json +9 -0
  204. data/ext/libcouchbase/example/analytics/queries/18-universal-quantification.json +7 -0
  205. data/ext/libcouchbase/example/analytics/queries/19-simple-aggregation.json +6 -0
  206. data/ext/libcouchbase/example/analytics/queries/20-simple-aggregation-unwrapped-value.json +6 -0
  207. data/ext/libcouchbase/example/analytics/queries/21-simple-aggregation-explicit.json +6 -0
  208. data/ext/libcouchbase/example/analytics/queries/22-grouping-and-aggregation.json +6 -0
  209. data/ext/libcouchbase/example/analytics/queries/23-grouping-and-aggregation-with-hint.json +7 -0
  210. data/ext/libcouchbase/example/analytics/queries/24-grouping-and-limits.json +7 -0
  211. data/ext/libcouchbase/example/analytics/queries/25-named-parameters.json +7 -0
  212. data/ext/libcouchbase/example/analytics/queries/26-positional-parameters.json +7 -0
  213. data/ext/libcouchbase/example/analytics/queries.h +113 -0
  214. data/ext/libcouchbase/example/crypto/.gitignore +2 -0
  215. data/ext/libcouchbase/example/crypto/Makefile +13 -0
  216. data/ext/libcouchbase/example/crypto/common_provider.c +26 -0
  217. data/ext/libcouchbase/example/crypto/common_provider.h +33 -0
  218. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +144 -0
  219. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +146 -0
  220. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +271 -0
  221. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
  222. data/ext/libcouchbase/example/db/db.c +171 -0
  223. data/ext/libcouchbase/example/db/vb.c +227 -0
  224. data/ext/libcouchbase/example/fts/.gitignore +1 -0
  225. data/ext/libcouchbase/example/fts/build-queries.rb +33 -0
  226. data/ext/libcouchbase/example/fts/fts.c +142 -0
  227. data/ext/libcouchbase/example/fts/queries/00-simple-text-query.json +12 -0
  228. data/ext/libcouchbase/example/fts/queries/01-simple-text-query-on-non-default-index.json +9 -0
  229. data/ext/libcouchbase/example/fts/queries/02-simple-text-query-on-stored-field.json +13 -0
  230. data/ext/libcouchbase/example/fts/queries/03-match-query-with-facet.json +19 -0
  231. data/ext/libcouchbase/example/fts/queries/04-docid-query.json +11 -0
  232. data/ext/libcouchbase/example/fts/queries/05-unanalyzed-term-query-with-fuzziness-level-of-0.json +13 -0
  233. data/ext/libcouchbase/example/fts/queries/06-unanalyzed-term-query-with-fuzziness-level-of-2.json +14 -0
  234. data/ext/libcouchbase/example/fts/queries/07-match-phrase-query.json +13 -0
  235. data/ext/libcouchbase/example/fts/queries/08-phrase-query.json +16 -0
  236. data/ext/libcouchbase/example/fts/queries/09-query-string-query.json +9 -0
  237. data/ext/libcouchbase/example/fts/queries/10-conjunction-query.json +21 -0
  238. data/ext/libcouchbase/example/fts/queries/11-wild-card-query.json +13 -0
  239. data/ext/libcouchbase/example/fts/queries/12-numeric-range-query.json +11 -0
  240. data/ext/libcouchbase/example/fts/queries/13-regexp-query.json +13 -0
  241. data/ext/libcouchbase/example/fts/queries.h +61 -0
  242. data/ext/libcouchbase/example/instancepool/main.cc +112 -0
  243. data/ext/libcouchbase/example/instancepool/pool.cc +102 -0
  244. data/ext/libcouchbase/example/instancepool/pool.h +69 -0
  245. data/ext/libcouchbase/example/libeventdirect/main.c +222 -0
  246. data/ext/libcouchbase/example/mcc/mcc.cc +246 -0
  247. data/ext/libcouchbase/example/minimal/.gitignore +1 -0
  248. data/ext/libcouchbase/example/minimal/minimal.c +132 -0
  249. data/ext/libcouchbase/example/minimal/query.c +185 -0
  250. data/ext/libcouchbase/example/observe/durability.c +102 -0
  251. data/ext/libcouchbase/example/observe/observe.c +159 -0
  252. data/ext/libcouchbase/example/subdoc/subdoc-multi.cc +143 -0
  253. data/ext/libcouchbase/example/subdoc/subdoc-simple.cc +201 -0
  254. data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +286 -0
  255. data/ext/libcouchbase/example/tick/tick.c +119 -0
  256. data/ext/libcouchbase/example/tracing/.gitignore +2 -0
  257. data/ext/libcouchbase/example/tracing/Makefile +8 -0
  258. data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
  259. data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
  260. data/ext/libcouchbase/example/tracing/tracing.c +439 -0
  261. data/ext/libcouchbase/example/tracing/views.c +444 -0
  262. data/ext/libcouchbase/example/users/README +48 -0
  263. data/ext/libcouchbase/example/users/users.c +147 -0
  264. data/ext/libcouchbase/example/views/views-example.cc +83 -0
  265. data/ext/libcouchbase/include/libcouchbase/_cxxwrap.h +150 -0
  266. data/ext/libcouchbase/include/libcouchbase/api-legacy.h +1689 -0
  267. data/ext/libcouchbase/include/libcouchbase/api3.h +2 -0
  268. data/ext/libcouchbase/include/libcouchbase/assert.h +44 -0
  269. data/ext/libcouchbase/include/libcouchbase/auth.h +297 -0
  270. data/ext/libcouchbase/include/libcouchbase/cbft.h +151 -0
  271. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +319 -0
  272. data/ext/libcouchbase/include/libcouchbase/cntl.h +1418 -0
  273. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +29 -0
  274. data/ext/libcouchbase/include/libcouchbase/couchbase.h +4089 -0
  275. data/ext/libcouchbase/include/libcouchbase/crypto.h +306 -0
  276. data/ext/libcouchbase/include/libcouchbase/deprecated.h +312 -0
  277. data/ext/libcouchbase/include/libcouchbase/error.h +680 -0
  278. data/ext/libcouchbase/include/libcouchbase/http.h +1 -0
  279. data/ext/libcouchbase/include/libcouchbase/iops.h +1053 -0
  280. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +263 -0
  281. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +137 -0
  282. data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
  283. data/ext/libcouchbase/include/libcouchbase/n1ql.h +539 -0
  284. data/ext/libcouchbase/include/libcouchbase/pktfwd.h +270 -0
  285. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +370 -0
  286. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr-inl.c +76 -0
  287. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr.h +199 -0
  288. data/ext/libcouchbase/include/libcouchbase/subdoc.h +347 -0
  289. data/ext/libcouchbase/include/libcouchbase/sysdefs.h +98 -0
  290. data/ext/libcouchbase/include/libcouchbase/tracing.h +437 -0
  291. data/ext/libcouchbase/include/libcouchbase/vbucket.h +680 -0
  292. data/ext/libcouchbase/include/libcouchbase/views.h +357 -0
  293. data/ext/libcouchbase/include/libcouchbase/visibility.h +66 -0
  294. data/ext/libcouchbase/include/memcached/COPYING +30 -0
  295. data/ext/libcouchbase/include/memcached/README +10 -0
  296. data/ext/libcouchbase/include/memcached/protocol_binary.h +885 -0
  297. data/ext/libcouchbase/packaging/README +7 -0
  298. data/ext/libcouchbase/packaging/abicheck/.gitignore +4 -0
  299. data/ext/libcouchbase/packaging/abicheck/Makefile +17 -0
  300. data/ext/libcouchbase/packaging/abicheck/README.md +27 -0
  301. data/ext/libcouchbase/packaging/abicheck/template.xml +3 -0
  302. data/ext/libcouchbase/packaging/deb/compat +1 -0
  303. data/ext/libcouchbase/packaging/deb/control +72 -0
  304. data/ext/libcouchbase/packaging/deb/copyright +10 -0
  305. data/ext/libcouchbase/packaging/deb/libcouchbase-dev.docs +3 -0
  306. data/ext/libcouchbase/packaging/deb/package.mk +31 -0
  307. data/ext/libcouchbase/packaging/deb/rules +46 -0
  308. data/ext/libcouchbase/packaging/deb/source/format +1 -0
  309. data/ext/libcouchbase/packaging/distinfo/README +1 -0
  310. data/ext/libcouchbase/packaging/distinfo/distinfo.cmake.in +4 -0
  311. data/ext/libcouchbase/packaging/dllversion.rc.in +39 -0
  312. data/ext/libcouchbase/packaging/libcouchbase.pc.in +10 -0
  313. data/ext/libcouchbase/packaging/nuget/libcouchbase.autopkg +76 -0
  314. data/ext/libcouchbase/packaging/parse-git-describe.pl +166 -0
  315. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +101 -0
  316. data/ext/libcouchbase/packaging/rpm/package.mk +40 -0
  317. data/ext/libcouchbase/plugins/io/iocp/CMakeLists.txt +9 -0
  318. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.c +467 -0
  319. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.h +217 -0
  320. data/ext/libcouchbase/plugins/io/iocp/iocp_loop.c +295 -0
  321. data/ext/libcouchbase/plugins/io/iocp/iocp_timer.c +79 -0
  322. data/ext/libcouchbase/plugins/io/iocp/iocp_util.c +229 -0
  323. data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +31 -0
  324. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +66 -0
  325. data/ext/libcouchbase/plugins/io/libev/plugin-libev.c +289 -0
  326. data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +31 -0
  327. data/ext/libcouchbase/plugins/io/libevent/libevent_io_opts.h +67 -0
  328. data/ext/libcouchbase/plugins/io/libevent/plugin-libevent.c +292 -0
  329. data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +44 -0
  330. data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +218 -0
  331. data/ext/libcouchbase/plugins/io/libuv/libuv_io_opts.h +118 -0
  332. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +155 -0
  333. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +709 -0
  334. data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +13 -0
  335. data/ext/libcouchbase/plugins/io/select/plugin-select.c +451 -0
  336. data/ext/libcouchbase/plugins/io/select/select_io_opts.h +39 -0
  337. data/ext/libcouchbase/src/README.md +101 -0
  338. data/ext/libcouchbase/src/aspend.h +105 -0
  339. data/ext/libcouchbase/src/auth-priv.h +85 -0
  340. data/ext/libcouchbase/src/auth.cc +146 -0
  341. data/ext/libcouchbase/src/bootstrap.cc +263 -0
  342. data/ext/libcouchbase/src/bootstrap.h +149 -0
  343. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +450 -0
  344. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  345. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +527 -0
  346. data/ext/libcouchbase/src/bucketconfig/bc_http.h +107 -0
  347. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  348. data/ext/libcouchbase/src/bucketconfig/clconfig.h +700 -0
  349. data/ext/libcouchbase/src/bucketconfig/confmon.cc +403 -0
  350. data/ext/libcouchbase/src/callbacks.c +380 -0
  351. data/ext/libcouchbase/src/cbft.cc +253 -0
  352. data/ext/libcouchbase/src/cntl.cc +1057 -0
  353. data/ext/libcouchbase/src/config_static.h +176 -0
  354. data/ext/libcouchbase/src/connspec.cc +555 -0
  355. data/ext/libcouchbase/src/connspec.h +155 -0
  356. data/ext/libcouchbase/src/crypto.cc +399 -0
  357. data/ext/libcouchbase/src/ctx-log-inl.h +44 -0
  358. data/ext/libcouchbase/src/dns-srv.cc +146 -0
  359. data/ext/libcouchbase/src/dump.cc +103 -0
  360. data/ext/libcouchbase/src/errmap.cc +173 -0
  361. data/ext/libcouchbase/src/errmap.h +271 -0
  362. data/ext/libcouchbase/src/getconfig.cc +72 -0
  363. data/ext/libcouchbase/src/gethrtime.c +109 -0
  364. data/ext/libcouchbase/src/handler.cc +1101 -0
  365. data/ext/libcouchbase/src/hashtable.c +75 -0
  366. data/ext/libcouchbase/src/hdr_timings.c +92 -0
  367. data/ext/libcouchbase/src/hostlist.cc +293 -0
  368. data/ext/libcouchbase/src/hostlist.h +160 -0
  369. data/ext/libcouchbase/src/http/http-priv.h +326 -0
  370. data/ext/libcouchbase/src/http/http.cc +672 -0
  371. data/ext/libcouchbase/src/http/http.h +1 -0
  372. data/ext/libcouchbase/src/http/http_io.cc +316 -0
  373. data/ext/libcouchbase/src/instance.cc +917 -0
  374. data/ext/libcouchbase/src/internal.h +285 -0
  375. data/ext/libcouchbase/src/iofactory.c +575 -0
  376. data/ext/libcouchbase/src/jsparse/parser.cc +445 -0
  377. data/ext/libcouchbase/src/jsparse/parser.h +159 -0
  378. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  379. data/ext/libcouchbase/src/lcbht/lcbht.h +210 -0
  380. data/ext/libcouchbase/src/lcbio/connect.cc +603 -0
  381. data/ext/libcouchbase/src/lcbio/connect.h +400 -0
  382. data/ext/libcouchbase/src/lcbio/ctx.c +658 -0
  383. data/ext/libcouchbase/src/lcbio/ctx.h +405 -0
  384. data/ext/libcouchbase/src/lcbio/iotable.c +290 -0
  385. data/ext/libcouchbase/src/lcbio/iotable.h +169 -0
  386. data/ext/libcouchbase/src/lcbio/ioutils.cc +356 -0
  387. data/ext/libcouchbase/src/lcbio/ioutils.h +144 -0
  388. data/ext/libcouchbase/src/lcbio/lcbio.h +51 -0
  389. data/ext/libcouchbase/src/lcbio/manager.cc +579 -0
  390. data/ext/libcouchbase/src/lcbio/manager.h +195 -0
  391. data/ext/libcouchbase/src/lcbio/protoctx.c +84 -0
  392. data/ext/libcouchbase/src/lcbio/rw-inl.h +137 -0
  393. data/ext/libcouchbase/src/lcbio/ssl.h +159 -0
  394. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  395. data/ext/libcouchbase/src/lcbio/timer-ng.h +179 -0
  396. data/ext/libcouchbase/src/lcbio/timer.c +132 -0
  397. data/ext/libcouchbase/src/legacy.c +431 -0
  398. data/ext/libcouchbase/src/list.c +144 -0
  399. data/ext/libcouchbase/src/list.h +127 -0
  400. data/ext/libcouchbase/src/logging.c +244 -0
  401. data/ext/libcouchbase/src/logging.h +88 -0
  402. data/ext/libcouchbase/src/mc/compress.cc +171 -0
  403. data/ext/libcouchbase/src/mc/compress.h +56 -0
  404. data/ext/libcouchbase/src/mc/forward.c +186 -0
  405. data/ext/libcouchbase/src/mc/forward.h +90 -0
  406. data/ext/libcouchbase/src/mc/iovcursor-inl.h +279 -0
  407. data/ext/libcouchbase/src/mc/iovcursor.h +66 -0
  408. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +115 -0
  409. data/ext/libcouchbase/src/mc/mcreq.c +983 -0
  410. data/ext/libcouchbase/src/mc/mcreq.h +1015 -0
  411. data/ext/libcouchbase/src/mcserver/mcserver.cc +1055 -0
  412. data/ext/libcouchbase/src/mcserver/mcserver.h +221 -0
  413. data/ext/libcouchbase/src/mcserver/negotiate.cc +757 -0
  414. data/ext/libcouchbase/src/mcserver/negotiate.h +128 -0
  415. data/ext/libcouchbase/src/mctx-helper.h +62 -0
  416. data/ext/libcouchbase/src/metrics.cc +132 -0
  417. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +857 -0
  418. data/ext/libcouchbase/src/n1ql/n1ql-internal.h +22 -0
  419. data/ext/libcouchbase/src/n1ql/n1ql.cc +830 -0
  420. data/ext/libcouchbase/src/n1ql/params.cc +260 -0
  421. data/ext/libcouchbase/src/netbuf/netbuf-defs.h +89 -0
  422. data/ext/libcouchbase/src/netbuf/netbuf-mblock.h +235 -0
  423. data/ext/libcouchbase/src/netbuf/netbuf.c +929 -0
  424. data/ext/libcouchbase/src/netbuf/netbuf.h +452 -0
  425. data/ext/libcouchbase/src/newconfig.cc +365 -0
  426. data/ext/libcouchbase/src/nodeinfo.cc +184 -0
  427. data/ext/libcouchbase/src/operations/cbflush.cc +63 -0
  428. data/ext/libcouchbase/src/operations/counter.cc +117 -0
  429. data/ext/libcouchbase/src/operations/durability-cas.cc +251 -0
  430. data/ext/libcouchbase/src/operations/durability-seqno.cc +170 -0
  431. data/ext/libcouchbase/src/operations/durability.cc +668 -0
  432. data/ext/libcouchbase/src/operations/durability_internal.h +306 -0
  433. data/ext/libcouchbase/src/operations/get.cc +409 -0
  434. data/ext/libcouchbase/src/operations/observe-seqno.cc +94 -0
  435. data/ext/libcouchbase/src/operations/observe.cc +367 -0
  436. data/ext/libcouchbase/src/operations/ping.cc +496 -0
  437. data/ext/libcouchbase/src/operations/pktfwd.cc +86 -0
  438. data/ext/libcouchbase/src/operations/remove.cc +84 -0
  439. data/ext/libcouchbase/src/operations/stats.cc +459 -0
  440. data/ext/libcouchbase/src/operations/store.cc +358 -0
  441. data/ext/libcouchbase/src/operations/subdoc.cc +614 -0
  442. data/ext/libcouchbase/src/operations/touch.cc +84 -0
  443. data/ext/libcouchbase/src/packetutils.h +388 -0
  444. data/ext/libcouchbase/src/probes.d +182 -0
  445. data/ext/libcouchbase/src/rdb/bigalloc.c +225 -0
  446. data/ext/libcouchbase/src/rdb/bigalloc.h +73 -0
  447. data/ext/libcouchbase/src/rdb/chunkalloc.c +174 -0
  448. data/ext/libcouchbase/src/rdb/libcalloc.c +94 -0
  449. data/ext/libcouchbase/src/rdb/rope.c +419 -0
  450. data/ext/libcouchbase/src/rdb/rope.h +488 -0
  451. data/ext/libcouchbase/src/retrychk.cc +113 -0
  452. data/ext/libcouchbase/src/retryq.cc +458 -0
  453. data/ext/libcouchbase/src/retryq.h +170 -0
  454. data/ext/libcouchbase/src/ringbuffer.c +442 -0
  455. data/ext/libcouchbase/src/ringbuffer.h +100 -0
  456. data/ext/libcouchbase/src/rnd.cc +61 -0
  457. data/ext/libcouchbase/src/rnd.h +39 -0
  458. data/ext/libcouchbase/src/settings.c +125 -0
  459. data/ext/libcouchbase/src/settings.h +273 -0
  460. data/ext/libcouchbase/src/sllist-inl.h +197 -0
  461. data/ext/libcouchbase/src/sllist.h +76 -0
  462. data/ext/libcouchbase/src/ssl/CMakeLists.txt +11 -0
  463. data/ext/libcouchbase/src/ssl/ssl_c.c +442 -0
  464. data/ext/libcouchbase/src/ssl/ssl_common.c +478 -0
  465. data/ext/libcouchbase/src/ssl/ssl_e.c +421 -0
  466. data/ext/libcouchbase/src/ssl/ssl_iot_common.h +182 -0
  467. data/ext/libcouchbase/src/strcodecs/base64.c +307 -0
  468. data/ext/libcouchbase/src/strcodecs/strcodecs.h +302 -0
  469. data/ext/libcouchbase/src/timings.c +207 -0
  470. data/ext/libcouchbase/src/trace.h +117 -0
  471. data/ext/libcouchbase/src/tracing/span.cc +421 -0
  472. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +213 -0
  473. data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
  474. data/ext/libcouchbase/src/tracing/tracing-internal.h +198 -0
  475. data/ext/libcouchbase/src/utilities.c +176 -0
  476. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -0
  477. data/ext/libcouchbase/src/vbucket/aliases.h +35 -0
  478. data/ext/libcouchbase/src/vbucket/crc32.h +83 -0
  479. data/ext/libcouchbase/src/vbucket/hash.h +30 -0
  480. data/ext/libcouchbase/src/vbucket/json-inl.h +112 -0
  481. data/ext/libcouchbase/src/vbucket/ketama.c +66 -0
  482. data/ext/libcouchbase/src/vbucket/rfc1321/global.h +32 -0
  483. data/ext/libcouchbase/src/vbucket/rfc1321/md5.h +35 -0
  484. data/ext/libcouchbase/src/vbucket/rfc1321/md5c-inl.h +335 -0
  485. data/ext/libcouchbase/src/vbucket/vbucket.c +1735 -0
  486. data/ext/libcouchbase/src/views/docreq.cc +213 -0
  487. data/ext/libcouchbase/src/views/docreq.h +94 -0
  488. data/ext/libcouchbase/src/views/viewreq.cc +381 -0
  489. data/ext/libcouchbase/src/views/viewreq.h +87 -0
  490. data/ext/libcouchbase/src/wait.cc +156 -0
  491. data/ext/libcouchbase/tests/CMakeLists.txt +149 -0
  492. data/ext/libcouchbase/tests/basic/t_base64.cc +109 -0
  493. data/ext/libcouchbase/tests/basic/t_ccbc103.cc +95 -0
  494. data/ext/libcouchbase/tests/basic/t_connstr.cc +456 -0
  495. data/ext/libcouchbase/tests/basic/t_creds.cc +96 -0
  496. data/ext/libcouchbase/tests/basic/t_ctlcodes.cc +92 -0
  497. data/ext/libcouchbase/tests/basic/t_host.cc +210 -0
  498. data/ext/libcouchbase/tests/basic/t_jsparse.cc +82 -0
  499. data/ext/libcouchbase/tests/basic/t_jsparse.h +589 -0
  500. data/ext/libcouchbase/tests/basic/t_list.cc +155 -0
  501. data/ext/libcouchbase/tests/basic/t_logger.cc +65 -0
  502. data/ext/libcouchbase/tests/basic/t_misc.cc +24 -0
  503. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +17 -0
  504. data/ext/libcouchbase/tests/basic/t_netbuf.cc +446 -0
  505. data/ext/libcouchbase/tests/basic/t_packet.cc +215 -0
  506. data/ext/libcouchbase/tests/basic/t_ringbuffer.cc +278 -0
  507. data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
  508. data/ext/libcouchbase/tests/basic/t_slist.cc +429 -0
  509. data/ext/libcouchbase/tests/basic/t_strerror.cc +64 -0
  510. data/ext/libcouchbase/tests/basic/t_urlencode.cc +132 -0
  511. data/ext/libcouchbase/tests/check-all.cc +612 -0
  512. data/ext/libcouchbase/tests/htparse/t_basic.cc +173 -0
  513. data/ext/libcouchbase/tests/ioserver/connection.cc +166 -0
  514. data/ext/libcouchbase/tests/ioserver/future.cc +50 -0
  515. data/ext/libcouchbase/tests/ioserver/ioserver.cc +117 -0
  516. data/ext/libcouchbase/tests/ioserver/ioserver.h +478 -0
  517. data/ext/libcouchbase/tests/ioserver/socket.cc +88 -0
  518. data/ext/libcouchbase/tests/ioserver/ssl_connection.cc +145 -0
  519. data/ext/libcouchbase/tests/ioserver/threads-pthreads.cc +119 -0
  520. data/ext/libcouchbase/tests/ioserver/threads-win32.cc +117 -0
  521. data/ext/libcouchbase/tests/ioserver/threads.h +66 -0
  522. data/ext/libcouchbase/tests/iotests/iotests.h +15 -0
  523. data/ext/libcouchbase/tests/iotests/mock-environment.cc +632 -0
  524. data/ext/libcouchbase/tests/iotests/mock-environment.h +480 -0
  525. data/ext/libcouchbase/tests/iotests/mock-unit-test.cc +67 -0
  526. data/ext/libcouchbase/tests/iotests/mock-unit-test.h +61 -0
  527. data/ext/libcouchbase/tests/iotests/serverparams.h +76 -0
  528. data/ext/libcouchbase/tests/iotests/t_arithmetic.cc +143 -0
  529. data/ext/libcouchbase/tests/iotests/t_behavior.cc +220 -0
  530. data/ext/libcouchbase/tests/iotests/t_configcache.cc +117 -0
  531. data/ext/libcouchbase/tests/iotests/t_confmon.cc +223 -0
  532. data/ext/libcouchbase/tests/iotests/t_durability.cc +1108 -0
  533. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +121 -0
  534. data/ext/libcouchbase/tests/iotests/t_errmap.cc +181 -0
  535. data/ext/libcouchbase/tests/iotests/t_forward.cc +118 -0
  536. data/ext/libcouchbase/tests/iotests/t_get.cc +512 -0
  537. data/ext/libcouchbase/tests/iotests/t_http.cc +438 -0
  538. data/ext/libcouchbase/tests/iotests/t_iops.cc +175 -0
  539. data/ext/libcouchbase/tests/iotests/t_lock.cc +274 -0
  540. data/ext/libcouchbase/tests/iotests/t_misc.cc +777 -0
  541. data/ext/libcouchbase/tests/iotests/t_mutate.cc +609 -0
  542. data/ext/libcouchbase/tests/iotests/t_n1ql.cc +270 -0
  543. data/ext/libcouchbase/tests/iotests/t_netfail.cc +778 -0
  544. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +156 -0
  545. data/ext/libcouchbase/tests/iotests/t_regression.cc +321 -0
  546. data/ext/libcouchbase/tests/iotests/t_sched.cc +87 -0
  547. data/ext/libcouchbase/tests/iotests/t_serverops.cc +231 -0
  548. data/ext/libcouchbase/tests/iotests/t_smoke.cc +528 -0
  549. data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
  550. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +857 -0
  551. data/ext/libcouchbase/tests/iotests/t_syncmode.cc +64 -0
  552. data/ext/libcouchbase/tests/iotests/t_views.cc +417 -0
  553. data/ext/libcouchbase/tests/iotests/testutil.cc +251 -0
  554. data/ext/libcouchbase/tests/iotests/testutil.h +163 -0
  555. data/ext/libcouchbase/tests/mc/mctest.h +119 -0
  556. data/ext/libcouchbase/tests/mc/pktmaker.h +101 -0
  557. data/ext/libcouchbase/tests/mc/t_alloc.cc +269 -0
  558. data/ext/libcouchbase/tests/mc/t_context.cc +100 -0
  559. data/ext/libcouchbase/tests/mc/t_flush.cc +185 -0
  560. data/ext/libcouchbase/tests/mc/t_forward.cc +239 -0
  561. data/ext/libcouchbase/tests/mc/t_ioflush.cc +102 -0
  562. data/ext/libcouchbase/tests/mc/t_iovcursor.cc +173 -0
  563. data/ext/libcouchbase/tests/mocksupport/procutil.c +305 -0
  564. data/ext/libcouchbase/tests/mocksupport/procutil.h +89 -0
  565. data/ext/libcouchbase/tests/mocksupport/server.c +391 -0
  566. data/ext/libcouchbase/tests/mocksupport/server.h +72 -0
  567. data/ext/libcouchbase/tests/mocksupport/timeout.c +69 -0
  568. data/ext/libcouchbase/tests/nonio_tests.cc +23 -0
  569. data/ext/libcouchbase/tests/rdb/rdbtest.h +133 -0
  570. data/ext/libcouchbase/tests/rdb/t_basic.cc +128 -0
  571. data/ext/libcouchbase/tests/rdb/t_bigalloc.cc +93 -0
  572. data/ext/libcouchbase/tests/rdb/t_refs.cc +112 -0
  573. data/ext/libcouchbase/tests/socktests/socktest.cc +344 -0
  574. data/ext/libcouchbase/tests/socktests/socktest.h +447 -0
  575. data/ext/libcouchbase/tests/socktests/t_basic.cc +143 -0
  576. data/ext/libcouchbase/tests/socktests/t_ctx.cc +73 -0
  577. data/ext/libcouchbase/tests/socktests/t_manager.cc +159 -0
  578. data/ext/libcouchbase/tests/socktests/t_putex.cc +256 -0
  579. data/ext/libcouchbase/tests/socktests/t_read.cc +187 -0
  580. data/ext/libcouchbase/tests/socktests/t_reentrant.cc +143 -0
  581. data/ext/libcouchbase/tests/socktests/t_ssl.cc +80 -0
  582. data/ext/libcouchbase/tests/socktests/t_write.cc +95 -0
  583. data/ext/libcouchbase/tests/start_mock.bat +15 -0
  584. data/ext/libcouchbase/tests/start_mock.sh +42 -0
  585. data/ext/libcouchbase/tests/unit_tests.cc +43 -0
  586. data/ext/libcouchbase/tests/vbucket/confdata/bad.json +101 -0
  587. data/ext/libcouchbase/tests/vbucket/confdata/full_25.json +363 -0
  588. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  589. data/ext/libcouchbase/tests/vbucket/confdata/map_node_present_nodesext_missing_nodes.json +94 -0
  590. data/ext/libcouchbase/tests/vbucket/confdata/memd_25.json +90 -0
  591. data/ext/libcouchbase/tests/vbucket/confdata/memd_30.json +1 -0
  592. data/ext/libcouchbase/tests/vbucket/confdata/memd_45.json +1 -0
  593. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  594. data/ext/libcouchbase/tests/vbucket/confdata/terse_25.json +291 -0
  595. data/ext/libcouchbase/tests/vbucket/confdata/terse_30.json +1 -0
  596. data/ext/libcouchbase/tests/vbucket/t_config.cc +386 -0
  597. data/ext/libcouchbase/tools/CMakeLists.txt +80 -0
  598. data/ext/libcouchbase/tools/cbc-handlers.h +636 -0
  599. data/ext/libcouchbase/tools/cbc-n1qlback.cc +496 -0
  600. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1230 -0
  601. data/ext/libcouchbase/tools/cbc-proxy.cc +534 -0
  602. data/ext/libcouchbase/tools/cbc-subdoc.cc +825 -0
  603. data/ext/libcouchbase/tools/cbc.cc +1928 -0
  604. data/ext/libcouchbase/tools/common/histogram.cc +44 -0
  605. data/ext/libcouchbase/tools/common/histogram.h +23 -0
  606. data/ext/libcouchbase/tools/common/options.cc +451 -0
  607. data/ext/libcouchbase/tools/common/options.h +90 -0
  608. data/ext/libcouchbase/tools/docgen/docgen.h +495 -0
  609. data/ext/libcouchbase/tools/docgen/loc.h +211 -0
  610. data/ext/libcouchbase/tools/docgen/placeholders.h +211 -0
  611. data/ext/libcouchbase/tools/docgen/seqgen.h +122 -0
  612. data/ext/libcouchbase/tools/extract-packets.rb +110 -0
  613. data/ext/libcouchbase/tools/linenoise/linenoise.c +1199 -0
  614. data/ext/libcouchbase/tools/linenoise/linenoise.h +73 -0
  615. data/lib/mt-libcouchbase/bucket.rb +825 -0
  616. data/lib/mt-libcouchbase/callbacks.rb +69 -0
  617. data/lib/mt-libcouchbase/connection.rb +896 -0
  618. data/lib/mt-libcouchbase/design_docs.rb +92 -0
  619. data/lib/mt-libcouchbase/error.rb +68 -0
  620. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdbase.rb +23 -0
  621. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdcounter.rb +36 -0
  622. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdendure.rb +26 -0
  623. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdfts.rb +24 -0
  624. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdget.rb +30 -0
  625. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdgetreplica.rb +49 -0
  626. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdhttp.rb +58 -0
  627. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdn1ql.rb +40 -0
  628. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdobseqno.rb +33 -0
  629. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdobserve.rb +30 -0
  630. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdstore.rb +40 -0
  631. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdstoredur.rb +45 -0
  632. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdsubdoc.rb +61 -0
  633. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdverbosity.rb +29 -0
  634. data/lib/mt-libcouchbase/ext/mt-libcouchbase/cmdviewquery.rb +61 -0
  635. data/lib/mt-libcouchbase/ext/mt-libcouchbase/contigbuf.rb +14 -0
  636. data/lib/mt-libcouchbase/ext/mt-libcouchbase/create_st.rb +15 -0
  637. data/lib/mt-libcouchbase/ext/mt-libcouchbase/create_st0.rb +23 -0
  638. data/lib/mt-libcouchbase/ext/mt-libcouchbase/create_st1.rb +26 -0
  639. data/lib/mt-libcouchbase/ext/mt-libcouchbase/create_st2.rb +32 -0
  640. data/lib/mt-libcouchbase/ext/mt-libcouchbase/create_st3.rb +26 -0
  641. data/lib/mt-libcouchbase/ext/mt-libcouchbase/crst_u.rb +20 -0
  642. data/lib/mt-libcouchbase/ext/mt-libcouchbase/durability_opts_st_v.rb +11 -0
  643. data/lib/mt-libcouchbase/ext/mt-libcouchbase/durability_opts_t.rb +14 -0
  644. data/lib/mt-libcouchbase/ext/mt-libcouchbase/durabilityopt_sv0.rb +63 -0
  645. data/lib/mt-libcouchbase/ext/mt-libcouchbase/enums.rb +1007 -0
  646. data/lib/mt-libcouchbase/ext/mt-libcouchbase/fragbuf.rb +18 -0
  647. data/lib/mt-libcouchbase/ext/mt-libcouchbase/ftshandle.rb +7 -0
  648. data/lib/mt-libcouchbase/ext/mt-libcouchbase/histogram.rb +34 -0
  649. data/lib/mt-libcouchbase/ext/mt-libcouchbase/http_request_t.rb +7 -0
  650. data/lib/mt-libcouchbase/ext/mt-libcouchbase/keybuf.rb +20 -0
  651. data/lib/mt-libcouchbase/ext/mt-libcouchbase/multicmd_ctx.rb +30 -0
  652. data/lib/mt-libcouchbase/ext/mt-libcouchbase/mutation_token.rb +17 -0
  653. data/lib/mt-libcouchbase/ext/mt-libcouchbase/n1qlhandle.rb +7 -0
  654. data/lib/mt-libcouchbase/ext/mt-libcouchbase/n1qlparams.rb +7 -0
  655. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respbase.rb +29 -0
  656. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respcounter.rb +32 -0
  657. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respendure.rb +49 -0
  658. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respfts.rb +40 -0
  659. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respget.rb +44 -0
  660. data/lib/mt-libcouchbase/ext/mt-libcouchbase/resphttp.rb +48 -0
  661. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respmcversion.rb +38 -0
  662. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respn1ql.rb +41 -0
  663. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respobseqno.rb +52 -0
  664. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respobserve.rb +41 -0
  665. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respserverbase.rb +32 -0
  666. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respstats.rb +38 -0
  667. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respstore.rb +32 -0
  668. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respstoredur.rb +38 -0
  669. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respsubdoc.rb +35 -0
  670. data/lib/mt-libcouchbase/ext/mt-libcouchbase/respviewquery.rb +67 -0
  671. data/lib/mt-libcouchbase/ext/mt-libcouchbase/sdentry.rb +22 -0
  672. data/lib/mt-libcouchbase/ext/mt-libcouchbase/sdspec.rb +31 -0
  673. data/lib/mt-libcouchbase/ext/mt-libcouchbase/t.rb +7 -0
  674. data/lib/mt-libcouchbase/ext/mt-libcouchbase/valbuf.rb +22 -0
  675. data/lib/mt-libcouchbase/ext/mt-libcouchbase/valbuf_u_buf.rb +14 -0
  676. data/lib/mt-libcouchbase/ext/mt-libcouchbase/viewhandle.rb +7 -0
  677. data/lib/mt-libcouchbase/ext/mt-libcouchbase.rb +1175 -0
  678. data/lib/mt-libcouchbase/ext/mt-libcouchbase_libuv.rb +22 -0
  679. data/lib/mt-libcouchbase/ext/tasks.rb +39 -0
  680. data/lib/mt-libcouchbase/n1ql.rb +80 -0
  681. data/lib/mt-libcouchbase/query_full_text.rb +147 -0
  682. data/lib/mt-libcouchbase/query_n1ql.rb +123 -0
  683. data/lib/mt-libcouchbase/query_view.rb +135 -0
  684. data/lib/mt-libcouchbase/results_fiber.rb +281 -0
  685. data/lib/mt-libcouchbase/results_native.rb +220 -0
  686. data/lib/mt-libcouchbase/subdoc_request.rb +139 -0
  687. data/lib/mt-libcouchbase/version.rb +5 -0
  688. data/lib/mt-libcouchbase.rb +40 -0
  689. data/mt-libcouchbase.gemspec +68 -0
  690. data/spec/bucket_spec.rb +290 -0
  691. data/spec/connection_spec.rb +257 -0
  692. data/spec/design_docs_spec.rb +31 -0
  693. data/spec/error_spec.rb +26 -0
  694. data/spec/fts_spec.rb +135 -0
  695. data/spec/n1ql_spec.rb +260 -0
  696. data/spec/results_libuv_spec.rb +244 -0
  697. data/spec/results_native_spec.rb +259 -0
  698. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/design.json +1 -0
  699. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/data-0000.cbb +0 -0
  700. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/failover.json +1 -0
  701. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/meta.json +1 -0
  702. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/seqno.json +1 -0
  703. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/snapshot_markers.json +1 -0
  704. data/spec/subdoc_spec.rb +192 -0
  705. data/spec/view_spec.rb +201 -0
  706. data/windows_build.md +36 -0
  707. metadata +873 -0
@@ -0,0 +1,1735 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2014 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
+
18
+ #include <stdlib.h>
19
+ #include <string.h>
20
+ #include <stddef.h>
21
+ #include <assert.h>
22
+ #include <libcouchbase/couchbase.h>
23
+ #include <libcouchbase/vbucket.h>
24
+ #include "config.h"
25
+ #include "contrib/cJSON/cJSON.h"
26
+ #include "json-inl.h"
27
+ #include "hash.h"
28
+ #include "crc32.h"
29
+
30
+ #define STRINGIFY_(X) #X
31
+ #define STRINGIFY(X) STRINGIFY_(X)
32
+ #define MAX_AUTHORITY_SIZE 100
33
+ #define SET_ERRSTR(cfg, s) if (!(cfg)->errstr) { \
34
+ (cfg)->errstr = __FILE__ ":" STRINGIFY(__LINE__) " " s ; \
35
+ }
36
+
37
+ /******************************************************************************
38
+ ******************************************************************************
39
+ ** Core Parsing Routines **
40
+ ******************************************************************************
41
+ ******************************************************************************/
42
+ static lcbvb_VBUCKET *
43
+ build_vbmap(lcbvb_CONFIG *cfg, cJSON *cj, unsigned *nitems)
44
+ {
45
+ lcbvb_VBUCKET *vblist = NULL;
46
+ cJSON *jvb;
47
+ unsigned ii, nalloc;
48
+
49
+ /** FIXME: Realloc dynamically when too small */
50
+ if (!(nalloc = cJSON_GetArraySize(cj))) {
51
+ goto GT_ERR;
52
+ }
53
+
54
+ if (!(vblist = calloc(nalloc, sizeof(*vblist)))) {
55
+ goto GT_ERR;
56
+ }
57
+
58
+ /* Iterate over all the vbuckets */
59
+ jvb = cj->child;
60
+ for (ii = 0; ii < nalloc && jvb; ++ii, jvb = jvb->next) {
61
+ cJSON *jsix;
62
+ lcbvb_VBUCKET *cvb;
63
+ unsigned jj, nservers;
64
+
65
+ if (jvb->type != cJSON_Array) {
66
+ goto GT_ERR;
67
+ }
68
+
69
+ nservers = cJSON_GetArraySize(jvb);
70
+ jsix = jvb->child;
71
+ cvb = vblist + ii;
72
+
73
+ /* Iterate over each index in the vbucket */
74
+ for (jj = 0; jj < nservers && jsix; ++jj, jsix = jsix->next) {
75
+ if (jsix->type != cJSON_Number) {
76
+ goto GT_ERR;
77
+ }
78
+ cvb->servers[jj] = jsix->valueint;
79
+ if (cvb->servers[jj] > (int)cfg->nsrv-1) {
80
+ SET_ERRSTR(cfg, "Invalid vBucket map received from server. Above-bounds vBucket target found");
81
+ goto GT_ERR;
82
+ }
83
+ }
84
+ }
85
+
86
+ *nitems = nalloc;
87
+ return vblist;
88
+
89
+ GT_ERR:
90
+ free(vblist);
91
+ return NULL;
92
+ }
93
+
94
+ static void copy_address(char *buf, size_t nbuf, const char *host, lcb_U16 port)
95
+ {
96
+ if (strchr(host, ':')) {
97
+ // IPv6 and should be bracketed
98
+ snprintf(buf, nbuf, "[%s]:%d", host, port);
99
+ } else {
100
+ snprintf(buf, nbuf, "%s:%d", host, port);
101
+ }
102
+ }
103
+
104
+ static lcbvb_SERVER *
105
+ find_server_memd(lcbvb_SERVER *servers, unsigned n, const char *s)
106
+ {
107
+ unsigned ii;
108
+ for (ii = 0; ii < n; ii++) {
109
+ char buf[4096] = { 0 };
110
+ lcbvb_SERVER *cur = servers + ii;
111
+ copy_address(buf, sizeof(buf), cur->hostname, cur->svc.data);
112
+ if (!strncmp(s, buf, sizeof(buf))) {
113
+ return cur;
114
+ }
115
+ }
116
+ return NULL;
117
+ }
118
+
119
+ static int
120
+ assign_dumy_server(lcbvb_CONFIG *cfg, lcbvb_SERVER *dst, const char *s)
121
+ {
122
+ int itmp;
123
+ char *colon;
124
+ if (!(dst->authority = strdup(s))) {
125
+ SET_ERRSTR(cfg, "Couldn't allocate authority string");
126
+ goto GT_ERR;
127
+ }
128
+
129
+ if (!(colon = strstr(s, ":"))) {
130
+ SET_ERRSTR(cfg, "Badly formatted name string");
131
+ goto GT_ERR;
132
+ }
133
+
134
+ if (sscanf(colon+1, "%d", &itmp) != 1) {
135
+ SET_ERRSTR(cfg, "Badly formatted port");
136
+ goto GT_ERR;
137
+ }
138
+
139
+ dst->svc.data = itmp;
140
+ return 1;
141
+
142
+ GT_ERR:
143
+ free(dst->authority);
144
+ return 0;
145
+ }
146
+
147
+ static void
148
+ set_vb_count(lcbvb_CONFIG *cfg, lcbvb_VBUCKET *vbs)
149
+ {
150
+ unsigned ii, jj;
151
+ if (!vbs) {
152
+ return;
153
+ }
154
+
155
+ for (ii = 0; ii < cfg->nvb; ++ii) {
156
+ for (jj = 0; jj < cfg->nrepl+1; ++jj) {
157
+ int ix = vbs[ii].servers[jj];
158
+ if (ix < 0 || (unsigned)ix > cfg->nsrv) {
159
+ continue;
160
+ }
161
+ cfg->servers[ix].nvbs++;
162
+ }
163
+ }
164
+ }
165
+
166
+ static int
167
+ pair_server_list(lcbvb_CONFIG *cfg, cJSON *vbconfig)
168
+ {
169
+ cJSON *servers;
170
+ lcbvb_SERVER *newlist = NULL;
171
+ unsigned ii, nsrv;
172
+
173
+ if (!get_jarray(vbconfig, "serverList", &servers)) {
174
+ SET_ERRSTR(cfg, "Couldn't find serverList");
175
+ goto GT_ERROR;
176
+ }
177
+
178
+ nsrv = cJSON_GetArraySize(servers);
179
+
180
+ if (nsrv > cfg->nsrv) {
181
+ /* nodes in serverList which are not in nodes/nodesExt */
182
+ void *tmp = realloc(cfg->servers, sizeof(*cfg->servers) * nsrv);
183
+ if (!tmp) {
184
+ SET_ERRSTR(cfg, "Couldn't allocate memory for server list");
185
+ goto GT_ERROR;
186
+ }
187
+ cfg->servers = tmp;
188
+ cfg->nsrv = nsrv;
189
+ }
190
+
191
+ /* allocate an array for the reordered server list */
192
+ newlist = calloc(nsrv, sizeof(*cfg->servers));
193
+
194
+ for (ii = 0; ii < nsrv; ii++) {
195
+ char *tmp;
196
+ cJSON *jst;
197
+ lcbvb_SERVER *cur;
198
+ jst = cJSON_GetArrayItem(servers, ii);
199
+ tmp = jst->valuestring;
200
+ cur = find_server_memd(cfg->servers, cfg->nsrv, tmp);
201
+
202
+ if (cur) {
203
+ newlist[ii] = *cur;
204
+ } else {
205
+ /* found server inside serverList but not in nodes? */
206
+ if (!assign_dumy_server(cfg, &newlist[ii], tmp)) {
207
+ goto GT_ERROR;
208
+ }
209
+ }
210
+ }
211
+
212
+ free(cfg->servers);
213
+ cfg->servers = newlist;
214
+ return 1;
215
+
216
+ GT_ERROR:
217
+ free(newlist);
218
+ return 0;
219
+
220
+ }
221
+
222
+ static int
223
+ parse_vbucket(lcbvb_CONFIG *cfg, cJSON *cj)
224
+ {
225
+ cJSON *vbconfig, *vbmap, *ffmap = NULL;
226
+
227
+ if (!get_jobj(cj, "vBucketServerMap", &vbconfig)) {
228
+ SET_ERRSTR(cfg, "Expected top-level 'vBucketServerMap'");
229
+ goto GT_ERROR;
230
+ }
231
+
232
+ if (!get_juint(vbconfig, "numReplicas", &cfg->nrepl)) {
233
+ SET_ERRSTR(cfg, "'numReplicas' missing");
234
+ goto GT_ERROR;
235
+ }
236
+
237
+ if (!get_jarray(vbconfig, "vBucketMap", &vbmap)) {
238
+ SET_ERRSTR(cfg, "Missing 'vBucketMap'");
239
+ goto GT_ERROR;
240
+ }
241
+
242
+ get_jarray(vbconfig, "vBucketMapForward", &ffmap);
243
+
244
+ if ((cfg->vbuckets = build_vbmap(cfg, vbmap, &cfg->nvb)) == NULL) {
245
+ goto GT_ERROR;
246
+ }
247
+
248
+ if (ffmap && (cfg->ffvbuckets = build_vbmap(cfg, ffmap, &cfg->nvb)) == NULL) {
249
+ goto GT_ERROR;
250
+ }
251
+
252
+ if (!cfg->is3x) {
253
+ if (!pair_server_list(cfg, vbconfig)) {
254
+ goto GT_ERROR;
255
+ }
256
+ }
257
+
258
+ /** Now figure out which server goes where */
259
+ set_vb_count(cfg, cfg->vbuckets);
260
+ set_vb_count(cfg, cfg->ffvbuckets);
261
+ return 1;
262
+
263
+ GT_ERROR:
264
+ return 0;
265
+ }
266
+
267
+ static int server_cmp(const void *s1, const void *s2)
268
+ {
269
+ return strcmp(((const lcbvb_SERVER *)s1)->authority,
270
+ ((const lcbvb_SERVER *)s2)->authority);
271
+ }
272
+
273
+ static int continuum_item_cmp(const void *t1, const void *t2)
274
+ {
275
+ const lcbvb_CONTINUUM *ct1 = t1, *ct2 = t2;
276
+
277
+ if (ct1->point == ct2->point) {
278
+ return 0;
279
+ } else if (ct1->point > ct2->point) {
280
+ return 1;
281
+ } else {
282
+ return -1;
283
+ }
284
+ }
285
+
286
+ static int
287
+ update_ketama(lcbvb_CONFIG *cfg)
288
+ {
289
+ char host[MAX_AUTHORITY_SIZE+10] = "";
290
+ int nhost;
291
+ unsigned pp, hh, ss, nn;
292
+ unsigned char digest[16];
293
+ lcbvb_CONTINUUM *new_continuum, *old_continuum;
294
+
295
+ qsort(cfg->servers, cfg->ndatasrv, sizeof(*cfg->servers), server_cmp);
296
+
297
+ new_continuum = calloc(160 * cfg->ndatasrv, sizeof(*new_continuum));
298
+ /* 40 hashes, 4 numbers per hash = 160 points per server */
299
+ for (ss = 0, pp = 0; ss < cfg->ndatasrv; ++ss) {
300
+ /* we can add more points to server which have more memory */
301
+ for (hh = 0; hh < 40; ++hh) {
302
+ lcbvb_SERVER *srv = cfg->servers + ss;
303
+ nhost = snprintf(host, MAX_AUTHORITY_SIZE+10, "%s-%u", srv->authority, hh);
304
+ vb__hash_md5(host, nhost, digest);
305
+ for (nn = 0; nn < 4; ++nn, ++pp) {
306
+ new_continuum[pp].index = ss;
307
+ new_continuum[pp].point = ((uint32_t) (digest[3 + nn * 4] & 0xFF) << 24)
308
+ | ((uint32_t) (digest[2 + nn * 4] & 0xFF) << 16)
309
+ | ((uint32_t) (digest[1 + nn * 4] & 0xFF) << 8)
310
+ | (digest[0 + nn * 4] & 0xFF);
311
+ }
312
+ }
313
+ }
314
+
315
+ qsort(new_continuum, pp, sizeof *new_continuum, continuum_item_cmp);
316
+ old_continuum = cfg->continuum;
317
+ cfg->continuum = new_continuum;
318
+ cfg->ncontinuum = pp;
319
+ free(old_continuum);
320
+ return 1;
321
+ }
322
+
323
+ static int
324
+ extract_services(lcbvb_CONFIG *cfg, cJSON *jsvc, lcbvb_SERVICES *svc, int is_ssl)
325
+ {
326
+ int itmp;
327
+ int rv;
328
+ const char *key;
329
+
330
+ #define EXTRACT_SERVICE(k, fld) \
331
+ key = is_ssl ? k"SSL" : k; \
332
+ rv = get_jint(jsvc, key, &itmp); \
333
+ if (rv) { svc->fld = itmp; } else { svc->fld = 0; }
334
+
335
+ EXTRACT_SERVICE("kv", data);
336
+ EXTRACT_SERVICE("mgmt", mgmt);
337
+ EXTRACT_SERVICE("capi", views);
338
+ EXTRACT_SERVICE("n1ql", n1ql);
339
+ EXTRACT_SERVICE("fts", fts);
340
+ EXTRACT_SERVICE("indexAdmin", ixadmin);
341
+ EXTRACT_SERVICE("indexScan", ixquery);
342
+ EXTRACT_SERVICE("cbas", cbas);
343
+
344
+ #undef EXTRACT_SERVICE
345
+
346
+ (void)cfg;
347
+ return 1;
348
+ }
349
+
350
+ static int
351
+ build_server_strings(lcbvb_CONFIG *cfg, lcbvb_SERVER *server)
352
+ {
353
+ /* get the authority */
354
+ char tmpbuf[4096];
355
+
356
+ copy_address(tmpbuf, sizeof(tmpbuf), server->hostname, server->svc.data);
357
+ server->authority = strdup(tmpbuf);
358
+ if (!server->authority) {
359
+ SET_ERRSTR(cfg, "Couldn't allocate authority");
360
+ return 0;
361
+ }
362
+
363
+ server->svc.hoststrs[LCBVB_SVCTYPE_DATA] = strdup(server->authority);
364
+ if (server->viewpath == NULL && server->svc.views) {
365
+ server->viewpath = malloc(strlen(cfg->bname) + 2);
366
+ sprintf(server->viewpath, "/%s", cfg->bname);
367
+ }
368
+ if (server->querypath == NULL && server->svc.n1ql) {
369
+ server->querypath = strdup("/query/service");
370
+ }
371
+ if (server->ftspath == NULL && server->svc.fts) {
372
+ server->ftspath = strdup("/");
373
+ }
374
+ if (server->cbaspath == NULL && server->svc.cbas) {
375
+ server->cbaspath = strdup("/query/service");
376
+ }
377
+ return 1;
378
+ }
379
+
380
+ /**
381
+ * Parse a node from the 'nodesExt' array
382
+ * @param cfg
383
+ * @param server
384
+ * @param js
385
+ * @return
386
+ */
387
+ static int
388
+ build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, char **network)
389
+ {
390
+ cJSON *jsvcs;
391
+ char *htmp;
392
+
393
+ if (!get_jstr(js, "hostname", &htmp)) {
394
+ htmp = "$HOST";
395
+ }
396
+ if (!(server->hostname = strdup(htmp))) {
397
+ SET_ERRSTR(cfg, "Couldn't allocate memory");
398
+ goto GT_ERR;
399
+ }
400
+
401
+ if (!get_jobj(js, "services", &jsvcs)) {
402
+ SET_ERRSTR(cfg, "Couldn't find 'services'");
403
+ goto GT_ERR;
404
+ }
405
+
406
+ if (!extract_services(cfg, jsvcs, &server->svc, 0)) {
407
+ goto GT_ERR;
408
+ }
409
+ if (!extract_services(cfg, jsvcs, &server->svc_ssl, 1)) {
410
+ goto GT_ERR;
411
+ }
412
+
413
+ if (!build_server_strings(cfg, server)) {
414
+ goto GT_ERR;
415
+ }
416
+
417
+ if (network && *network && strcmp(*network, "default") != 0) {
418
+ cJSON *jaltaddr = cJSON_GetObjectItem(js, "alternateAddresses");
419
+ if (jaltaddr && jaltaddr->type == cJSON_Object) {
420
+ cJSON *jnetwork = cJSON_GetObjectItem(jaltaddr, *network);
421
+ if (jnetwork && get_jstr(jnetwork, "hostname", &htmp)) {
422
+ cJSON *jports;
423
+ server->alt_hostname = strdup(htmp);
424
+ jports = cJSON_GetObjectItem(jnetwork, "ports");
425
+ if (jports && jports->type == cJSON_Object) {
426
+ extract_services(cfg, jports, &server->alt_svc, 0);
427
+ extract_services(cfg, jports, &server->alt_svc_ssl, 1);
428
+ }
429
+
430
+ #define COPY_SERVICE(src, dst) \
431
+ if ((dst)->data == 0) (dst)->data = (src)->data; \
432
+ if ((dst)->mgmt == 0) (dst)->mgmt = (src)->mgmt; \
433
+ if ((dst)->views == 0) (dst)->views = (src)->views; \
434
+ if ((dst)->n1ql == 0) (dst)->n1ql = (src)->n1ql; \
435
+ if ((dst)->fts == 0) (dst)->fts = (src)->fts; \
436
+ if ((dst)->ixadmin == 0) (dst)->ixadmin = (src)->ixadmin; \
437
+ if ((dst)->ixquery == 0) (dst)->ixquery = (src)->ixquery; \
438
+ if ((dst)->cbas == 0) (dst)->cbas = (src)->cbas;
439
+
440
+ COPY_SERVICE(&server->svc, &server->alt_svc);
441
+ COPY_SERVICE(&server->svc_ssl, &server->alt_svc_ssl);
442
+
443
+ #undef COPY_SERVICE
444
+ }
445
+ }
446
+ }
447
+
448
+ return 1;
449
+
450
+ GT_ERR:
451
+ return 0;
452
+ }
453
+
454
+ /**
455
+ * Initialize a server from a JSON Object
456
+ * @param server The server to initialize
457
+ * @param js The object which contains the server information
458
+ * @return nonzero on success, 0 on failure.
459
+ */
460
+ static int
461
+ build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, char **network)
462
+ {
463
+ char *tmp = NULL, *colon;
464
+ int itmp;
465
+ cJSON *jsports;
466
+
467
+ if (!get_jstr(js, "hostname", &tmp)) {
468
+ SET_ERRSTR(cfg, "Couldn't find hostname");
469
+ goto GT_ERR;
470
+ }
471
+
472
+ /** Hostname is the _rest_ API host, e.g. '8091' */
473
+ if ((server->hostname = strdup(tmp)) == NULL) {
474
+ SET_ERRSTR(cfg, "Couldn't allocate hostname");
475
+ goto GT_ERR;
476
+ }
477
+
478
+ colon = strchr(server->hostname, ':');
479
+ if (!colon) {
480
+ SET_ERRSTR(cfg, "Expected ':' in 'hostname'");
481
+ goto GT_ERR;
482
+ }
483
+ if (sscanf(colon+1, "%d", &itmp) != 1) {
484
+ SET_ERRSTR(cfg, "Expected port after ':'");
485
+ goto GT_ERR;
486
+ }
487
+
488
+ /* plain mgmt port is extracted from hostname */
489
+ server->svc.mgmt = itmp;
490
+ *colon = '\0';
491
+
492
+ /** Handle the views name */
493
+ if (get_jstr(js, "couchApiBase", &tmp)) {
494
+ /** Have views */
495
+ char *path_begin;
496
+ colon = strrchr(tmp, ':');
497
+
498
+ if (!colon) {
499
+ /* no port */
500
+ goto GT_ERR;
501
+ }
502
+ if (sscanf(colon+1, "%d", &itmp) != 1) {
503
+ goto GT_ERR;
504
+ }
505
+
506
+ /* Assign the port */
507
+ server->svc.views = itmp;
508
+ path_begin = strstr(colon, "/");
509
+ if (!path_begin) {
510
+ SET_ERRSTR(cfg, "Expected path in couchApiBase");
511
+ goto GT_ERR;
512
+ }
513
+ server->viewpath = strdup(path_begin);
514
+ } else {
515
+ server->svc.views = 0;
516
+ }
517
+
518
+ /* get the 'ports' dictionary */
519
+ if (!get_jobj(js, "ports", &jsports)) {
520
+ SET_ERRSTR(cfg, "Expected 'ports' dictionary");
521
+ goto GT_ERR;
522
+ }
523
+
524
+ /* memcached port */
525
+ if (get_jint(jsports, "direct", &itmp)) {
526
+ server->svc.data = itmp;
527
+ } else {
528
+ SET_ERRSTR(cfg, "Expected 'direct' field in 'ports'");
529
+ goto GT_ERR;
530
+ }
531
+
532
+ /* set the authority */
533
+ if (!build_server_strings(cfg, server)) {
534
+ goto GT_ERR;
535
+ }
536
+ return 1;
537
+
538
+ GT_ERR:
539
+ return 0;
540
+ }
541
+
542
+ static void
543
+ guess_network(cJSON *jnodes, int nsrv, const char *source, char **network)
544
+ {
545
+ int ii;
546
+ for (ii = 0; ii < nsrv; ii++) {
547
+ cJSON *jsrv = cJSON_GetArrayItem(jnodes, ii);
548
+ {
549
+ cJSON *jhostname = cJSON_GetObjectItem(jsrv, "hostname");
550
+ if (jhostname && jhostname->type == cJSON_String) {
551
+ if (strcmp(jhostname->valuestring, source) == 0) {
552
+ *network = strdup("default");
553
+ return;
554
+ }
555
+ }
556
+ }
557
+ {
558
+ cJSON *jaltaddr = cJSON_GetObjectItem(jsrv, "alternateAddresses");
559
+ if (jaltaddr && jaltaddr->type == cJSON_Object) {
560
+ cJSON *cur;
561
+ for (cur = jaltaddr->child; cur != NULL; cur = cur->next) {
562
+ if (cur->type == cJSON_Object) {
563
+ cJSON *jhostname = cJSON_GetObjectItem(cur, "hostname");
564
+ if (jhostname && jhostname->type == cJSON_String) {
565
+ if (strcmp(jhostname->valuestring, source) == 0) {
566
+ *network = strdup(cur->string);
567
+ return;
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+ }
575
+ *network = strdup("default");
576
+ }
577
+
578
+ int
579
+ lcbvb_load_json_ex(lcbvb_CONFIG *cfg, const char *data, const char *source, char **network)
580
+ {
581
+ cJSON *cj = NULL, *jnodes_ext = NULL, *jnodes = NULL;
582
+ char *tmp = NULL;
583
+ unsigned ii, jnodes_size = 0;
584
+ int jnodes_defined = 0;
585
+
586
+ if ((cj = cJSON_Parse(data)) == NULL) {
587
+ SET_ERRSTR(cfg, "Couldn't parse JSON");
588
+ goto GT_ERROR;
589
+ }
590
+
591
+ if (!get_jstr(cj, "name", &tmp)) {
592
+ SET_ERRSTR(cfg, "Expected 'name' key");
593
+ goto GT_ERROR;
594
+ }
595
+ cfg->bname = strdup(tmp);
596
+
597
+ if (!get_jstr(cj, "nodeLocator", &tmp)) {
598
+ SET_ERRSTR(cfg, "Expected 'nodeLocator' key");
599
+ goto GT_ERROR;
600
+ }
601
+
602
+ get_jarray(cj, "nodes", &jnodes);
603
+ if (jnodes) {
604
+ jnodes_defined = 1;
605
+ jnodes_size = cJSON_GetArraySize(jnodes);
606
+ }
607
+ if (get_jarray(cj, "nodesExt", &jnodes_ext)) {
608
+ cfg->is3x = 1;
609
+ cfg->nsrv = cJSON_GetArraySize(jnodes_ext);
610
+ jnodes = jnodes_ext;
611
+ } else if (jnodes == NULL) {
612
+ SET_ERRSTR(cfg, "expected 'nodesExt' or 'nodes' array");
613
+ goto GT_ERROR;
614
+ }
615
+
616
+ if (!strcmp(tmp, "ketama")) {
617
+ cfg->dtype = LCBVB_DIST_KETAMA;
618
+ } else {
619
+ cfg->dtype = LCBVB_DIST_VBUCKET;
620
+ }
621
+
622
+ if (get_jstr(cj, "uuid", &tmp)) {
623
+ cfg->buuid = strdup(tmp);
624
+ }
625
+
626
+ if (!get_jint(cj, "rev", &cfg->revid)) {
627
+ cfg->revid = -1;
628
+ }
629
+
630
+ cfg->caps = 0;
631
+ {
632
+ cJSON *jcaps = NULL;
633
+ if (get_jarray(cj, "bucketCapabilities", &jcaps)) {
634
+ unsigned ncaps = cJSON_GetArraySize(jcaps);
635
+ for (ii = 0; ii < ncaps; ii++) {
636
+ cJSON *jcap = cJSON_GetArrayItem(jcaps, ii);
637
+ if (jcap || jcap->type == cJSON_String) {
638
+ if (strcmp(jcap->valuestring, "xattr") == 0) {
639
+ cfg->caps |= LCBVB_CAP_XATTR;
640
+ } else if (strcmp(jcap->valuestring, "dcp") == 0) {
641
+ cfg->caps |= LCBVB_CAP_DCP;
642
+ } else if (strcmp(jcap->valuestring, "cbhello") == 0) {
643
+ cfg->caps |= LCBVB_CAP_CBHELLO;
644
+ } else if (strcmp(jcap->valuestring, "touch") == 0) {
645
+ cfg->caps |= LCBVB_CAP_TOUCH;
646
+ } else if (strcmp(jcap->valuestring, "couchapi") == 0) {
647
+ cfg->caps |= LCBVB_CAP_COUCHAPI;
648
+ } else if (strcmp(jcap->valuestring, "cccp") == 0) {
649
+ cfg->caps |= LCBVB_CAP_CCCP;
650
+ } else if (strcmp(jcap->valuestring, "xdcrCheckpointing") == 0) {
651
+ cfg->caps |= LCBVB_CAP_XDCR_CHECKPOINTING;
652
+ } else if (strcmp(jcap->valuestring, "nodesExt") == 0) {
653
+ cfg->caps |= LCBVB_CAP_NODES_EXT;
654
+ }
655
+ }
656
+ }
657
+ }
658
+ }
659
+
660
+ /** Get the number of nodes. This traverses the list. Yuck */
661
+ cfg->nsrv = cJSON_GetArraySize(jnodes);
662
+
663
+ if (network && *network == NULL) {
664
+ guess_network(jnodes, cfg->nsrv, source, network);
665
+ }
666
+
667
+ /** Allocate a temporary one on the heap */
668
+ cfg->servers = calloc(cfg->nsrv, sizeof(*cfg->servers));
669
+ for (ii = 0; ii < cfg->nsrv; ii++) {
670
+ int rv;
671
+ cJSON *jsrv = cJSON_GetArrayItem(jnodes, ii);
672
+
673
+ if (cfg->is3x) {
674
+ rv = build_server_3x(cfg, cfg->servers + ii, jsrv, network);
675
+ if (jnodes_defined && rv && ii >= jnodes_size) {
676
+ cfg->servers[ii].svc.data = 0;
677
+ cfg->servers[ii].svc_ssl.data = 0;
678
+ cfg->servers[ii].alt_svc.data = 0;
679
+ cfg->servers[ii].alt_svc_ssl.data = 0;
680
+ }
681
+ } else {
682
+ rv = build_server_2x(cfg, cfg->servers + ii, jsrv, network);
683
+ }
684
+
685
+ if (!rv) {
686
+ SET_ERRSTR(cfg, "Failed to build server");
687
+ goto GT_ERROR;
688
+ }
689
+ }
690
+
691
+ /* Count the number of _data_ servers in the cluster. Per the spec,
692
+ * these will always appear in order (so that we won't ever have "holes") */
693
+ for (ii = 0; ii < cfg->nsrv; ii++) {
694
+ if (!cfg->servers[ii].svc.data) {
695
+ break;
696
+ }
697
+ }
698
+ cfg->ndatasrv = ii;
699
+
700
+ if (cfg->dtype == LCBVB_DIST_VBUCKET) {
701
+ if (!parse_vbucket(cfg, cj)) {
702
+ SET_ERRSTR(cfg, "Failed to parse vBucket map");
703
+ goto GT_ERROR;
704
+ }
705
+ } else {
706
+ /* If there is no $HOST then we can update the ketama config, otherwise
707
+ * we must wait for the hostname to be replaced! */
708
+ if (strstr(data, "$HOST") == NULL) {
709
+ if (!update_ketama(cfg)) {
710
+ SET_ERRSTR(cfg, "Failed to establish ketama continuums");
711
+ }
712
+ }
713
+ }
714
+ cfg->servers = realloc(cfg->servers, sizeof(*cfg->servers) * cfg->nsrv);
715
+ cfg->randbuf = malloc(cfg->nsrv * sizeof(*cfg->randbuf));
716
+ cJSON_Delete(cj);
717
+ return 0;
718
+
719
+ GT_ERROR:
720
+ if (cj) {
721
+ cJSON_Delete(cj);
722
+ }
723
+ return -1;
724
+ }
725
+
726
+ int
727
+ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
728
+ {
729
+ return lcbvb_load_json_ex(cfg, data, NULL, NULL);
730
+ }
731
+
732
+ static void
733
+ replace_hoststr(char **orig, const char *replacement)
734
+ {
735
+ char *match;
736
+ char *newbuf;
737
+
738
+ if (!*orig) {
739
+ return;
740
+ }
741
+
742
+ match = strstr(*orig, "$HOST");
743
+ if (match == NULL || *match == '\0') {
744
+ return;
745
+ }
746
+
747
+ newbuf = malloc(strlen(*orig) + strlen(replacement));
748
+ *match = '\0';
749
+
750
+ /* copy until the placeholder */
751
+ strcpy(newbuf, *orig);
752
+ /* copy the host */
753
+ strcat(newbuf, replacement);
754
+ /* copy after the placeholder */
755
+ match += sizeof("$HOST")-1;
756
+ strcat(newbuf, match);
757
+ free(*orig);
758
+ *orig = newbuf;
759
+ }
760
+
761
+ LIBCOUCHBASE_API
762
+ void
763
+ lcbvb_replace_host(lcbvb_CONFIG *cfg, const char *hoststr)
764
+ {
765
+ unsigned ii, copy = 0;
766
+ char *replacement = (char *)hoststr;
767
+ if (strchr(replacement, ':')) {
768
+ size_t len = strlen(hoststr);
769
+ replacement = calloc(len + 2, sizeof(char));
770
+ replacement[0] = '[';
771
+ memcpy(replacement + 1, hoststr, len);
772
+ replacement[len + 1] = ']';
773
+ copy = 1;
774
+ }
775
+ for (ii = 0; ii < cfg->nsrv; ++ii) {
776
+ unsigned jj;
777
+ lcbvb_SERVER *srv = cfg->servers + ii;
778
+ lcbvb_SERVICES *svcs[] = { &srv->svc, &srv->svc_ssl };
779
+
780
+ replace_hoststr(&srv->hostname, hoststr);
781
+ for (jj = 0; jj < 2; ++jj) {
782
+ unsigned kk;
783
+ lcbvb_SERVICES *cursvc = svcs[jj];
784
+ replace_hoststr(&cursvc->views_base_, replacement);
785
+ for (kk = 0; kk < LCBVB_SVCTYPE__MAX; ++kk) {
786
+ replace_hoststr(&cursvc->hoststrs[kk], replacement);
787
+ }
788
+ }
789
+ /* reassign authority */
790
+ free(srv->authority);
791
+ srv->authority = strdup(srv->svc.hoststrs[LCBVB_SVCTYPE_DATA]);
792
+ }
793
+ if (copy) {
794
+ free(replacement);
795
+ }
796
+ if (cfg->dtype == LCBVB_DIST_KETAMA) {
797
+ update_ketama(cfg);
798
+ }
799
+ }
800
+
801
+ lcbvb_CONFIG *
802
+ lcbvb_parse_json(const char *js)
803
+ {
804
+ int rv;
805
+ lcbvb_CONFIG *cfg = calloc(1, sizeof(*cfg));
806
+ rv = lcbvb_load_json(cfg, js);
807
+ if (rv) {
808
+ lcbvb_destroy(cfg);
809
+ return NULL;
810
+ }
811
+ return cfg;
812
+ }
813
+
814
+ LIBCOUCHBASE_API
815
+ lcbvb_CONFIG *
816
+ lcbvb_create(void)
817
+ {
818
+ return calloc(1, sizeof(lcbvb_CONFIG));
819
+ }
820
+
821
+ static void
822
+ free_service_strs(lcbvb_SERVICES *svc)
823
+ {
824
+ unsigned ii;
825
+ for (ii = 0; ii < LCBVB_SVCTYPE__MAX; ii++) {
826
+ free(svc->hoststrs[ii]);
827
+ }
828
+ free(svc->views_base_);
829
+ free(svc->query_base_);
830
+ free(svc->fts_base_);
831
+ free(svc->cbas_base_);
832
+ }
833
+
834
+ void
835
+ lcbvb_destroy(lcbvb_CONFIG *conf)
836
+ {
837
+ unsigned ii;
838
+ for (ii = 0; ii < conf->nsrv; ii++) {
839
+ lcbvb_SERVER *srv = conf->servers + ii;
840
+ free(srv->hostname);
841
+ free(srv->viewpath);
842
+ free(srv->querypath);
843
+ free(srv->ftspath);
844
+ free(srv->cbaspath);
845
+ free_service_strs(&srv->svc);
846
+ free_service_strs(&srv->svc_ssl);
847
+ free(srv->authority);
848
+ free(srv->alt_hostname);
849
+ free_service_strs(&srv->alt_svc);
850
+ free_service_strs(&srv->alt_svc_ssl);
851
+ }
852
+ free(conf->servers);
853
+ free(conf->continuum);
854
+ free(conf->buuid);
855
+ free(conf->bname);
856
+ free(conf->vbuckets);
857
+ free(conf->ffvbuckets);
858
+ free(conf->randbuf);
859
+ free(conf);
860
+ }
861
+
862
+ static void
863
+ svcs_to_json(lcbvb_SERVICES *svc, cJSON *jsvc, int is_ssl)
864
+ {
865
+ cJSON *tmp;
866
+ const char *key;
867
+ #define EXTRACT_SERVICE(name, fld) \
868
+ if (svc->fld) { \
869
+ key = is_ssl ? name"SSL" : name; \
870
+ tmp = cJSON_CreateNumber(svc->fld); \
871
+ cJSON_AddItemToObject(jsvc, key, tmp); \
872
+ }
873
+
874
+ EXTRACT_SERVICE("mgmt", mgmt);
875
+ EXTRACT_SERVICE("capi", views);
876
+ EXTRACT_SERVICE("kv", data);
877
+ EXTRACT_SERVICE("n1ql", n1ql);
878
+ EXTRACT_SERVICE("indexScan", ixquery);
879
+ EXTRACT_SERVICE("indexAdmin", ixadmin);
880
+ EXTRACT_SERVICE("fts", fts);
881
+ EXTRACT_SERVICE("cbas", cbas);
882
+
883
+ #undef EXTRACT_SERVICE
884
+ }
885
+
886
+ LIBCOUCHBASE_API
887
+ char *
888
+ lcbvb_save_json(lcbvb_CONFIG *cfg)
889
+ {
890
+ unsigned ii;
891
+ char *ret;
892
+ cJSON *tmp = NULL, *nodes = NULL;
893
+ cJSON *root = cJSON_CreateObject();
894
+
895
+ if (cfg->dtype == LCBVB_DIST_VBUCKET) {
896
+ tmp = cJSON_CreateString("vbucket");
897
+ } else {
898
+ tmp = cJSON_CreateString("ketama");
899
+ }
900
+ cJSON_AddItemToObject(root, "nodeLocator", tmp);
901
+
902
+ if (cfg->buuid) {
903
+ tmp = cJSON_CreateString(cfg->buuid);
904
+ cJSON_AddItemToObject(root, "uuid", tmp);
905
+ }
906
+ if (cfg->revid > -1) {
907
+ tmp = cJSON_CreateNumber(cfg->revid);
908
+ cJSON_AddItemToObject(root, "rev", tmp);
909
+ }
910
+ tmp = cJSON_CreateString(cfg->bname);
911
+ cJSON_AddItemToObject(root, "name", tmp);
912
+
913
+ nodes = cJSON_CreateArray();
914
+ cJSON_AddItemToObject(root, "nodesExt", nodes);
915
+
916
+ for (ii = 0; ii < cfg->nsrv; ii++) {
917
+ cJSON *sj = cJSON_CreateObject(), *jsvc = cJSON_CreateObject();
918
+ lcbvb_SERVER *srv = cfg->servers + ii;
919
+
920
+ tmp = cJSON_CreateString(srv->hostname);
921
+ cJSON_AddItemToObject(sj, "hostname", tmp);
922
+ svcs_to_json(&srv->svc, jsvc, 0);
923
+ svcs_to_json(&srv->svc_ssl, jsvc, 1);
924
+
925
+ /* add the services to the server */
926
+ cJSON_AddItemToObject(sj, "services", jsvc);
927
+ cJSON_AddItemToArray(nodes, sj);
928
+ }
929
+
930
+ /* Now either add the vbucket or ketama stuff */
931
+ if (cfg->dtype == LCBVB_DIST_VBUCKET) {
932
+ cJSON *vbroot = cJSON_CreateObject();
933
+ cJSON *vbmap = cJSON_CreateArray();
934
+
935
+ tmp = cJSON_CreateNumber(cfg->nrepl);
936
+ cJSON_AddItemToObject(vbroot, "numReplicas", tmp);
937
+
938
+ for (ii = 0; ii < cfg->nvb; ii++) {
939
+ cJSON *curvb = cJSON_CreateIntArray(
940
+ cfg->vbuckets[ii].servers, cfg->nrepl+1);
941
+ cJSON_AddItemToArray(vbmap, curvb);
942
+ }
943
+
944
+ cJSON_AddItemToObject(vbroot, "vBucketMap", vbmap);
945
+ cJSON_AddItemToObject(root, "vBucketServerMap", vbroot);
946
+ }
947
+
948
+ ret = cJSON_PrintUnformatted(root);
949
+ cJSON_Delete(root);
950
+ return ret;
951
+ }
952
+
953
+ /******************************************************************************
954
+ ******************************************************************************
955
+ ** Mapping Routines **
956
+ ******************************************************************************
957
+ ******************************************************************************/
958
+
959
+ static int
960
+ map_ketama(lcbvb_CONFIG *cfg, const void *key, size_t nkey)
961
+ {
962
+ uint32_t digest, mid, prev;
963
+ lcbvb_CONTINUUM *beginp, *endp, *midp, *highp, *lowp;
964
+ assert(cfg->continuum);
965
+ digest = vb__hash_ketama(key, nkey);
966
+ beginp = lowp = cfg->continuum;
967
+ endp = highp = cfg->continuum + cfg->ncontinuum;
968
+
969
+ /* divide and conquer array search to find server with next biggest
970
+ * point after what this key hashes to */
971
+ while (1)
972
+ {
973
+ /* pick the middle point */
974
+ midp = lowp + (highp - lowp) / 2;
975
+
976
+ if (midp == endp) {
977
+ /* if at the end, roll back to zeroth */
978
+ return beginp->index;
979
+ break;
980
+ }
981
+
982
+ mid = midp->point;
983
+ prev = (midp == beginp) ? 0 : (midp-1)->point;
984
+
985
+ if (digest <= mid && digest > prev) {
986
+ /* we found nearest server */
987
+ return midp->index;
988
+ break;
989
+ }
990
+
991
+ /* adjust the limits */
992
+ if (mid < digest) {
993
+ lowp = midp + 1;
994
+ } else {
995
+ highp = midp - 1;
996
+ }
997
+
998
+ if (lowp > highp) {
999
+ return beginp->index;
1000
+ break;
1001
+ }
1002
+ }
1003
+ return -1;
1004
+ }
1005
+
1006
+ int
1007
+ lcbvb_k2vb(lcbvb_CONFIG *cfg, const void *k, lcb_SIZE n)
1008
+ {
1009
+ uint32_t digest = hash_crc32(k, n);
1010
+ return digest % cfg->nvb;
1011
+ }
1012
+
1013
+ int
1014
+ lcbvb_vbmaster(lcbvb_CONFIG *cfg, int vbid)
1015
+ {
1016
+ return cfg->vbuckets[vbid].servers[0];
1017
+ }
1018
+
1019
+ int
1020
+ lcbvb_vbreplica(lcbvb_CONFIG *cfg, int vbid, unsigned ix)
1021
+ {
1022
+ if (ix < cfg->nrepl) {
1023
+ return cfg->vbuckets[vbid].servers[ix+1];
1024
+ } else {
1025
+ return -1;
1026
+ }
1027
+ }
1028
+
1029
+ /*
1030
+ * (https://www.couchbase.com/issues/browse/MB-12268?focusedCommentId=101894&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-101894)
1031
+ *
1032
+ * So (from my possibly partially ignorant view of that matter) I'd do the following:
1033
+ *
1034
+ * 1) Send first request according to lated vbucket map you have.
1035
+ * If it works, we're good. Exit.
1036
+ *
1037
+ * 2) if that fails, look if you've newer vbucket map. If there's newer vbucket map
1038
+ * and it points to _different_ node, send request to that node and proceed
1039
+ * to step 3. Otherwise go to step 4
1040
+ *
1041
+ * 3) if newer node still gives you not-my-vbucket, go to step 4
1042
+ *
1043
+ * 4) if there's fast forward map in latest bucket info and fast forward map
1044
+ * points to different node, send request to that node. And go to step 5.
1045
+ * Otherwise (not ff map or it points to one of nodes you've tried already),
1046
+ * go to step 6
1047
+ *
1048
+ * 5) if ff map node request succeeds. Exit. Otherwise go to step 6.
1049
+ *
1050
+ * 6) Try first replica unless it's one of nodes you've already tried.
1051
+ * If it succeeds. Exit. Otherwise go to step 7.
1052
+ *
1053
+ * 7) Try all nodes in turn, prioritizing other replicas to beginning of list
1054
+ * and nodes you have already tried to end. If one of nodes agrees to perform
1055
+ * your request. Exit. Otherwise propagate error to back to app
1056
+ */
1057
+ int
1058
+ lcbvb_nmv_remap_ex(lcbvb_CONFIG *cfg, int vbid, int bad, int heuristic)
1059
+ {
1060
+ int cur = cfg->vbuckets[vbid].servers[0];
1061
+ int rv = cur;
1062
+ unsigned ii;
1063
+
1064
+ if (bad != cur) {
1065
+ return cur;
1066
+ }
1067
+
1068
+ /* if a forward table exists, then return the vbucket id from the forward table
1069
+ * and update that information in the current table. We also need to Update the
1070
+ * replica information for that vbucket */
1071
+
1072
+ if (cfg->ffvbuckets &&
1073
+ (rv = cfg->ffvbuckets[vbid].servers[0]) != bad && rv > -1) {
1074
+ memcpy(&cfg->vbuckets[vbid], &cfg->ffvbuckets[vbid], sizeof (lcbvb_VBUCKET));
1075
+ }
1076
+
1077
+ /* this path is usually only followed if fvbuckets is not present */
1078
+ if (heuristic && cur == bad) {
1079
+ int validrv = -1;
1080
+ for (ii = 0; ii < cfg->ndatasrv; ii++) {
1081
+ rv = (rv + 1) % cfg->ndatasrv;
1082
+ /* check that the new index has assigned vbuckets (master or replica) */
1083
+ if (cfg->servers[rv].nvbs) {
1084
+ validrv = rv;
1085
+ cfg->vbuckets[vbid].servers[0] = rv;
1086
+ break;
1087
+ }
1088
+ }
1089
+
1090
+ if (validrv == -1) {
1091
+ /* this should happen when there is only one valid node remaining
1092
+ * in the cluster, and we've removed serveral other nodes that are
1093
+ * still present in the map due to the grace period window.*/
1094
+ return -1;
1095
+ }
1096
+ }
1097
+
1098
+ if (rv == bad) {
1099
+ return -1;
1100
+ }
1101
+
1102
+ return rv;
1103
+ }
1104
+
1105
+
1106
+ int
1107
+ lcbvb_map_key(lcbvb_CONFIG *cfg, const void *key, lcb_SIZE nkey,
1108
+ int *vbid, int *srvix)
1109
+ {
1110
+ if (cfg->dtype == LCBVB_DIST_KETAMA) {
1111
+ *srvix = map_ketama(cfg, key, nkey);
1112
+ *vbid = 0;
1113
+ return 0;
1114
+ } else {
1115
+ *vbid = lcbvb_k2vb(cfg, key, nkey);
1116
+ *srvix = lcbvb_vbmaster(cfg, *vbid);
1117
+ }
1118
+ return 0;
1119
+ }
1120
+
1121
+ int
1122
+ lcbvb_has_vbucket(lcbvb_CONFIG *vbc, int vbid, int ix)
1123
+ {
1124
+ unsigned ii;
1125
+ lcbvb_VBUCKET *vb = & vbc->vbuckets[vbid];
1126
+ for (ii = 0; ii < vbc->nrepl+1; ii++) {
1127
+ if (vb->servers[ii] == ix) {
1128
+ return 1;
1129
+ }
1130
+ }
1131
+ return 0;
1132
+ }
1133
+
1134
+ /******************************************************************************
1135
+ ******************************************************************************
1136
+ ** Configuration Comparisons/Diffs **
1137
+ ******************************************************************************
1138
+ ******************************************************************************/
1139
+ static void
1140
+ compute_vb_list_diff(lcbvb_CONFIG *from, lcbvb_CONFIG *to, char **out)
1141
+ {
1142
+ int offset = 0;
1143
+ unsigned ii, jj;
1144
+
1145
+ for (ii = 0; ii < to->nsrv; ii++) {
1146
+ int found = 0;
1147
+ lcbvb_SERVER *newsrv = to->servers + ii;
1148
+ for (jj = 0; !found && jj < from->nsrv; jj++) {
1149
+ lcbvb_SERVER *oldsrv = from->servers + jj;
1150
+ found |= (strcmp(newsrv->authority, oldsrv->authority) == 0);
1151
+ }
1152
+ if (!found) {
1153
+ char *infostr = malloc(strlen(newsrv->authority) + 128);
1154
+ assert(infostr);
1155
+ sprintf(infostr, "%s(Data=%d, Index=%d, Query=%d)",
1156
+ newsrv->authority,
1157
+ newsrv->svc.data, newsrv->svc.n1ql, newsrv->svc.ixquery);
1158
+ out[offset] = infostr;
1159
+ ++offset;
1160
+ }
1161
+ }
1162
+ }
1163
+
1164
+ lcbvb_CONFIGDIFF *
1165
+ lcbvb_compare(lcbvb_CONFIG *from, lcbvb_CONFIG *to)
1166
+ {
1167
+ int nservers;
1168
+ lcbvb_CONFIGDIFF *ret;
1169
+ unsigned ii;
1170
+
1171
+ ret = calloc(1, sizeof(*ret));
1172
+ nservers = (from->nsrv > to->nsrv ? from->nsrv : to->nsrv) + 1;
1173
+ ret->servers_added = calloc(nservers, sizeof(*ret->servers_added));
1174
+ ret->servers_removed = calloc(nservers, sizeof(*ret->servers_removed));
1175
+ compute_vb_list_diff(from, to, ret->servers_added);
1176
+ compute_vb_list_diff(to, from, ret->servers_removed);
1177
+
1178
+ if (to->nsrv == from->nsrv) {
1179
+ for (ii = 0; ii < from->nsrv; ii++) {
1180
+ const char *sa, *sb;
1181
+ sa = from->servers[ii].authority;
1182
+ sb = to->servers[ii].authority;
1183
+ ret->sequence_changed |= (0 != strcmp(sa, sb));
1184
+ }
1185
+ } else {
1186
+ ret->sequence_changed = 1;
1187
+ }
1188
+
1189
+ if (from->nvb == to->nvb) {
1190
+ for (ii = 0; ii < from->nvb; ii++) {
1191
+ lcbvb_VBUCKET *vba = from->vbuckets + ii, *vbb = to->vbuckets + ii;
1192
+ if (vba->servers[0] != vbb->servers[0]) {
1193
+ ret->n_vb_changes++;
1194
+ }
1195
+ }
1196
+ } else {
1197
+ ret->n_vb_changes = -1;
1198
+ }
1199
+ return ret;
1200
+ }
1201
+
1202
+ static void
1203
+ free_array_helper(char **l)
1204
+ {
1205
+ int ii;
1206
+ for (ii = 0; l[ii]; ii++) {
1207
+ free(l[ii]);
1208
+ }
1209
+ free(l);
1210
+ }
1211
+
1212
+ void
1213
+ lcbvb_free_diff(lcbvb_CONFIGDIFF *diff) {
1214
+ assert(diff);
1215
+ free_array_helper(diff->servers_added);
1216
+ free_array_helper(diff->servers_removed);
1217
+ free(diff);
1218
+ }
1219
+
1220
+
1221
+ lcbvb_CHANGETYPE
1222
+ lcbvb_get_changetype(lcbvb_CONFIGDIFF *diff)
1223
+ {
1224
+ lcbvb_CHANGETYPE ret = 0;
1225
+ if (diff->n_vb_changes) {
1226
+ ret |= LCBVB_MAP_MODIFIED;
1227
+ }
1228
+ if (*diff->servers_added || *diff->servers_removed || diff->sequence_changed) {
1229
+ ret |= LCBVB_SERVERS_MODIFIED;
1230
+ }
1231
+ return ret;
1232
+ }
1233
+
1234
+ /******************************************************************************
1235
+ ******************************************************************************
1236
+ ** String/Port Getters **
1237
+ ******************************************************************************
1238
+ ******************************************************************************/
1239
+
1240
+ static const lcbvb_SERVICES *
1241
+ get_svc(const lcbvb_SERVER *srv, lcbvb_SVCMODE mode)
1242
+ {
1243
+ if (srv->alt_hostname) {
1244
+ if (mode == LCBVB_SVCMODE_PLAIN) {
1245
+ return &srv->alt_svc;
1246
+ } else {
1247
+ return &srv->alt_svc_ssl;
1248
+ }
1249
+ } else {
1250
+ if (mode == LCBVB_SVCMODE_PLAIN) {
1251
+ return &srv->svc;
1252
+ } else {
1253
+ return &srv->svc_ssl;
1254
+ }
1255
+ }
1256
+ }
1257
+
1258
+ static const char *
1259
+ get_hostname(const lcbvb_SERVER *srv)
1260
+ {
1261
+ if (srv->alt_hostname) {
1262
+ return srv->alt_hostname;
1263
+ } else {
1264
+ return srv->hostname;
1265
+ }
1266
+ }
1267
+
1268
+ LIBCOUCHBASE_API
1269
+ unsigned
1270
+ lcbvb_get_port(lcbvb_CONFIG *cfg,
1271
+ unsigned ix, lcbvb_SVCTYPE type, lcbvb_SVCMODE mode)
1272
+ {
1273
+ const lcbvb_SERVICES *svc;
1274
+ lcbvb_SERVER *srv;
1275
+ if (type >= LCBVB_SVCTYPE__MAX || mode >= LCBVB_SVCMODE__MAX) {
1276
+ return 0;
1277
+ }
1278
+ if (ix >= cfg->nsrv) {
1279
+ return 0;
1280
+ }
1281
+
1282
+ srv = cfg->servers + ix;
1283
+ svc = get_svc(srv, mode);
1284
+
1285
+ if (type == LCBVB_SVCTYPE_DATA) {
1286
+ return svc->data;
1287
+ } else if (type == LCBVB_SVCTYPE_MGMT) {
1288
+ return svc->mgmt;
1289
+ } else if (type == LCBVB_SVCTYPE_VIEWS) {
1290
+ return svc->views;
1291
+ } else if (type == LCBVB_SVCTYPE_IXADMIN) {
1292
+ return svc->ixadmin;
1293
+ } else if (type == LCBVB_SVCTYPE_IXQUERY) {
1294
+ return svc->ixquery;
1295
+ } else if (type == LCBVB_SVCTYPE_N1QL) {
1296
+ return svc->n1ql;
1297
+ } else if (type == LCBVB_SVCTYPE_FTS) {
1298
+ return svc->fts;
1299
+ } else if (type == LCBVB_SVCTYPE_CBAS) {
1300
+ return svc->cbas;
1301
+ } else {
1302
+ return 0;
1303
+ }
1304
+ }
1305
+
1306
+ LIBCOUCHBASE_API
1307
+ const char *
1308
+ lcbvb_get_hostport(lcbvb_CONFIG *cfg,
1309
+ unsigned ix, lcbvb_SVCTYPE type, lcbvb_SVCMODE mode)
1310
+ {
1311
+ char **strp;
1312
+ lcbvb_SERVER *srv;
1313
+ lcbvb_SERVICES *svc;
1314
+ unsigned port = lcbvb_get_port(cfg, ix, type, mode);
1315
+
1316
+ if (!port) {
1317
+ return NULL;
1318
+ }
1319
+
1320
+ srv = cfg->servers + ix;
1321
+ svc = (lcbvb_SERVICES *)get_svc(srv, mode);
1322
+
1323
+ strp = &svc->hoststrs[type];
1324
+ if (*strp == NULL) {
1325
+ size_t strn = strlen(srv->hostname) + 20;
1326
+ *strp = calloc(strn, sizeof(char));
1327
+ copy_address(*strp, strn, get_hostname(srv), port);
1328
+ }
1329
+ return *strp;
1330
+ }
1331
+
1332
+ LIBCOUCHBASE_API
1333
+ const char *
1334
+ lcbvb_get_hostname(const lcbvb_CONFIG *cfg, unsigned ix)
1335
+ {
1336
+ if (cfg->nsrv > ix) {
1337
+ return get_hostname(cfg->servers + ix);
1338
+ } else {
1339
+ return NULL;
1340
+ }
1341
+ }
1342
+
1343
+ LIBCOUCHBASE_API
1344
+ int
1345
+ lcbvb_get_randhost_ex(const lcbvb_CONFIG *cfg,
1346
+ lcbvb_SVCTYPE type, lcbvb_SVCMODE mode, int *used)
1347
+ {
1348
+ size_t nn, oix = 0;
1349
+
1350
+ /*
1351
+ * Since not all nodes support all service types, we need to make it a
1352
+ * fair selection by pre-filtering the nodes which actually support the
1353
+ * service, and then proceed to actually select a suitable node.
1354
+ */
1355
+ for (nn = 0; nn < cfg->nsrv; nn++) {
1356
+ const lcbvb_SERVER *server = cfg->servers + nn;
1357
+ const lcbvb_SERVICES *svcs = get_svc(server, mode);
1358
+ int has_svc = 0;
1359
+
1360
+ // Check if this node is in the exclude list
1361
+ if (used && used[nn]) {
1362
+ continue;
1363
+ }
1364
+
1365
+ has_svc =
1366
+ (type == LCBVB_SVCTYPE_DATA && svcs->data) ||
1367
+ (type == LCBVB_SVCTYPE_IXADMIN && svcs->ixadmin) ||
1368
+ (type == LCBVB_SVCTYPE_IXQUERY && svcs->ixquery) ||
1369
+ (type == LCBVB_SVCTYPE_MGMT && svcs->mgmt) ||
1370
+ (type == LCBVB_SVCTYPE_N1QL && svcs->n1ql) ||
1371
+ (type == LCBVB_SVCTYPE_FTS && svcs->fts) ||
1372
+ (type == LCBVB_SVCTYPE_VIEWS && svcs->views) ||
1373
+ (type == LCBVB_SVCTYPE_CBAS && svcs->cbas);
1374
+
1375
+ if (has_svc) {
1376
+ cfg->randbuf[oix++] = (int)nn;
1377
+ }
1378
+ }
1379
+
1380
+ if (!oix) {
1381
+ /* nothing supports it! */
1382
+ return -1;
1383
+ }
1384
+
1385
+ nn = rand();
1386
+ nn %= oix;
1387
+ return cfg->randbuf[nn];
1388
+ }
1389
+
1390
+ LIBCOUCHBASE_API
1391
+ int
1392
+ lcbvb_get_randhost(const lcbvb_CONFIG *cfg,
1393
+ lcbvb_SVCTYPE type, lcbvb_SVCMODE mode)
1394
+ {
1395
+ return lcbvb_get_randhost_ex(cfg, type, mode, NULL);
1396
+ }
1397
+
1398
+ LIBCOUCHBASE_API
1399
+ const char *
1400
+ lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix,
1401
+ lcbvb_SVCTYPE svc, lcbvb_SVCMODE mode)
1402
+ {
1403
+ char **strp;
1404
+ const char *prefix;
1405
+ const char *path;
1406
+
1407
+ lcbvb_SERVER *srv;
1408
+ lcbvb_SERVICES *svcs;
1409
+ unsigned port;
1410
+ port = lcbvb_get_port(cfg, ix, svc, mode);
1411
+ if (!port) {
1412
+ return NULL;
1413
+ }
1414
+
1415
+ srv = cfg->servers + ix;
1416
+ if (mode == LCBVB_SVCMODE_PLAIN) {
1417
+ prefix = "http";
1418
+ } else {
1419
+ prefix = "https";
1420
+ }
1421
+ svcs = (lcbvb_SERVICES *)get_svc(srv, mode);
1422
+
1423
+ if (svc == LCBVB_SVCTYPE_VIEWS) {
1424
+ path = srv->viewpath;
1425
+ strp = &svcs->views_base_;
1426
+ } else if (svc == LCBVB_SVCTYPE_N1QL) {
1427
+ path = srv->querypath;
1428
+ strp = &svcs->query_base_;
1429
+ } else if (svc == LCBVB_SVCTYPE_FTS) {
1430
+ path = srv->ftspath;
1431
+ strp = &svcs->fts_base_;
1432
+ } else if (svc == LCBVB_SVCTYPE_CBAS) {
1433
+ path = srv->cbaspath;
1434
+ strp = &svcs->cbas_base_;
1435
+ } else {
1436
+ /* Unknown service! */
1437
+ return NULL;
1438
+ }
1439
+
1440
+ if (path == NULL) {
1441
+ return NULL;
1442
+ } else if (!*strp) {
1443
+ char buf[4096];
1444
+ const char *hostname = get_hostname(srv);
1445
+ if (strchr(hostname, ':')) {
1446
+ // IPv6 and should be bracketed
1447
+ snprintf(buf, sizeof(buf), "%s://[%s]:%d%s", prefix, hostname, port, path);
1448
+ } else {
1449
+ snprintf(buf, sizeof(buf), "%s://%s:%d%s", prefix, hostname, port, path);
1450
+ }
1451
+ *strp = strdup(buf);
1452
+ }
1453
+
1454
+ return *strp;
1455
+ }
1456
+
1457
+ LIBCOUCHBASE_API
1458
+ const char *
1459
+ lcbvb_get_capibase(lcbvb_CONFIG *cfg, unsigned ix, lcbvb_SVCMODE mode)
1460
+ {
1461
+ return lcbvb_get_resturl(cfg, ix, LCBVB_SVCTYPE_VIEWS, mode);
1462
+ }
1463
+
1464
+ LIBCOUCHBASE_API int lcbvb_get_revision(const lcbvb_CONFIG *cfg) {
1465
+ return cfg->revid;
1466
+ }
1467
+ LIBCOUCHBASE_API unsigned lcbvb_get_nservers(const lcbvb_CONFIG *cfg) {
1468
+ return cfg->nsrv;
1469
+ }
1470
+ LIBCOUCHBASE_API unsigned lcbvb_get_nreplicas(const lcbvb_CONFIG *cfg) {
1471
+ return cfg->nrepl;
1472
+ }
1473
+ LIBCOUCHBASE_API lcbvb_DISTMODE lcbvb_get_distmode(const lcbvb_CONFIG *cfg) {
1474
+ return cfg->dtype;
1475
+ }
1476
+ LIBCOUCHBASE_API const char *lcbvb_get_error(const lcbvb_CONFIG *cfg) {
1477
+ return cfg->errstr;
1478
+ }
1479
+ /******************************************************************************
1480
+ ******************************************************************************
1481
+ ** Generation Functions **
1482
+ ******************************************************************************
1483
+ ******************************************************************************/
1484
+
1485
+ static void copy_service(const char *hostname, const lcbvb_SERVICES *src, lcbvb_SERVICES *dst)
1486
+ {
1487
+ *dst = *src;
1488
+ memset(&dst->hoststrs, 0, sizeof dst->hoststrs);
1489
+ if (src->views_base_) {
1490
+ dst->views_base_ = strdup(src->views_base_);
1491
+ }
1492
+ if (src->query_base_) {
1493
+ dst->query_base_ = strdup(src->query_base_);
1494
+ }
1495
+ if (src->fts_base_) {
1496
+ dst->fts_base_ = strdup(src->fts_base_);
1497
+ }
1498
+ if (src->cbas_base_) {
1499
+ dst->cbas_base_ = strdup(src->cbas_base_);
1500
+ }
1501
+ if (dst->data) {
1502
+ char buf[4096];
1503
+ copy_address(buf, sizeof(buf), hostname, dst->data);
1504
+ dst->hoststrs[LCBVB_SVCTYPE_DATA] = strdup(buf);
1505
+ }
1506
+ }
1507
+
1508
+ LIBCOUCHBASE_API
1509
+ int
1510
+ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
1511
+ const char *name, const char *uuid,
1512
+ const lcbvb_SERVER *servers,
1513
+ unsigned nservers, unsigned nreplica, unsigned nvbuckets)
1514
+ {
1515
+ unsigned ii, jj;
1516
+ int srvix = 0, in_nondata = 0;
1517
+
1518
+ assert(nservers);
1519
+
1520
+ if (!name) {
1521
+ name = "default";
1522
+ }
1523
+
1524
+ memset(vb, 0, sizeof(*vb));
1525
+ vb->dtype = LCBVB_DIST_VBUCKET;
1526
+ vb->nvb = nvbuckets;
1527
+ vb->nrepl = nreplica;
1528
+ vb->nsrv = nservers;
1529
+ vb->bname = strdup(name);
1530
+ if (uuid) {
1531
+ vb->buuid = strdup(uuid);
1532
+ }
1533
+
1534
+ if (nreplica >= nservers) {
1535
+ vb->errstr = "nservers must be > nreplicas";
1536
+ return -1;
1537
+ }
1538
+
1539
+ if (nreplica > 4) {
1540
+ vb->errstr = "Replicas must be <= 4";
1541
+ return -1;
1542
+ }
1543
+
1544
+ /* Count the number of data servers.. */
1545
+ for (ii = 0; ii < nservers; ii++) {
1546
+ const lcbvb_SERVER *server = servers + ii;
1547
+ if (server->svc.data) {
1548
+ if (in_nondata) {
1549
+ vb->errstr = "All data servers must be specified before non-data servers";
1550
+ return -1;
1551
+ }
1552
+ vb->ndatasrv++;
1553
+ } else {
1554
+ in_nondata = 1;
1555
+ }
1556
+ }
1557
+
1558
+ if (vb->nvb) {
1559
+ vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
1560
+ if (!vb->vbuckets) {
1561
+ vb->errstr = "Couldn't allocate vbucket array";
1562
+ return -1;
1563
+ }
1564
+ }
1565
+
1566
+ for (ii = 0; ii < vb->nvb; ii++) {
1567
+ lcbvb_VBUCKET *cur = vb->vbuckets + ii;
1568
+ cur->servers[0] = srvix;
1569
+ for (jj = 1; jj < vb->nrepl+1; jj++) {
1570
+ cur->servers[jj] = (srvix + jj) % vb->ndatasrv;
1571
+ }
1572
+ srvix = (srvix + 1) % vb->ndatasrv;
1573
+ }
1574
+
1575
+ vb->servers = calloc(vb->nsrv, sizeof(*vb->servers));
1576
+ vb->randbuf = calloc(vb->nsrv, sizeof(*vb->randbuf));
1577
+
1578
+ for (ii = 0; ii < vb->nsrv; ii++) {
1579
+ lcbvb_SERVER *dst = vb->servers + ii;
1580
+ const lcbvb_SERVER *src = servers + ii;
1581
+
1582
+ *dst = *src;
1583
+ dst->hostname = strdup(src->hostname);
1584
+ if (src->viewpath) {
1585
+ dst->viewpath = strdup(src->viewpath);
1586
+ }
1587
+ if (src->querypath) {
1588
+ dst->querypath = strdup(src->querypath);
1589
+ }
1590
+ if (src->ftspath) {
1591
+ dst->ftspath = strdup(src->ftspath);
1592
+ }
1593
+ if (src->cbaspath) {
1594
+ dst->cbaspath = strdup(src->cbaspath);
1595
+ }
1596
+
1597
+ copy_service(src->hostname, &src->svc, &dst->svc);
1598
+ copy_service(src->hostname, &src->svc_ssl, &dst->svc_ssl);
1599
+ {
1600
+ char tmpbuf[MAX_AUTHORITY_SIZE] = {0};
1601
+ copy_address(tmpbuf, sizeof(tmpbuf), dst->hostname, dst->svc.data);
1602
+ dst->authority = strdup(tmpbuf);
1603
+ }
1604
+ }
1605
+
1606
+ for (ii = 0; ii < vb->nvb; ii++) {
1607
+ for (jj = 0; jj < vb->nrepl+1; jj++) {
1608
+ int ix = vb->vbuckets[ii].servers[jj];
1609
+ if (ix >= 0) {
1610
+ vb->servers[ix].nvbs++;
1611
+ }
1612
+ }
1613
+ }
1614
+ return 0;
1615
+ }
1616
+
1617
+ int
1618
+ lcbvb_genconfig(lcbvb_CONFIG *vb,
1619
+ unsigned nservers, unsigned nreplica, unsigned nvbuckets)
1620
+ {
1621
+ unsigned ii;
1622
+ int rv;
1623
+ lcbvb_SERVER *srvarry;
1624
+
1625
+ srvarry = calloc(nservers, sizeof(*srvarry));
1626
+ for (ii = 0; ii < nservers; ii++) {
1627
+ srvarry[ii].svc.data = 1000 + ii;
1628
+ srvarry[ii].svc.views = 2000 + ii;
1629
+ srvarry[ii].svc.mgmt = 3000 + ii;
1630
+ srvarry[ii].hostname = "localhost";
1631
+ srvarry[ii].svc.views_base_ = "/default";
1632
+ }
1633
+ rv = lcbvb_genconfig_ex(vb,
1634
+ "default", NULL, srvarry, nservers, nreplica, nvbuckets);
1635
+ free(srvarry);
1636
+ return rv;
1637
+ }
1638
+
1639
+ void
1640
+ lcbvb_genffmap(lcbvb_CONFIG *cfg)
1641
+ {
1642
+ size_t ii;
1643
+ assert(cfg->nrepl);
1644
+ if (cfg->ffvbuckets) {
1645
+ free(cfg->ffvbuckets);
1646
+ }
1647
+ cfg->ffvbuckets = calloc(cfg->nvb, sizeof *cfg->ffvbuckets);
1648
+ for (ii = 0; ii < cfg->nvb; ++ii) {
1649
+ size_t jj;
1650
+ lcbvb_VBUCKET *vb = cfg->ffvbuckets + ii;
1651
+ memcpy(vb, cfg->vbuckets + ii, sizeof *vb);
1652
+ for (jj = 0; jj < cfg->ndatasrv; ++jj) {
1653
+ vb->servers[jj] = (vb->servers[jj] + 1) % cfg->ndatasrv;
1654
+ }
1655
+ }
1656
+ }
1657
+
1658
+ void
1659
+ lcbvb_make_ketama(lcbvb_CONFIG *vb)
1660
+ {
1661
+ if (vb->dtype == LCBVB_DIST_KETAMA) {
1662
+ return;
1663
+ }
1664
+ vb->dtype = LCBVB_DIST_KETAMA;
1665
+ vb->nrepl = 0;
1666
+ vb->nvb = 0;
1667
+ update_ketama(vb);
1668
+ }
1669
+
1670
+
1671
+ /******************************************************************************
1672
+ ******************************************************************************
1673
+ ** Compatibility APIs **
1674
+ ******************************************************************************
1675
+ ******************************************************************************/
1676
+ LIBCOUCHBASE_API lcbvb_CONFIG* vbucket_config_create(void) {
1677
+ return lcbvb_create();
1678
+ }
1679
+ LIBCOUCHBASE_API void vbucket_config_destroy(lcbvb_CONFIG*h) {
1680
+ lcbvb_destroy(h);
1681
+ }
1682
+ LIBCOUCHBASE_API int vbucket_config_parse(lcbvb_CONFIG*h, vbucket_source_t src, const char *s) {
1683
+ (void)src; return lcbvb_load_json(h, s);
1684
+ }
1685
+ LIBCOUCHBASE_API const char * vbucket_get_error_message(lcbvb_CONFIG*h) {
1686
+ return h->errstr;
1687
+ }
1688
+ LIBCOUCHBASE_API int vbucket_config_get_num_servers(lcbvb_CONFIG *cfg) {
1689
+ return cfg->nsrv;
1690
+ }
1691
+ LIBCOUCHBASE_API int vbucket_config_get_num_replicas(lcbvb_CONFIG *cfg) {
1692
+ return cfg->nrepl;
1693
+ }
1694
+ LIBCOUCHBASE_API int vbucket_config_get_num_vbuckets(lcbvb_CONFIG *cfg) {
1695
+ return cfg->nvb;
1696
+ }
1697
+ LIBCOUCHBASE_API const char *vbucket_config_get_server(lcbvb_CONFIG *cfg, int ix) {
1698
+ return lcbvb_get_hostport(cfg, ix, LCBVB_SVCTYPE_DATA, LCBVB_SVCMODE_PLAIN);
1699
+ }
1700
+ LIBCOUCHBASE_API const char *vbucket_config_get_rest_api_server(lcbvb_CONFIG *cfg, int ix) {
1701
+ return lcbvb_get_hostport(cfg, ix, LCBVB_SVCTYPE_MGMT, LCBVB_SVCMODE_PLAIN);
1702
+ }
1703
+ LIBCOUCHBASE_API const char *vbucket_config_get_couch_api_base(lcbvb_CONFIG *cfg, int ix) {
1704
+ return lcbvb_get_capibase(cfg, ix, LCBVB_SVCMODE_PLAIN);
1705
+ }
1706
+ LIBCOUCHBASE_API lcbvb_DISTMODE vbucket_config_get_distribution_type(lcbvb_CONFIG *cfg) {
1707
+ return cfg->dtype;
1708
+ }
1709
+ LIBCOUCHBASE_API int vbucket_map(lcbvb_CONFIG *cfg, const void *k, lcb_SIZE nk, int *pvb, int *pix) {
1710
+ return lcbvb_map_key(cfg, k, nk, pvb, pix);
1711
+ }
1712
+ LIBCOUCHBASE_API int vbucket_get_vbucket_by_key(lcbvb_CONFIG *cfg, const void *k, lcb_SIZE nk) {
1713
+ return lcbvb_k2vb(cfg, k, nk);
1714
+ }
1715
+ LIBCOUCHBASE_API int vbucket_get_master(lcbvb_CONFIG *cfg, int vb) {
1716
+ return lcbvb_vbmaster(cfg, vb);
1717
+ }
1718
+ LIBCOUCHBASE_API int vbucket_get_replica(lcbvb_CONFIG *cfg, int vb, int repl) {
1719
+ return lcbvb_vbreplica(cfg, vb, repl);
1720
+ }
1721
+ LIBCOUCHBASE_API lcbvb_CONFIGDIFF *vbucket_compare(lcbvb_CONFIG*a,lcbvb_CONFIG*b) {
1722
+ return lcbvb_compare(a,b);
1723
+ }
1724
+ LIBCOUCHBASE_API void vbucket_free_diff(lcbvb_CONFIGDIFF *p) {
1725
+ lcbvb_free_diff(p);
1726
+ }
1727
+ LIBCOUCHBASE_API int vbucket_config_get_revision(lcbvb_CONFIG *p) {
1728
+ return lcbvb_get_revision(p);
1729
+ }
1730
+ LIBCOUCHBASE_API lcbvb_CHANGETYPE vbucket_what_changed(lcbvb_CONFIGDIFF *diff) {
1731
+ return lcbvb_get_changetype(diff);
1732
+ }
1733
+ LIBCOUCHBASE_API int vbucket_config_generate(lcbvb_CONFIG*cfg, unsigned nsrv, unsigned nrepl, unsigned nvb) {
1734
+ return lcbvb_genconfig(cfg,nsrv,nrepl,nvb);
1735
+ }