MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / prefetchKeysAsync

Method prefetchKeysAsync

src/db.cpp:3282–3399  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3280}
3281
3282void redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command)
3283{
3284 if (m_spstorage == nullptr) {
3285#if defined(__x86_64__) || defined(__i386__)
3286 // We do a quick 'n dirty check for set & get. Anything else is too slow.
3287 // Should the user do something weird like remap them then the worst that will
3288 // happen is we don't prefetch or we prefetch wrong data. A mild perf hit, but
3289 // not dangerous
3290 if (command.argc >= 2) {
3291 const char *cmd = szFromObj(command.argv[0]);
3292 if (!strcasecmp(cmd, "set") || !strcasecmp(cmd, "get")) {
3293 if (c->db->m_spdbSnapshotHOLDER != nullptr)
3294 return; // this is dangerous enough without a snapshot around
3295 auto h = dictSdsHash(szFromObj(command.argv[1]));
3296 for (int iht = 0; iht < 2; ++iht) {
3297 auto hT = h & c->db->m_pdict->ht[iht].sizemask;
3298 dictEntry **table;
3299 __atomic_load(&c->db->m_pdict->ht[iht].table, &table, __ATOMIC_RELAXED);
3300 if (table != nullptr) {
3301 dictEntry *de;
3302 __atomic_load(&table[hT], &de, __ATOMIC_ACQUIRE);
3303 while (de != nullptr) {
3304 _mm_prefetch(dictGetKey(de), _MM_HINT_T2);
3305 __atomic_load(&de->next, &de, __ATOMIC_ACQUIRE);
3306 }
3307 }
3308 if (!dictIsRehashing(c->db->m_pdict))
3309 break;
3310 }
3311 }
3312 }
3313#endif
3314 return;
3315 }
3316
3317 AeLocker lock;
3318
3319 std::vector<robj*> veckeys;
3320 lock.arm(c);
3321 getKeysResult result = GETKEYS_RESULT_INIT;
3322 auto cmd = lookupCommand(szFromObj(command.argv[0]));
3323 if (cmd == nullptr)
3324 return; // Bad command? It's not for us to judge, just bail
3325
3326 if (command.argc < std::abs(cmd->arity))
3327 return; // Invalid number of args
3328
3329 int numkeys = getKeysFromCommand(cmd, command.argv, command.argc, &result);
3330 for (int ikey = 0; ikey < numkeys; ++ikey)
3331 {
3332 robj *objKey = command.argv[result.keys[ikey]];
3333 if (this->find_cached_threadsafe(szFromObj(objKey)) == nullptr)
3334 veckeys.push_back(objKey);
3335 }
3336 lock.disarm();
3337
3338 getKeysFreeResult(&result);
3339

Callers 1

parseClientCommandBufferFunction · 0.80

Calls 15

szFromObjFunction · 0.85
lookupCommandFunction · 0.85
getKeysFromCommandFunction · 0.85
getKeysFreeResultFunction · 0.85
sdsdupsharedFunction · 0.85
deserializeExpireFunction · 0.85
deserializeStoredObjectFunction · 0.85
sdsfreeFunction · 0.85
decrRefCountFunction · 0.85
armMethod · 0.80
disarmMethod · 0.80

Tested by

no test coverage detected