Skip to content

Commit

Permalink
New idea
Browse files Browse the repository at this point in the history
Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
  • Loading branch information
zuiderkwast committed Nov 21, 2024
1 parent c23fd1f commit f64c223
Showing 1 changed file with 28 additions and 24 deletions.
52 changes: 28 additions & 24 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,7 @@ static valkey *dbSetValue(serverDb *db, robj *key, robj *val, int overwrite, voi
}
serverAssertWithInfo(NULL, key, oldref != NULL);
valkey *old = *oldref;

val->lru = old->lru;
valkey *new;

if (overwrite) {
/* VM_StringDMA may call dbUnshareStringValue which may free val, so we
Expand All @@ -332,30 +331,35 @@ static valkey *dbSetValue(serverDb *db, robj *key, robj *val, int overwrite, voi
old = *oldref;
}

/* Can we keep the old object in the database and just replace the ptr? */
if ((old->refcount == 1 && old->type == OBJ_STRING && old->encoding != OBJ_ENCODING_EMBSTR) &&
(val->refcount == 1 && val->type == OBJ_STRING && val->encoding != OBJ_ENCODING_EMBSTR)) {
if (old->encoding == OBJ_ENCODING_RAW) {
/* TODO: Offload sdsfree to io thread. */
sdsfree(old->ptr);
}
if ((old->refcount == 1 && old->encoding != OBJ_ENCODING_EMBSTR) &&
(val->refcount == 1 && val->encoding != OBJ_ENCODING_EMBSTR)) {
/* Keep old object in the database. Just swap it's ptr, type and
* encoding with the content of val. */
int tmp_type = old->type;
int tmp_encoding = old->encoding;
void *tmp_ptr = old->ptr;
old->type = val->type;
old->encoding = val->encoding;
old->ptr = val->ptr;
val->ptr = NULL;
decrRefCount(val);
return old;
}

/* Replace the old value at its location in the key space. */
long long expire = objectGetExpire(old);
valkey *new = objectSetKeyAndExpire(val, key->ptr, expire);
*oldref = new;
/* Replace the old value at its location in the expire space. */
if (expire >= 0) {
int dict_index = getKVStoreIndexForKey(key->ptr);
void **expireref = kvstoreHashtableFindRef(db->expires, dict_index, key->ptr);
serverAssert(expireref != NULL);
*expireref = new;
val->type = tmp_type;
val->encoding = tmp_encoding;
val->ptr = tmp_ptr;
/* Return the old object as new. Set old to val to be freed below. */
new = old;
old = val;
} else {
/* Replace the old value at its location in the key space. */
val->lru = old->lru;
long long expire = objectGetExpire(old);
new = objectSetKeyAndExpire(val, key->ptr, expire);
*oldref = new;
/* Replace the old value at its location in the expire space. */
if (expire >= 0) {
int dict_index = getKVStoreIndexForKey(key->ptr);
void **expireref = kvstoreHashtableFindRef(db->expires, dict_index, key->ptr);
serverAssert(expireref != NULL);
*expireref = new;
}
}
/* For efficiency, let the I/O thread that allocated an object also deallocate it. */
if (tryOffloadFreeObjToIOThreads(old) == C_OK) {
Expand Down

0 comments on commit f64c223

Please sign in to comment.