| 246 | } |
| 247 | |
| 248 | bool redisDbPersistentDataSnapshot::freeTombstoneObjects(int depth) |
| 249 | { |
| 250 | if (m_pdbSnapshot == nullptr) |
| 251 | { |
| 252 | serverAssert(dictSize(m_pdictTombstone) == 0); |
| 253 | return true; |
| 254 | } |
| 255 | |
| 256 | if (!const_cast<redisDbPersistentDataSnapshot*>(m_pdbSnapshot)->freeTombstoneObjects(depth+1)) |
| 257 | return false; |
| 258 | |
| 259 | { |
| 260 | AeLocker ae; |
| 261 | ae.arm(nullptr); |
| 262 | if (m_pdbSnapshot->m_refCount != depth && (m_pdbSnapshot->m_refCount != (m_refCount+1))) |
| 263 | return false; |
| 264 | ae.disarm(); |
| 265 | } |
| 266 | |
| 267 | std::unique_lock<fastlock> lock(s_lock, std::defer_lock); |
| 268 | if (!lock.try_lock()) |
| 269 | return false; // this is a best effort function |
| 270 | |
| 271 | std::unique_ptr<LazyFree> splazy = std::make_unique<LazyFree>(); |
| 272 | |
| 273 | dict *dictTombstoneNew = dictCreate(&dbTombstoneDictType, nullptr); |
| 274 | dictIterator *di = dictGetIterator(m_pdictTombstone); |
| 275 | dictEntry *de; |
| 276 | std::vector<dictEntry*> vecdeFree; |
| 277 | vecdeFree.reserve(dictSize(m_pdictTombstone)); |
| 278 | unsigned rgcremoved[2] = {0}; |
| 279 | while ((de = dictNext(di)) != nullptr) |
| 280 | { |
| 281 | dictEntry **dePrev = nullptr; |
| 282 | dictht *ht = nullptr; |
| 283 | sds key = (sds)dictGetKey(de); |
| 284 | // BUG BUG: Why can't we do a shallow search here? |
| 285 | dictEntry *deObj = dictFindWithPrev(m_pdbSnapshot->m_pdict, key, (uint64_t)dictGetVal(de), &dePrev, &ht, false); |
| 286 | |
| 287 | if (deObj != nullptr) |
| 288 | { |
| 289 | // Now unlink the DE |
| 290 | __atomic_store(dePrev, &deObj->next, __ATOMIC_RELEASE); |
| 291 | if (ht == &m_pdbSnapshot->m_pdict->ht[0]) |
| 292 | rgcremoved[0]++; |
| 293 | else |
| 294 | rgcremoved[1]++; |
| 295 | splazy->vecde.push_back(deObj); |
| 296 | } else { |
| 297 | serverAssert(dictFind(m_pdbSnapshot->m_pdict, key) == nullptr); |
| 298 | serverAssert(m_pdbSnapshot->find_cached_threadsafe(key) != nullptr); |
| 299 | dictAdd(dictTombstoneNew, sdsdupshared((sds)dictGetKey(de)), dictGetVal(de)); |
| 300 | } |
| 301 | } |
| 302 | dictReleaseIterator(di); |
| 303 | |
| 304 | dictForceRehash(dictTombstoneNew); |
| 305 | aeAcquireLock(); |
no test coverage detected