improve overwrite key performance
Former-commit-id: 56f9d5528385ea78074a308c6d3987b920d6cc35
This commit is contained in:
parent
8210d67c24
commit
86784fe9ba
27
src/db.cpp
27
src/db.cpp
@ -242,7 +242,7 @@ robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply) {
|
||||
return o;
|
||||
}
|
||||
|
||||
bool dbAddCore(redisDb *db, sds key, robj *val, bool fUpdateMvcc, bool fAssumeNew = false) {
|
||||
bool dbAddCore(redisDb *db, sds key, robj *val, bool fUpdateMvcc, bool fAssumeNew = false, dict_iter *piterExisting = nullptr) {
|
||||
serverAssert(!val->FExpires());
|
||||
sds copy = sdsdupshared(key);
|
||||
|
||||
@ -251,7 +251,7 @@ bool dbAddCore(redisDb *db, sds key, robj *val, bool fUpdateMvcc, bool fAssumeNe
|
||||
setMvccTstamp(val, mvcc);
|
||||
}
|
||||
|
||||
bool fInserted = db->insert(copy, val, fAssumeNew);
|
||||
bool fInserted = db->insert(copy, val, fAssumeNew, piterExisting);
|
||||
|
||||
if (fInserted)
|
||||
{
|
||||
@ -321,8 +321,12 @@ void redisDb::dbOverwriteCore(redisDb::iter itr, sds keySds, robj *val, bool fUp
|
||||
* This function does not modify the expire time of the existing key.
|
||||
*
|
||||
* The program is aborted if the key was not already present. */
|
||||
void dbOverwrite(redisDb *db, robj *key, robj *val, bool fRemoveExpire) {
|
||||
auto itr = db->find(key);
|
||||
void dbOverwrite(redisDb *db, robj *key, robj *val, bool fRemoveExpire, dict_iter *pitrExisting) {
|
||||
redisDb::iter itr;
|
||||
if (pitrExisting != nullptr)
|
||||
itr = *pitrExisting;
|
||||
else
|
||||
itr = db->find(key);
|
||||
|
||||
serverAssertWithInfo(NULL,key,itr != nullptr);
|
||||
lookupKeyUpdateObj(itr.val(), LOOKUP_NONE);
|
||||
@ -366,8 +370,9 @@ int dbMerge(redisDb *db, sds key, robj *val, int fReplace)
|
||||
* in a context where there is no clear client performing the operation. */
|
||||
void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal) {
|
||||
db->prepOverwriteForSnapshot(szFromObj(key));
|
||||
if (!dbAddCore(db, szFromObj(key), val, true /* fUpdateMvcc */)) {
|
||||
dbOverwrite(db, key, val, !keepttl);
|
||||
dict_iter iter;
|
||||
if (!dbAddCore(db, szFromObj(key), val, true /* fUpdateMvcc */, false /*fAssumeNew*/, &iter)) {
|
||||
dbOverwrite(db, key, val, !keepttl, &iter);
|
||||
}
|
||||
incrRefCount(val);
|
||||
if (signal) signalModifiedKey(c,db,key);
|
||||
@ -2594,11 +2599,12 @@ void redisDb::storageProviderInitialize()
|
||||
}
|
||||
}
|
||||
|
||||
bool redisDbPersistentData::insert(char *key, robj *o, bool fAssumeNew)
|
||||
bool redisDbPersistentData::insert(char *key, robj *o, bool fAssumeNew, dict_iter *piterExisting)
|
||||
{
|
||||
if (!fAssumeNew && (g_pserver->m_pstorageFactory != nullptr || m_pdbSnapshot != nullptr))
|
||||
ensure(key);
|
||||
int res = dictAdd(m_pdict, key, o);
|
||||
dictEntry *de;
|
||||
int res = dictAdd(m_pdict, key, o, &de);
|
||||
serverAssert(FImplies(fAssumeNew, res == DICT_OK));
|
||||
if (res == DICT_OK)
|
||||
{
|
||||
@ -2610,6 +2616,11 @@ bool redisDbPersistentData::insert(char *key, robj *o, bool fAssumeNew)
|
||||
#endif
|
||||
trackkey(key, false /* fUpdate */);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (piterExisting)
|
||||
*piterExisting = dict_iter(m_pdict, de);
|
||||
}
|
||||
return (res == DICT_OK);
|
||||
}
|
||||
|
||||
|
@ -573,9 +573,9 @@ static void _dictRehashStep(dict *d) {
|
||||
}
|
||||
|
||||
/* Add an element to the target hash table */
|
||||
int dictAdd(dict *d, void *key, void *val)
|
||||
int dictAdd(dict *d, void *key, void *val, dictEntry **existing)
|
||||
{
|
||||
dictEntry *entry = dictAddRaw(d,key,NULL);
|
||||
dictEntry *entry = dictAddRaw(d,key,existing);
|
||||
|
||||
if (!entry) return DICT_ERR;
|
||||
dictSetVal(d, entry, val);
|
||||
|
@ -205,7 +205,7 @@ typedef void (dictScanBucketFunction)(void *privdata, dictEntry **bucketref);
|
||||
dict *dictCreate(dictType *type, void *privDataPtr);
|
||||
int dictExpand(dict *d, unsigned long size, bool fShrink = false);
|
||||
int dictTryExpand(dict *d, unsigned long size, bool fShrink);
|
||||
int dictAdd(dict *d, void *key, void *val);
|
||||
int dictAdd(dict *d, void *key, void *val, dictEntry **existing = nullptr);
|
||||
dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing);
|
||||
dictEntry *dictAddOrFind(dict *d, void *key);
|
||||
int dictReplace(dict *d, void *key, void *val);
|
||||
|
@ -2086,7 +2086,7 @@ void databasesCron(bool fMainThread) {
|
||||
/* Perform hash tables rehashing if needed, but only if there are no
|
||||
* other processes saving the DB on disk. Otherwise rehashing is bad
|
||||
* as will cause a lot of copy-on-write of memory pages. */
|
||||
if (!hasActiveChildProcess() || g_pserver->FRdbSaveInProgress()) {
|
||||
if (!(hasActiveChildProcess() || g_pserver->FRdbSaveInProgress())) {
|
||||
/* We use global counters so if we stop the computation at a given
|
||||
* DB we'll be able to start from the successive in the next
|
||||
* cron loop iteration. */
|
||||
|
@ -1067,6 +1067,9 @@ class dict_iter : public dict_const_iter
|
||||
{
|
||||
dict *m_dict = nullptr;
|
||||
public:
|
||||
dict_iter()
|
||||
: dict_const_iter(nullptr)
|
||||
{}
|
||||
explicit dict_iter(nullptr_t)
|
||||
: dict_const_iter(nullptr)
|
||||
{}
|
||||
@ -1131,7 +1134,7 @@ public:
|
||||
void getStats(char *buf, size_t bufsize) { dictGetStats(buf, bufsize, m_pdict); }
|
||||
void getExpireStats(char *buf, size_t bufsize) { m_setexpire->getstats(buf, bufsize); }
|
||||
|
||||
bool insert(char *k, robj *o, bool fAssumeNew = false);
|
||||
bool insert(char *k, robj *o, bool fAssumeNew = false, dict_iter *existing = nullptr);
|
||||
void tryResize();
|
||||
int incrementallyRehash();
|
||||
void updateValue(dict_iter itr, robj *val);
|
||||
@ -3325,7 +3328,7 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
|
||||
#define LOOKUP_NONOTIFY (1<<1)
|
||||
#define LOOKUP_UPDATEMVCC (1<<2)
|
||||
void dbAdd(redisDb *db, robj *key, robj *val);
|
||||
void dbOverwrite(redisDb *db, robj *key, robj *val, bool fRemoveExpire = false);
|
||||
void dbOverwrite(redisDb *db, robj *key, robj *val, bool fRemoveExpire = false, dict_iter *pitrExisting = nullptr);
|
||||
int dbMerge(redisDb *db, sds key, robj *val, int fReplace);
|
||||
void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal);
|
||||
void setKey(client *c, redisDb *db, robj *key, robj *val);
|
||||
|
Loading…
x
Reference in New Issue
Block a user