/src/cc/Hyperspace/Protocol.cc

https://github.com/ak2consulting/hypertable · C++ · 342 lines · 251 code · 46 blank · 45 comment · 5 complexity · 2fa95bb4e9c5b4db0d6863b5cd3db9b5 MD5 · raw file

  1. /**
  2. * Copyright (C) 2007 Doug Judd (Zvents, Inc.)
  3. *
  4. * This file is part of Hypertable.
  5. *
  6. * Hypertable is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * Hypertable is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19. * 02110-1301, USA.
  20. */
  21. #include "Common/Compat.h"
  22. #include <cassert>
  23. #include <iostream>
  24. #include "Common/Error.h"
  25. #include "Common/Serialization.h"
  26. #include "Common/StringExt.h"
  27. #include "AsyncComm/CommHeader.h"
  28. #include "Protocol.h"
  29. using namespace std;
  30. using namespace Hyperspace;
  31. using namespace Hypertable;
  32. using namespace Serialization;
  33. const char *Hyperspace::Protocol::command_strs[COMMAND_MAX] = {
  34. "keepalive",
  35. "handshake",
  36. "open",
  37. "stat",
  38. "cancel",
  39. "close",
  40. "poison",
  41. "mkdir",
  42. "attrset",
  43. "attrget",
  44. "attrincr",
  45. "attrdel",
  46. "attrlist",
  47. "attrexists",
  48. "exists",
  49. "delete",
  50. "readdir",
  51. "readdirattr",
  52. "readpathattr",
  53. "lock",
  54. "release",
  55. "checksequencer",
  56. "status"
  57. };
  58. /**
  59. *
  60. */
  61. const char *Hyperspace::Protocol::command_text(uint64_t command) {
  62. if (command < 0 || command >= COMMAND_MAX)
  63. return "UNKNOWN";
  64. return command_strs[command];
  65. }
  66. /**
  67. *
  68. */
  69. CommBuf *
  70. Hyperspace::Protocol::create_client_keepalive_request(uint64_t session_id,
  71. uint64_t last_known_event, bool shutdown) {
  72. CommHeader header(COMMAND_KEEPALIVE);
  73. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  74. CommBuf *cbuf = new CommBuf(header, 17);
  75. cbuf->append_i64(session_id);
  76. cbuf->append_i64(last_known_event);
  77. cbuf->append_bool(shutdown);
  78. return cbuf;
  79. }
  80. /**
  81. *
  82. */
  83. CommBuf *
  84. Hyperspace::Protocol::create_server_keepalive_request(uint64_t session_id,
  85. int error) {
  86. CommHeader header(COMMAND_KEEPALIVE);
  87. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  88. CommBuf *cbuf = new CommBuf(header, 16);
  89. cbuf->append_i64(session_id);
  90. cbuf->append_i32(error);
  91. cbuf->append_i32(0);
  92. return cbuf;
  93. }
  94. /**
  95. *
  96. */
  97. CommBuf *
  98. Hyperspace::Protocol::create_server_keepalive_request(
  99. SessionDataPtr &session_data) {
  100. uint32_t len = 16;
  101. CommBuf *cbuf = 0;
  102. CommHeader header(COMMAND_KEEPALIVE);
  103. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  104. cbuf = session_data->serialize_notifications_for_keepalive(header, len);
  105. return cbuf;
  106. }
  107. /**
  108. *
  109. */
  110. CommBuf *Hyperspace::Protocol::create_server_redirect_request(const std::string &host) {
  111. CommHeader header(COMMAND_REDIRECT);
  112. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  113. size_t len = encoded_length_vstr(host);
  114. CommBuf *cbuf = new CommBuf(header, len);
  115. cbuf->append_vstr(host);
  116. return cbuf;
  117. }
  118. /**
  119. *
  120. */
  121. CommBuf *Hyperspace::Protocol::create_handshake_request(uint64_t session_id,
  122. const std::string &name) {
  123. CommHeader header(COMMAND_HANDSHAKE);
  124. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  125. size_t len = 8 + encoded_length_vstr(name);
  126. CommBuf *cbuf = new CommBuf(header, len);
  127. cbuf->append_i64(session_id);
  128. cbuf->append_vstr(name);
  129. return cbuf;
  130. }
  131. /**
  132. *
  133. */
  134. CommBuf *
  135. Hyperspace::Protocol::create_open_request(const std::string &name,
  136. uint32_t flags, HandleCallbackPtr &callback,
  137. std::vector<Attribute> &init_attrs) {
  138. size_t len = 12 + encoded_length_vstr(name.size());
  139. CommHeader header(COMMAND_OPEN);
  140. for (size_t i=0; i<init_attrs.size(); i++)
  141. len += encoded_length_vstr(init_attrs[i].name)
  142. + encoded_length_vstr(init_attrs[i].value_len);
  143. CommBuf *cbuf = new CommBuf(header, len);
  144. cbuf->append_i32(flags);
  145. if (callback)
  146. cbuf->append_i32(callback->get_event_mask());
  147. else
  148. cbuf->append_i32(0);
  149. cbuf->append_vstr(name);
  150. // append initial attributes
  151. cbuf->append_i32(init_attrs.size());
  152. for (size_t i=0; i<init_attrs.size(); i++) {
  153. cbuf->append_vstr(init_attrs[i].name);
  154. cbuf->append_vstr(init_attrs[i].value, init_attrs[i].value_len);
  155. }
  156. return cbuf;
  157. }
  158. CommBuf *Hyperspace::Protocol::create_close_request(uint64_t handle) {
  159. CommHeader header(COMMAND_CLOSE);
  160. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  161. CommBuf *cbuf = new CommBuf(header, 8);
  162. cbuf->append_i64(handle);
  163. return cbuf;
  164. }
  165. CommBuf *Hyperspace::Protocol::create_mkdir_request(const std::string &name) {
  166. CommHeader header(COMMAND_MKDIR);
  167. header.gid = filename_to_group(name);
  168. CommBuf *cbuf = new CommBuf(header, encoded_length_vstr(name.size()));
  169. cbuf->append_vstr(name);
  170. return cbuf;
  171. }
  172. CommBuf *Hyperspace::Protocol::create_delete_request(const std::string &name) {
  173. CommHeader header(COMMAND_DELETE);
  174. header.gid = filename_to_group(name);
  175. CommBuf *cbuf = new CommBuf(header, encoded_length_vstr(name.size()));
  176. cbuf->append_vstr(name);
  177. return cbuf;
  178. }
  179. CommBuf *
  180. Hyperspace::Protocol::create_attr_set_request(uint64_t handle,
  181. const std::string &name, const void *value, size_t value_len) {
  182. CommHeader header(COMMAND_ATTRSET);
  183. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  184. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size())
  185. + encoded_length_vstr(value_len));
  186. cbuf->append_i64(handle);
  187. cbuf->append_vstr(name);
  188. cbuf->append_vstr(value, value_len);
  189. return cbuf;
  190. }
  191. CommBuf *
  192. Hyperspace::Protocol::create_attr_incr_request(uint64_t handle,
  193. const std::string &name) {
  194. CommHeader header(COMMAND_ATTRINCR);
  195. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  196. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  197. cbuf->append_i64(handle);
  198. cbuf->append_vstr(name);
  199. return cbuf;
  200. }
  201. CommBuf *
  202. Hyperspace::Protocol::create_attr_get_request(uint64_t handle,
  203. const std::string &name) {
  204. CommHeader header(COMMAND_ATTRGET);
  205. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  206. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  207. cbuf->append_i64(handle);
  208. cbuf->append_vstr(name);
  209. return cbuf;
  210. }
  211. CommBuf *
  212. Hyperspace::Protocol::create_attr_del_request(uint64_t handle,
  213. const std::string &name) {
  214. CommHeader header(COMMAND_ATTRDEL);
  215. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  216. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  217. cbuf->append_i64(handle);
  218. cbuf->append_vstr(name);
  219. return cbuf;
  220. }
  221. CommBuf *
  222. Hyperspace::Protocol::create_attr_exists_request(uint64_t handle, const std::string &name) {
  223. CommHeader header(COMMAND_ATTREXISTS);
  224. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  225. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  226. cbuf->append_i64(handle);
  227. cbuf->append_vstr(name);
  228. return cbuf;
  229. }
  230. CommBuf *
  231. Hyperspace::Protocol::create_attr_list_request(uint64_t handle) {
  232. CommHeader header(COMMAND_ATTRLIST);
  233. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  234. CommBuf *cbuf = new CommBuf(header, 8);
  235. cbuf->append_i64(handle);
  236. return cbuf;
  237. }
  238. CommBuf *Hyperspace::Protocol::create_readdir_request(uint64_t handle) {
  239. CommHeader header(COMMAND_READDIR);
  240. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  241. CommBuf *cbuf = new CommBuf(header, 8);
  242. cbuf->append_i64(handle);
  243. return cbuf;
  244. }
  245. CommBuf *Hyperspace::Protocol::create_readdir_attr_request(uint64_t handle,
  246. const std::string &name) {
  247. CommHeader header(COMMAND_READDIRATTR);
  248. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  249. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  250. cbuf->append_i64(handle);
  251. cbuf->append_vstr(name);
  252. return cbuf;
  253. }
  254. CommBuf *Hyperspace::Protocol::create_readpath_attr_request(uint64_t handle,
  255. const std::string &name) {
  256. CommHeader header(COMMAND_READPATHATTR);
  257. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  258. CommBuf *cbuf = new CommBuf(header, 8 + encoded_length_vstr(name.size()));
  259. cbuf->append_i64(handle);
  260. cbuf->append_vstr(name);
  261. return cbuf;
  262. }
  263. CommBuf *Hyperspace::Protocol::create_exists_request(const std::string &name) {
  264. CommHeader header(COMMAND_EXISTS);
  265. header.gid = filename_to_group(name);
  266. CommBuf *cbuf = new CommBuf(header, encoded_length_vstr(name.size()));
  267. cbuf->append_vstr(name);
  268. return cbuf;
  269. }
  270. CommBuf *
  271. Hyperspace::Protocol::create_lock_request(uint64_t handle, uint32_t mode,
  272. bool try_lock) {
  273. CommHeader header(COMMAND_LOCK);
  274. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  275. CommBuf *cbuf = new CommBuf(header, 13);
  276. cbuf->append_i64(handle);
  277. cbuf->append_i32(mode);
  278. cbuf->append_byte(try_lock);
  279. return cbuf;
  280. }
  281. CommBuf *Hyperspace::Protocol::create_release_request(uint64_t handle) {
  282. CommHeader header(COMMAND_RELEASE);
  283. header.gid = (uint32_t)((handle ^ (handle >> 32)) & 0x0FFFFFFFFLL);
  284. CommBuf *cbuf = new CommBuf(header, 8);
  285. cbuf->append_i64(handle);
  286. return cbuf;
  287. }
  288. /**
  289. *
  290. */
  291. CommBuf *Hyperspace::Protocol::create_status_request() {
  292. CommHeader header(COMMAND_STATUS);
  293. header.flags |= CommHeader::FLAGS_BIT_URGENT;
  294. CommBuf *cbuf = new CommBuf(header, 0);
  295. return cbuf;
  296. }