Skip to content

Commit ad6bc79

Browse files
committed
address Jim early PR comments
Signed-off-by: Ran Shidlansik <ranshid@amazon.com>
1 parent 18c112a commit ad6bc79

File tree

6 files changed

+89
-95
lines changed

6 files changed

+89
-95
lines changed

src/db.c

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@
4444
* C-level DB API
4545
*----------------------------------------------------------------------------*/
4646

47-
/* Flags for expireIfNeeded */
48-
#define EXPIRE_FORCE_DELETE_EXPIRED 1
49-
#define EXPIRE_AVOID_DELETE_EXPIRED 2
50-
5147
static keyStatus expireIfNeededWithDictIndex(serverDb *db, robj *key, robj *val, int flags, int dict_index);
5248
static keyStatus expireIfNeeded(serverDb *db, robj *key, robj *val, int flags);
5349
static int keyIsExpiredWithDictIndex(serverDb *db, robj *key, int dict_index);
@@ -1921,69 +1917,6 @@ void propagateDeletion(serverDb *db, robj *key, int lazy) {
19211917
server.replication_allowed = prev_replication_allowed;
19221918
}
19231919

1924-
/* Returns 1 if the expire value is expired, 0 otherwise. */
1925-
int timestampIsExpired(mstime_t when) {
1926-
if (when < 0) return 0; /* no expire */
1927-
mstime_t now = commandTimeSnapshot();
1928-
1929-
/* The key expired if the current (virtual or real) time is greater
1930-
* than the expire time of the key. */
1931-
return now > when;
1932-
}
1933-
1934-
/* This function verify if the current conditions allow expiration of keys and fields.
1935-
* For some cases expiration is not allowed, but we would still like to ignore the key
1936-
* so to treat it as "expired" without actively deleting it. */
1937-
expirationPolicy getExpirationPolicyWithFlags(int flags) {
1938-
if (server.loading) return POLICY_IGNORE_EXPIRE;
1939-
1940-
/* If we are running in the context of a replica, instead of
1941-
* evicting the expired key from the database, we return ASAP:
1942-
* the replica key expiration is controlled by the primary that will
1943-
* send us synthesized DEL operations for expired keys. The
1944-
* exception is when write operations are performed on writable
1945-
* replicas.
1946-
*
1947-
* Still we try to reflect the correct state to the caller,
1948-
* that is, POLICY_KEEP_EXPIRED so that the key will be ignored, but not deleted.
1949-
*
1950-
* When replicating commands from the primary, keys are never considered
1951-
* expired, so we return POLICY_IGNORE_EXPIRE */
1952-
if (server.primary_host != NULL) {
1953-
if (server.current_client && (server.current_client->flag.primary)) return POLICY_IGNORE_EXPIRE;
1954-
if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) return POLICY_KEEP_EXPIRED;
1955-
} else if (server.import_mode) {
1956-
/* If we are running in the import mode on a primary, instead of
1957-
* evicting the expired key from the database, we return ASAP:
1958-
* the key expiration is controlled by the import source that will
1959-
* send us synthesized DEL operations for expired keys. The
1960-
* exception is when write operations are performed on this server
1961-
* because it's a primary.
1962-
*
1963-
* Notice: other clients, apart from the import source, should not access
1964-
* the data imported by import source.
1965-
*
1966-
* Still we try to reflect the correct state to the caller,
1967-
* that is, POLICY_KEEP_EXPIRED so that the key will be ignored, but not deleted.
1968-
*
1969-
* When receiving commands from the import source, keys are never considered
1970-
* expired, so we return POLICY_IGNORE_EXPIRE */
1971-
if (server.current_client && (server.current_client->flag.import_source)) return POLICY_IGNORE_EXPIRE;
1972-
if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) return POLICY_KEEP_EXPIRED;
1973-
}
1974-
1975-
/* In some cases we're explicitly instructed to return an indication of a
1976-
* missing key without actually deleting it, even on primaries. */
1977-
if (flags & EXPIRE_AVOID_DELETE_EXPIRED) return POLICY_KEEP_EXPIRED;
1978-
1979-
/* If 'expire' action is paused, for whatever reason, then don't expire any key.
1980-
* Typically, at the end of the pause we will properly expire the key OR we
1981-
* will have failed over and the new primary will send us the expire. */
1982-
if (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)) return POLICY_KEEP_EXPIRED;
1983-
1984-
return POLICY_DELETE_EXPIRED;
1985-
}
1986-
19871920
/* Use this instead of keyIsExpired if you already have the value object. */
19881921
static int objectIsExpired(robj *val) {
19891922
/* Don't expire anything while loading. It will be done later. */

src/entry.c

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
/* Returns true in case the entry's value is not embedded in the entry.
5252
* Returns false otherwise. */
53-
bool entryHasValuePtr(const entry *entry) {
53+
static inline bool entryHasValuePtr(const entry *entry) {
5454
return sdsGetAuxBit(entry, FIELD_SDS_AUX_BIT_ENTRY_HAS_VALUE_PTR);
5555
}
5656

@@ -81,8 +81,6 @@ sds entryGetValue(const entry *entry) {
8181
} else {
8282
/* Skip field content, field null terminator and value sds8 hdr. */
8383
size_t offset = sdslen(entry) + 1 + sdsHdrSize(SDS_TYPE_8);
84-
serverAssert((char *)entry + offset);
85-
8684
return (char *)entry + offset;
8785
}
8886
}
@@ -117,8 +115,9 @@ long long entryGetExpiry(const entry *entry) {
117115
long long expiry = EXPIRY_NONE;
118116
if (entryHasExpiry(entry)) {
119117
char *buf = sdsAllocPtr(entry);
118+
debugServerAssert((((uintptr_t)buf & 0x7) == 0));
120119
if (entryHasValuePtr(entry)) buf -= sizeof(sds *);
121-
buf -= sizeof(expiry);
120+
buf -= sizeof(long long);
122121
expiry = *(long long *)buf;
123122
}
124123
return expiry;
@@ -138,26 +137,21 @@ entry *entrySetExpiry(entry *e, long long expiry) {
138137
}
139138

140139
/* Return true in case the entry has assigned expiration or false otherwise. */
141-
int entryIsExpired(entry *entry) {
142-
/* Don't expire anything while loading. It will be done later. */
143-
if (server.loading) return 0;
144-
if (!timestampIsExpired(entryGetExpiry(entry))) return 0;
145-
if (server.primary_host == NULL && server.import_mode) {
146-
if (server.current_client && server.current_client->flag.import_source) return 0;
147-
}
148-
return 1;
140+
bool entryIsExpired(entry *entry) {
141+
if (!timestampIsExpired(entryGetExpiry(entry))) return false;
142+
return true;
149143
}
150144
/**************************************** Entry Expiry API - End *****************************************/
151145

152146
void entryFree(entry *entry) {
153147
if (entryHasValuePtr(entry)) {
154-
sdsfree(*entryGetValueRef(entry));
148+
sdsfree(entryGetValue(entry));
155149
}
156150
zfree(entryAllocPtr(entry));
157151
}
158152

159153
/* Takes ownership of value. does not take ownership of field */
160-
entry *entryCreate(sds field, sds value, long long expiry) {
154+
entry *entryCreate(const_sds field, sds value, long long expiry) {
161155
sds embedded_field_sds;
162156
size_t expiry_size = (expiry == EXPIRY_NONE) ? 0 : sizeof(long long);
163157
size_t field_len = sdslen(field);
@@ -192,7 +186,7 @@ entry *entryCreate(sds field, sds value, long long expiry) {
192186
* +------+-------+---------------+
193187
*/
194188
embed_value = false;
195-
alloc_size += sizeof(sds *);
189+
alloc_size += sizeof(sds);
196190
if (field_sds_type == SDS_TYPE_5) {
197191
field_sds_type = SDS_TYPE_8;
198192
alloc_size -= field_size;
@@ -214,8 +208,8 @@ entry *entryCreate(sds field, sds value, long long expiry) {
214208
if (value) {
215209
if (!embed_value) {
216210
*(sds *)buf = value;
217-
buf += sizeof(sds *);
218-
buf_size -= sizeof(sds *);
211+
buf += sizeof(sds);
212+
buf_size -= sizeof(sds);
219213
} else {
220214
sdswrite(buf + field_size, buf_size - field_size, SDS_TYPE_8, value, value_len);
221215
sdsfree(value);
@@ -237,13 +231,13 @@ entry *entryUpdate(entry *e, sds value, long long expiry) {
237231
sds field = (sds)e;
238232

239233
bool update_value = value ? true : false;
240-
long long ttl = entryGetExpiry(e);
241-
bool update_expiry = (expiry != ttl) ? true : false;
234+
long long expiration_time = entryGetExpiry(e);
235+
bool update_expiry = (expiry != expiration_time) ? true : false;
242236
if (!update_value && !update_expiry)
243237
return e;
244-
ttl = expiry;
238+
expiration_time = expiry;
245239
value = update_value ? value : entryGetValue(e);
246-
size_t expiry_size = ttl != EXPIRY_NONE ? sizeof(ttl) : 0;
240+
size_t expiry_size = (expiration_time != EXPIRY_NONE) ? sizeof(expiration_time) : 0;
247241
int field_sds_type = sdsReqType(sdslen(field));
248242
if (field_sds_type == SDS_TYPE_5 && (expiry_size > 0)) {
249243
field_sds_type = SDS_TYPE_8;
@@ -257,7 +251,7 @@ entry *entryUpdate(entry *e, sds value, long long expiry) {
257251
/* // We will create a new entry in the following cases:
258252
* 1. In the case were we add or remove expiration.
259253
* 2. in the case were we are NOT migrating from an embedded entry to an embedded entry with ~the same size. */
260-
bool create_new_entry = (update_expiry && (entryGetExpiry(e) == EXPIRY_NONE || ttl == EXPIRY_NONE)) ||
254+
bool create_new_entry = (update_expiry && (entryGetExpiry(e) == EXPIRY_NONE || expiration_time == EXPIRY_NONE)) ||
261255
!(update_value && !entryHasValuePtr(e) &&
262256
required_embedded_size <= EMBED_VALUE_MAX_ALLOC_SIZE &&
263257
required_embedded_size <= current_embedded_allocation_size &&
@@ -307,7 +301,7 @@ entry *entryUpdate(entry *e, sds value, long long expiry) {
307301
}
308302
}
309303

310-
entry *new_entry = entryCreate(entryGetField(e), value, ttl);
304+
entry *new_entry = entryCreate(entryGetField(e), value, expiration_time);
311305
if (new_entry != e)
312306
entryFree(e);
313307
return new_entry;
@@ -355,7 +349,7 @@ entry *entryDefrag(entry *entry, void *(*defragfn)(void *), sds (*sdsdefragfn)(s
355349

356350
/* Used for releasing memory to OS to avoid unnecessary CoW. Called when we've
357351
* forked and memory won't be used again. See zmadvise_dontneed() */
358-
void dismissEntry(entry *entry) {
352+
void entryDismissMemory(entry *entry) {
359353
/* Only dismiss values memory since the field size usually is small. */
360354
if (entryHasValuePtr(entry)) {
361355
dismissSds(*entryGetValueRef(entry));

src/entry.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ entry *entrySetValue(entry *entry, sds value);
1212
long long entryGetExpiry(const entry *entry);
1313
bool entryHasExpiry(const entry *entry);
1414
entry *entrySetExpiry(entry *entry, long long expiry);
15-
int entryIsExpired(entry *entry);
15+
bool entryIsExpired(entry *entry);
1616

1717
void entryFree(entry *entry);
18-
entry *entryCreate(sds field, sds value, long long expiry);
18+
entry *entryCreate(const_sds field, sds value, long long expiry);
1919
entry *entryUpdate(entry *entry, sds value, long long expiry);
2020
size_t entryMemUsage(entry *entry);
2121
entry *entryDefrag(entry *entry, void *(*defragfn)(void *), sds (*sdsdefragfn)(sds));
22-
void dismissEntry(entry *entry);
22+
void entryDismissMemory(entry *entry);
2323

2424
#endif

src/expire.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,3 +877,66 @@ void touchCommand(client *c) {
877877
if (lookupKeyRead(c->db, c->argv[j]) != NULL) touched++;
878878
addReplyLongLong(c, touched);
879879
}
880+
881+
/* Returns 1 if the expire value is expired, 0 otherwise. */
882+
int timestampIsExpired(mstime_t when) {
883+
if (when < 0) return 0; /* no expire */
884+
mstime_t now = commandTimeSnapshot();
885+
886+
/* The time indicated by 'when' is considered expired if the current (virtual or real) time is greater
887+
* than it. */
888+
return now > when;
889+
}
890+
891+
/* This function verify if the current conditions allow expiration of keys and fields.
892+
* For some cases expiration is not allowed, but we would still like to ignore the key
893+
* so to treat it as "expired" without actively deleting it. */
894+
expirationPolicy getExpirationPolicyWithFlags(int flags) {
895+
if (server.loading) return POLICY_IGNORE_EXPIRE;
896+
897+
/* If we are running in the context of a replica, instead of
898+
* evicting the expired key from the database, we return ASAP:
899+
* the replica key expiration is controlled by the primary that will
900+
* send us synthesized DEL operations for expired keys. The
901+
* exception is when write operations are performed on writable
902+
* replicas.
903+
*
904+
* Still we try to reflect the correct state to the caller,
905+
* that is, POLICY_KEEP_EXPIRED so that the key will be ignored, but not deleted.
906+
*
907+
* When replicating commands from the primary, keys are never considered
908+
* expired, so we return POLICY_IGNORE_EXPIRE */
909+
if (server.primary_host != NULL) {
910+
if (server.current_client && (server.current_client->flag.primary)) return POLICY_IGNORE_EXPIRE;
911+
if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) return POLICY_KEEP_EXPIRED;
912+
} else if (server.import_mode) {
913+
/* If we are running in the import mode on a primary, instead of
914+
* evicting the expired key from the database, we return ASAP:
915+
* the key expiration is controlled by the import source that will
916+
* send us synthesized DEL operations for expired keys. The
917+
* exception is when write operations are performed on this server
918+
* because it's a primary.
919+
*
920+
* Notice: other clients, apart from the import source, should not access
921+
* the data imported by import source.
922+
*
923+
* Still we try to reflect the correct state to the caller,
924+
* that is, POLICY_KEEP_EXPIRED so that the key will be ignored, but not deleted.
925+
*
926+
* When receiving commands from the import source, keys are never considered
927+
* expired, so we return POLICY_IGNORE_EXPIRE */
928+
if (server.current_client && (server.current_client->flag.import_source)) return POLICY_IGNORE_EXPIRE;
929+
if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) return POLICY_KEEP_EXPIRED;
930+
}
931+
932+
/* In some cases we're explicitly instructed to return an indication of a
933+
* missing key without actually deleting it, even on primaries. */
934+
if (flags & EXPIRE_AVOID_DELETE_EXPIRED) return POLICY_KEEP_EXPIRED;
935+
936+
/* If 'expire' action is paused, for whatever reason, then don't expire any key.
937+
* Typically, at the end of the pause we will properly expire the key OR we
938+
* will have failed over and the new primary will send us the expire. */
939+
if (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)) return POLICY_KEEP_EXPIRED;
940+
941+
return POLICY_DELETE_EXPIRED;
942+
}

src/expire.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include <time.h>
55
#include "monotonic.h"
66

7+
/* Flags for expireIfNeeded */
8+
#define EXPIRE_FORCE_DELETE_EXPIRED 1
9+
#define EXPIRE_AVOID_DELETE_EXPIRED 2
10+
711
#define ACTIVE_EXPIRE_CYCLE_SLOW 0
812
#define ACTIVE_EXPIRE_CYCLE_FAST 1
913

src/object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ void dismissHashObject(robj *o, size_t size_hint) {
683683
hashtableInitIterator(&iter, ht, 0);
684684
void *next;
685685
while (hashtableNext(&iter, &next)) {
686-
dismissEntry(next);
686+
entryDismissMemory(next);
687687
}
688688
hashtableResetIterator(&iter);
689689
}

0 commit comments

Comments
 (0)