| 130 | |
| 131 | long _dictKeyIndex(dict *d, const void *key, uint64_t hash, dictEntry **existing); |
| 132 | void StorageCache::bulkInsert(char **rgkeys, size_t *rgcbkeys, char **rgvals, size_t *rgcbvals, size_t celem) |
| 133 | { |
| 134 | std::vector<dictEntry*> vechashes; |
| 135 | if (m_pdict != nullptr) { |
| 136 | vechashes.reserve(celem); |
| 137 | } |
| 138 | |
| 139 | for (size_t ielem = 0; ielem < celem; ++ielem) { |
| 140 | if (m_pdict != nullptr) { |
| 141 | dictEntry *de = (dictEntry*)zmalloc(sizeof(dictEntry)); |
| 142 | de->key = (void*)dictGenHashFunction(rgkeys[ielem], (int)rgcbkeys[ielem]); |
| 143 | de->v.u64 = 1; |
| 144 | vechashes.push_back(de); |
| 145 | } |
| 146 | auto e = deserializeExpire(rgvals[ielem], rgcbvals[ielem], nullptr); |
| 147 | if (e != nullptr) |
| 148 | m_spstorage->setExpire(rgkeys[ielem], rgcbkeys[ielem], e->when()); |
| 149 | } |
| 150 | |
| 151 | std::unique_lock<fastlock> ul(m_lock); |
| 152 | bulkInsertsInProgress++; |
| 153 | if (m_pdict != nullptr) { |
| 154 | for (dictEntry *de : vechashes) { |
| 155 | if (dictIsRehashing(m_pdict)) dictRehash(m_pdict,1); |
| 156 | /* Get the index of the new element, or -1 if |
| 157 | * the element already exists. */ |
| 158 | long index; |
| 159 | if ((index = _dictKeyIndex(m_pdict, de->key, (uint64_t)de->key, nullptr)) == -1) { |
| 160 | dictEntry *deLocal = dictFind(m_pdict, de->key); |
| 161 | serverAssert(deLocal != nullptr); |
| 162 | deLocal->v.s64++; |
| 163 | m_collisionCount++; |
| 164 | zfree(de); |
| 165 | } else { |
| 166 | int iht = dictIsRehashing(m_pdict) ? 1 : 0; |
| 167 | de->next = m_pdict->ht[iht].table[index]; |
| 168 | m_pdict->ht[iht].table[index] = de; |
| 169 | m_pdict->ht[iht].used++; |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | ul.unlock(); |
| 174 | |
| 175 | m_spstorage->bulkInsert(rgkeys, rgcbkeys, rgvals, rgcbvals, celem); |
| 176 | |
| 177 | bulkInsertsInProgress--; |
| 178 | } |
| 179 | |
| 180 | const StorageCache *StorageCache::clone() |
| 181 | { |
no test coverage detected