示例#1
0
bool UmbrellaSerializedMessage::prepare(const McReply& reply, mc_op_t op,
                                        uint64_t reqid, struct iovec*& iovOut,
                                        size_t& niovOut) {
  niovOut = 0;

  appendInt(I32, msg_op, umbrella_op_from_mc[op]);
  appendInt(U64, msg_reqid, reqid);
  appendInt(I32, msg_result, umbrella_res_from_mc[reply.result()]);

  if (reply.appSpecificErrorCode()) {
    appendInt(I32, msg_err_code, reply.appSpecificErrorCode());
  }
  if (reply.flags()) {
    appendInt(U64, msg_flags, reply.flags());
  }
  if (reply.exptime()) {
    appendInt(U64, msg_exptime, reply.exptime());
  }
  if (reply.delta()) {
    appendInt(U64, msg_delta, reply.delta());
  }
  if (reply.leaseToken()) {
    appendInt(U64, msg_lease_id, reply.leaseToken());
  }
  if (reply.cas()) {
    appendInt(U64, msg_cas, reply.cas());
  }
  if (reply.number()) {
    appendInt(U64, msg_number, reply.number());
  }

  /* TODO: if we intend to pass chained IOBufs as values,
     we can optimize this to write multiple iovs directly */
  if (reply.hasValue()) {
    auto valueRange = reply.valueRangeSlow();
    appendString(msg_value,
                 reinterpret_cast<const uint8_t*>(valueRange.begin()),
                 valueRange.size());
  }

  /* NOTE: this check must come after all append*() calls */
  if (error_) {
    return false;
  }

  niovOut = finalizeMessage();
  iovOut = iovs_;
  return true;
}
bool UmbrellaSerializedReply::prepare(const McReply& reply,
                                      mc_op_t op, uint64_t reqid,
                                      struct iovec*& iovOut, size_t& niovOut) {
  static char nul = '\0';

  /* We can reuse this struct multiple times, reset the counters */
  nEntries_ = nStrings_ = offset_ = 0;
  error_ = false;
  niovOut = 0;

  appendInt(I32, msg_op, umbrella_op_from_mc[op]);
  appendInt(U64, msg_reqid, reqid);
  appendInt(I32, msg_result, umbrella_res_from_mc[reply.result()]);

  if (reply.appSpecificErrorCode()) {
    appendInt(I32, msg_err_code, reply.appSpecificErrorCode());
  }
  if (reply.flags()) {
    appendInt(U64, msg_flags, reply.flags());
  }
  if (reply.exptime()) {
    appendInt(U64, msg_exptime, reply.exptime());
  }
  if (reply.delta()) {
    appendInt(U64, msg_delta, reply.delta());
  }
  if (reply.leaseToken()) {
    appendInt(U64, msg_lease_id, reply.leaseToken());
  }
  if (reply.cas()) {
    appendInt(U64, msg_cas, reply.cas());
  }
  if (reply.lowValue() || reply.highValue()) {
    appendDouble(reply.lowValue());
  }
  if (reply.highValue()) {
    appendDouble(reply.highValue());
  }

  /* TODO: if we intend to pass chained IOBufs as values,
     we can optimize this to write multiple iovs directly */
  if (reply.hasValue()) {
    auto valueRange = reply.valueRangeSlow();
    appendString(msg_value,
                 reinterpret_cast<const uint8_t*>(valueRange.begin()),
                 valueRange.size());
  }

  /* NOTE: this check must come after all append*() calls */
  if (error_) {
    return false;
  }

  size_t size = sizeof(entry_list_msg_t) +
    sizeof(um_elist_entry_t) * nEntries_ +
    offset_;

  msg_.total_size = folly::Endian::big((uint32_t)size);
  msg_.nentries = folly::Endian::big((uint16_t)nEntries_);

  iovs_[1].iov_len = sizeof(um_elist_entry_t) * nEntries_;
  niovOut = 2;

  for (size_t i = 0; i < nStrings_; i++) {
    iovs_[niovOut].iov_base = (char *)strings_[i].begin();
    iovs_[niovOut].iov_len = strings_[i].size();
    niovOut++;

    iovs_[niovOut].iov_base = &nul;
    iovs_[niovOut].iov_len = 1;
    niovOut++;
  }

  iovOut = iovs_;
  return true;
}