McRequest::McRequest(const McRequest& other) : exptime_(other.exptime_), flags_(other.flags_), delta_(other.delta_), leaseToken_(other.leaseToken_), cas_(other.cas_) { // Key is always a single piece, so it's safe to do cloneOneInto. other.keyData_.cloneOneInto(keyData_); keys_ = Keys(getRange(keyData_)); other.valueData_.cloneInto(valueData_); if (hasSameMemoryRegion(keyData_, other.keyData_) && hasSameMemoryRegion(valueData_, other.valueData_)) { msg_ = other.msg_.clone(); } else { msg_ = createMcMsgRef( other.msg_, getRange(keyData_), coalesceAndGetRange(valueData_)); } #ifndef LIBMC_FBTRACE_DISABLE if (other.fbtraceInfo_.get()) { fbtraceInfo_ = McFbtraceRef::moveRef( mc_fbtrace_info_deep_copy(other.fbtraceInfo_.get())); } #endif }
void mc_msg_shallow_copy(mc_msg_t *dst, const mc_msg_t *src) { FBI_ASSERT(dst && src); int _refcount = dst->_refcount; size_t _extra_size = dst->_extra_size; *dst = *src; dst->_refcount = _refcount; dst->_extra_size = _extra_size; #ifndef LIBMC_FBTRACE_DISABLE if (src->fbtrace_info) { dst->fbtrace_info = mc_fbtrace_info_deep_copy(src->fbtrace_info); } #endif }
/* copy src's contents into dst * dst->_extra_size must be greater than or equal to src->_extra_size * If any string fields occur within src's whole message, they will be * deep copied into dst's deep message. External strings will be shallow * copied */ static void _msgcpy(mc_msg_t *dst, const mc_msg_t *src) { FBI_ASSERT(dst && (dst->_refcount > 0 || dst->_refcount == MSG_NOT_REFCOUNTED)); FBI_ASSERT(src && (src->_refcount > 0 || src->_refcount == MSG_NOT_REFCOUNTED)); FBI_ASSERT(dst->_extra_size >= src->_extra_size); // The difference between the old msg and the new message // By adding this to void*'s we can shift the pointer forward pretty easily // // Example: // ________(delta)_________ // | | // v v // | src ... | | dst ... | // ^ ^ // ptr ptr // |________(delta)_________| // // dst->ptr = (void*)src->ptr + delta ssize_t delta = (void*)dst - (void*)src; int _refcount = dst->_refcount; size_t _extra_size = dst->_extra_size; memcpy(dst, src, sizeof(mc_msg_t) + src->_extra_size); dst->_refcount = _refcount; // restore dst->_extra_size = _extra_size; // restore #ifndef LIBMC_FBTRACE_DISABLE if (src->fbtrace_info) { dst->fbtrace_info = mc_fbtrace_info_deep_copy(src->fbtrace_info); } #endif if (src->stats != NULL) { int i, stats_count = src->number * 2; FBI_ASSERT(stats_count > 0); if (_in_msg(src, src->stats, sizeof(src->stats[0]) * stats_count)) { dst->stats = (void*)(src->stats) + delta; for (i = 0; i < stats_count; i++) { if (_in_msg(src, src->stats[i].str, src->stats[i].len)) { dst->stats[i].str = (void*)(src->stats[i].str) + delta; } } } } if (_in_msg(src, src->key.str, src->key.len)) { dst->key.str = (void*)(src->key.str) + delta; } if (_in_msg(src, src->value.str, src->value.len)) { dst->value.str = (void*)(src->value.str) + delta; } }
McRequest::McRequest(const McRequest& other) : exptime_(other.exptime_), number_(other.number_), flags_(other.flags_), delta_(other.delta_), leaseToken_(other.leaseToken_), cas_(other.cas_) { // Key is always a single piece, so it's safe to do cloneOneInto. other.keyData_.cloneOneInto(keyData_); assert(hasSameMemoryRegion(keyData_, other.keyData_)); // it's safe to copy existing StringPieces since we don't copy the data keys_ = other.keys_; other.valueData_.cloneInto(valueData_); #ifndef LIBMC_FBTRACE_DISABLE if (other.fbtraceInfo_.get()) { fbtraceInfo_ = McFbtraceRef::moveRef( mc_fbtrace_info_deep_copy(other.fbtraceInfo_.get())); } #endif }