McMsgRef McReplyBase::releasedMsg(mc_op_t op) const {
  if (msg_.get() != nullptr &&
      msg_->op == op &&
      msg_->result == result_ &&
      msg_->flags == flags_ &&
      msg_->lease_id == leaseToken_ &&
      msg_->delta == delta_ &&
      msg_->err_code == errCode_ &&
      hasSameMemoryRegion(value(), to<folly::StringPiece>(msg_->value))) {
    return msg_.clone();
  } else {
    auto len = value().computeChainDataLength();
    auto toRelease = createMcMsgRef(len + 1);
    if (msg_.get() != nullptr) {
      mc_msg_shallow_copy(toRelease.get(), msg_.get());
      // TODO: fbtrace?
    }
    toRelease->key.str = nullptr;
    toRelease->key.len = 0;
    toRelease->value.str =
      static_cast<char*>(static_cast<void*>(toRelease.get() + 1));
    copyInto(toRelease->value.str, value());
    toRelease->value.len = len;
    toRelease->op = op;
    toRelease->result = result_;
    toRelease->flags = flags_;
    toRelease->lease_id = leaseToken_;
    toRelease->delta = delta_;
    toRelease->cas = cas_;
    toRelease->err_code = errCode_;

    return std::move(toRelease);
  }
}
Beispiel #2
0
void McRequest::dependentHelper(mc_op_t op, folly::StringPiece key,
                                folly::StringPiece value,
                                MutableMcMsgRef& into) const {
  if (msg_.get()) {
    mc_msg_shallow_copy(into.get(), msg_.get());
  }
  into->op = op;
  into->exptime = exptime_;
  into->flags = flags_;
  into->delta = delta_;
  into->lease_id = leaseToken_;
  into->cas = cas_;
#ifndef LIBMC_FBTRACE_DISABLE
  into->fbtrace_info = fbtraceInfo_.clone().release();
#endif
  into->key = to<nstring_t>(key);
  into->value = to<nstring_t>(value);
}
Beispiel #3
0
void McReplyBase::dependentMsg(mc_op_t op, mc_msg_t* out) const {
  if (msg_.get() != nullptr) {
    mc_msg_shallow_copy(out, msg_.get());
  }

  auto value = valueRangeSlow();

  out->key.str = nullptr;
  out->key.len = 0;
  out->value.str = const_cast<char*>(value.begin());
  out->value.len = value.size();
  out->op = op;
  out->result = result_;
  out->flags = flags_;
  out->lease_id = leaseToken_;
  out->delta = delta_;
  out->cas = cas_;
}
Beispiel #4
0
mc_msg_t* mc_msg_dup_append_key_full(const mc_msg_t *msg,
                                     const char* key_append,
                                     size_t nkey_append) {
  FBI_ASSERT(msg);
  FBI_ASSERT(msg->_refcount > 0 || msg->_refcount == MSG_NOT_REFCOUNTED);
  FBI_ASSERT(key_append);

  // Stats are not supported.
  if (msg->stats) {
    return NULL;
  }

  if (!nkey_append) {
    return mc_msg_dup(msg);
  }

  size_t new_extra_size = msg->_extra_size + nkey_append;
  if (!_in_msg(msg, msg->key.str, msg->key.len)) {
    new_extra_size += msg->key.len + 1; // +1 for null terminator
  }
  mc_msg_t* const msg_copy = mc_msg_new(new_extra_size);
  if (msg_copy == NULL) {
    return NULL;
  }
  mc_msg_shallow_copy(msg_copy, msg);

  // The new message's key is always embedded.
  msg_copy->key.len = msg->key.len + nkey_append;
  msg_copy->key.str = (void*) msg_copy + sizeof(*msg_copy);
  memcpy(msg_copy->key.str, msg->key.str, msg->key.len);
  memcpy(msg_copy->key.str + msg->key.len, key_append, nkey_append);
  msg_copy->key.str[msg_copy->key.len] = 0;

  if (_in_msg(msg, msg->value.str, msg->value.len)) {
    // The value starts after the key, including the null terminator.
    msg_copy->value.str = msg_copy->key.str + msg_copy->key.len + 1;
    memcpy(msg_copy->value.str, msg->value.str, msg_copy->value.len);
  }
  return msg_copy;
}