mirror of https://gitee.com/bigwinds/arangodb
Avoid memset on non-POD types for portability. (#5558)
This commit is contained in:
parent
c6e1672338
commit
66e9fb1dbd
|
@ -142,7 +142,14 @@ void PlainBucket::evict(CachedValue* value, bool optimizeForInsertion) {
|
|||
|
||||
void PlainBucket::clear() {
|
||||
TRI_ASSERT(isLocked());
|
||||
memset(this, 0, sizeof(PlainBucket));
|
||||
_state.clear(); // "clear" will keep the lock!
|
||||
|
||||
for (size_t i = 0; i < slotsData; ++i) {
|
||||
_cachedHashes[i] = 0;
|
||||
_cachedData[i] = nullptr;
|
||||
}
|
||||
|
||||
_state.unlock();
|
||||
}
|
||||
|
||||
void PlainBucket::moveSlot(size_t slot, bool moveToFront) {
|
||||
|
|
|
@ -34,6 +34,8 @@ using namespace arangodb::cache;
|
|||
const uint32_t Table::minLogSize = 8;
|
||||
const uint32_t Table::maxLogSize = 32;
|
||||
|
||||
Table::GenericBucket::GenericBucket() : _state{}, _padding{} {}
|
||||
|
||||
bool Table::GenericBucket::lock(uint64_t maxTries) {
|
||||
return _state.lock(maxTries);
|
||||
}
|
||||
|
@ -43,6 +45,16 @@ void Table::GenericBucket::unlock() {
|
|||
_state.unlock();
|
||||
}
|
||||
|
||||
void Table::GenericBucket::clear() {
|
||||
_state.lock(UINT64_MAX, [this]() -> void {
|
||||
_state.clear();
|
||||
for (size_t i = 0; i < paddingSize; i++) {
|
||||
_padding[i] = static_cast<uint8_t>(0);
|
||||
}
|
||||
_state.unlock();
|
||||
});
|
||||
}
|
||||
|
||||
bool Table::GenericBucket::isMigrated() const {
|
||||
TRI_ASSERT(_state.isLocked());
|
||||
return _state.isSet(BucketState::Flag::migrated);
|
||||
|
@ -88,7 +100,19 @@ Table::Table(uint32_t logSize)
|
|||
_bucketClearer(defaultClearer),
|
||||
_slotsTotal(_size),
|
||||
_slotsUsed(static_cast<uint64_t>(0)) {
|
||||
memset(_buckets, 0, BUCKET_SIZE * _size);
|
||||
for (size_t i = 0; i < _size; i++) {
|
||||
// use placement new in order to properly initialize the bucket
|
||||
new (_buckets + i) GenericBucket();
|
||||
}
|
||||
}
|
||||
|
||||
Table::~Table() {
|
||||
for (size_t i = 0; i < _size; i++) {
|
||||
// retrieve pointer to bucket
|
||||
GenericBucket* b = _buckets + i;
|
||||
// call dtor
|
||||
b->~GenericBucket();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Table::allocationSize(uint32_t logSize) {
|
||||
|
@ -102,8 +126,8 @@ uint64_t Table::size() const { return _size; }
|
|||
|
||||
uint32_t Table::logSize() const { return _logSize; }
|
||||
|
||||
std::pair<void*, Table*> Table::fetchAndLockBucket(
|
||||
uint32_t hash, uint64_t maxTries) {
|
||||
std::pair<void*, Table*> Table::fetchAndLockBucket(uint32_t hash,
|
||||
uint64_t maxTries) {
|
||||
GenericBucket* bucket = nullptr;
|
||||
Table* source = nullptr;
|
||||
bool ok = _lock.readLock(maxTries);
|
||||
|
@ -228,14 +252,14 @@ bool Table::isEnabled(uint64_t maxTries) {
|
|||
|
||||
bool Table::slotFilled() {
|
||||
size_t i = _slotsUsed.fetch_add(1, std::memory_order_acq_rel);
|
||||
return ((static_cast<double>(i + 1) /
|
||||
static_cast<double>(_slotsTotal)) > Table::idealUpperRatio);
|
||||
return ((static_cast<double>(i + 1) / static_cast<double>(_slotsTotal)) >
|
||||
Table::idealUpperRatio);
|
||||
}
|
||||
|
||||
bool Table::slotEmptied() {
|
||||
size_t i = _slotsUsed.fetch_sub(1, std::memory_order_acq_rel);
|
||||
return (((static_cast<double>(i - 1) /
|
||||
static_cast<double>(_slotsTotal)) < Table::idealLowerRatio) &&
|
||||
return (((static_cast<double>(i - 1) / static_cast<double>(_slotsTotal)) <
|
||||
Table::idealLowerRatio) &&
|
||||
(_logSize > Table::minLogSize));
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,12 @@ class Table : public std::enable_shared_from_this<Table> {
|
|||
private:
|
||||
struct GenericBucket {
|
||||
BucketState _state;
|
||||
uint8_t _filler[BUCKET_SIZE - sizeof(BucketState)];
|
||||
static constexpr size_t paddingSize = BUCKET_SIZE - sizeof(BucketState);
|
||||
uint8_t _padding[paddingSize];
|
||||
GenericBucket();
|
||||
bool lock(uint64_t maxTries);
|
||||
void unlock();
|
||||
void clear();
|
||||
bool isMigrated() const;
|
||||
};
|
||||
static_assert(sizeof(GenericBucket) == BUCKET_SIZE,
|
||||
|
@ -87,6 +90,11 @@ class Table : public std::enable_shared_from_this<Table> {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
explicit Table(uint32_t logSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Destroy the table
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
~Table();
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Returns the memory usage for a table with specified logSize
|
||||
|
|
|
@ -198,7 +198,16 @@ void TransactionalBucket::evict(CachedValue* value, bool optimizeForInsertion) {
|
|||
|
||||
void TransactionalBucket::clear() {
|
||||
TRI_ASSERT(isLocked());
|
||||
memset(this, 0, sizeof(TransactionalBucket));
|
||||
_state.clear(); // "clear" will keep the lock!
|
||||
for (size_t i = 0; i < slotsBlacklist; ++i) {
|
||||
_blacklistHashes[i] = 0;
|
||||
}
|
||||
_blacklistTerm = 0;
|
||||
for (size_t i = 0; i < slotsData; ++i) {
|
||||
_cachedHashes[i] = 0;
|
||||
_cachedData[i] = nullptr;
|
||||
}
|
||||
_state.unlock();
|
||||
}
|
||||
|
||||
void TransactionalBucket::updateBlacklistTerm(uint64_t term) {
|
||||
|
|
Loading…
Reference in New Issue