//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Daniel H. Larkin //////////////////////////////////////////////////////////////////////////////// #include "Cache/CachedValue.h" #include #include using namespace arangodb::cache; const size_t CachedValue::_headerAllocSize = sizeof(CachedValue) + CachedValue::_padding; CachedValue* CachedValue::copy() const { uint8_t* buf = new uint8_t[size()]; CachedValue* value = nullptr; try { value = new (buf + offset()) CachedValue(*this); } catch (...) { delete[] buf; return nullptr; } return value; } CachedValue* CachedValue::construct(void const* k, size_t kSize, void const* v, size_t vSize) { if (kSize == 0 || k == nullptr || (vSize > 0 && v == nullptr) || kSize > maxKeySize || vSize > maxValueSize) { return nullptr; } uint8_t* buf = new uint8_t[_headerAllocSize + kSize + vSize]; CachedValue* cv = nullptr; try { uint8_t* aligned = reinterpret_cast( (reinterpret_cast(buf) + _headerAllocOffset) & _headerAllocMask); size_t offset = buf - aligned; cv = new (aligned) CachedValue(offset, k, kSize, v, vSize); } catch (...) { delete[] buf; return nullptr; } return cv; } void CachedValue::operator delete(void* ptr) { CachedValue* cv = reinterpret_cast(ptr); size_t offset = cv->offset(); cv->~CachedValue(); delete[](reinterpret_cast(ptr) - offset); } CachedValue::CachedValue(size_t off, void const* k, size_t kSize, void const* v, size_t vSize) noexcept : _refCount(0), _keySize(static_cast(kSize + (off << _offsetShift))), _valueSize(static_cast(vSize)) { std::memcpy(const_cast(key()), k, kSize); if (vSize > 0) { std::memcpy(const_cast(value()), v, vSize); } } CachedValue::CachedValue(CachedValue const& other) noexcept : _refCount(0), _keySize(other._keySize), _valueSize(other._valueSize) { std::memcpy(const_cast(key()), other.key(), keySize() + valueSize()); }