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; }