Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parsing support for RDB_OPCODE_RAM_LRU for Redis Ent (No-op) #67

Merged
merged 2 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ destruction, or when newer block replacing old one.
Usage: rdb-cli /path/to/dump.rdb [OPTIONS] {print|json|resp|redis} [FORMAT_OPTIONS]
OPTIONS:
-l, --log-file <PATH> Path to the log file or stdout (Default: './rdb-cli.log')
-i, --ignore-checksum Ignore RDB file checksum verification
-s, --show-progress <MBytes> Show progress to STDOUT after every <MBytes> processed
-k, --key <REGEX> Include only keys that match REGEX
-K --no-key <REGEX> Exclude all keys that match REGEX
Expand Down Expand Up @@ -237,6 +238,7 @@ destruction, or when newer block replacing old one.
FORMAT_OPTIONS ('redis'|'resp'):
-r, --support-restore Use the RESTORE command when possible
-d, --del-before-write Delete each key before writing. Relevant for non-empty db
-f, --func-replace-if-exist Replace function-library if already exists in the same name rather than aborting
-t, --target-redis-ver <VER> Specify the target Redis version. Helps determine which commands can
be applied. Particularly crucial if support-restore being used
as RESTORE is closely tied to specific RDB versions. If versions not
Expand Down
9 changes: 9 additions & 0 deletions src/cli/rdb-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ FILE* logfile = NULL;
/* common options to all FORMATTERS */
typedef struct Options {
const char *logfilePath;
int ignoreChecksum;
int progressMb; /* print progress every <progressMb> MB. Set to 0 if disabled */
RdbRes (*formatFunc)(RdbParser *p, int argc, char **argv);
} Options;
Expand Down Expand Up @@ -102,6 +103,7 @@ static void printUsage(int shortUsage) {
printf("Usage: rdb-cli /path/to/dump.rdb [OPTIONS] {print|json|resp|redis} [FORMAT_OPTIONS]\n");
printf("OPTIONS:\n");
printf("\t-l, --log-file <PATH> Path to the log file or stdout (Default: './rdb-cli.log')\n");
printf("\t-i, --ignore-checksum Ignore RDB file checksum verification\n");
printf("\t-s, --show-progress <MBytes> Show progress to STDOUT after every <MBytes> processed\n");
printf("\t-k, --key <REGEX> Include only keys that match REGEX\n");
printf("\t-K --no-key <REGEX> Exclude all keys that match REGEX\n");
Expand Down Expand Up @@ -355,6 +357,7 @@ int readCommonOptions(RdbParser *p, int argc, char* argv[], Options *options, in
/* default */
options->progressMb = 0;
options->logfilePath = LOG_FILE_PATH_DEF;
options->ignoreChecksum = 0;
options->formatFunc = formatJson;

/* parse common options until FORMAT (json/resp/redis) specified */
Expand All @@ -363,6 +366,9 @@ int readCommonOptions(RdbParser *p, int argc, char* argv[], Options *options, in

if (getOptArg(argc, argv, &at, "-l", "--log-file", NULL, &(options->logfilePath)))
continue;

if (getOptArg(argc, argv, &at, "-i", "--ignore-checksum", &(options->ignoreChecksum), NULL))
continue;

if (getOptArgVal(argc, argv, &at, "-s", "--show-progress", NULL, &options->progressMb, 0, INT_MAX))
continue;
Expand Down Expand Up @@ -471,6 +477,9 @@ int main(int argc, char **argv)
RdbParser *parser = RDB_createParserRdb(NULL);
RDB_setLogLevel(parser, RDB_LOG_INF);
RDB_setLogger(parser, logger);

if (options.ignoreChecksum)
RDB_IgnoreChecksum(parser);

if (strcmp(input, "-") == 0) {
if (RDBX_createReaderFileDesc(parser, 0 /*stdin*/, 0) == NULL)
Expand Down
5 changes: 3 additions & 2 deletions src/lib/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@

/* Garantia V1006 (current) opcodes */
/*#define RDB_OPCODE_GD_DICT 100*/
#define RDB_OPCODE_GCAS 101
#define RDB_OPCODE_GFLAGS 102
#define RDB_OPCODE_GCAS 101
#define RDB_OPCODE_GFLAGS 102
#define __RDB_OPCODE_RAM_LRU 107 /* Available only in Redis Enterprise */

/* Defines related to the dump file format. To store 32 bits lengths for short
* keys requires a lot of space, so we check the most significant 2 bits of
Expand Down
13 changes: 13 additions & 0 deletions src/lib/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct ParsingElementInfo peInfo[PE_MAX] = {
[PE_EXPIRETIMEMSEC] = {elementExpireTimeMsec, "elementExpireTimeMsec", "Parsing expire-time-msec"},
[PE_FREQ] = {elementFreq, "elementFreq", "Parsing LFU frequency"},
[PE_IDLE] = {elementIdle, "elementIdle", "Parsing LRU idle time"},
[__PE_RAM_LRU] = {__elementRamLru, "elementRamLru", "Parsing RAM LRU Opcode. Relevant only for Redis Ent."},

[PE_NEW_KEY] = {elementNewKey, "elementNewKey", "Parsing new key-value"},
[PE_END_KEY] = {elementEndKey, "elementEndKey", "Parsing end key"},
Expand Down Expand Up @@ -1528,6 +1529,7 @@ RdbStatus elementNextRdbType(RdbParser *p) {
case RDB_OPCODE_RESIZEDB: return nextParsingElement(p, PE_RESIZE_DB);
case RDB_OPCODE_FREQ: return nextParsingElement(p, PE_FREQ);
case RDB_OPCODE_IDLE: return nextParsingElement(p, PE_IDLE);
case __RDB_OPCODE_RAM_LRU: return nextParsingElement(p, __PE_RAM_LRU);

/* string */
case RDB_TYPE_STRING: return nextParsingElementKeyValue(p, PE_RAW_STRING, PE_STRING);
Expand Down Expand Up @@ -1608,6 +1610,17 @@ RdbStatus elementIdle(RdbParser *p) {
return nextParsingElement(p, PE_NEXT_RDB_TYPE);
}

RdbStatus __elementRamLru(RdbParser *p) {
uint64_t dummy;
IF_NOT_OK_RETURN(rdbLoadLen(p, NULL, &dummy, NULL, NULL));

/*** ENTER SAFE STATE ***/

/* Do nothing. Relevant only for Redis Ent. */

return nextParsingElement(p, PE_NEXT_RDB_TYPE);
}

/*** Parsing data-types Elements ***/

RdbStatus elementString(RdbParser *p) {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ typedef enum ParsingElementType {
PE_EXPIRETIMEMSEC,
PE_FREQ,
PE_IDLE,
__PE_RAM_LRU, /* Redis Enterprise specific */

PE_NEW_KEY,
PE_END_KEY,
Expand Down Expand Up @@ -529,6 +530,7 @@ RdbStatus elementExpireTime(RdbParser *p);
RdbStatus elementExpireTimeMsec(RdbParser *p);
RdbStatus elementFreq(RdbParser *p);
RdbStatus elementIdle(RdbParser *p);
RdbStatus __elementRamLru(RdbParser *p);

/*** Struct/Data Parsing Elements ***/
RdbStatus elementString(RdbParser *p);
Expand Down
Binary file added test/dumps/redis_ent_opcode_ram_lru.rdb
Binary file not shown.
19 changes: 19 additions & 0 deletions test/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,24 @@ static void test_checksum(void **state) {
RDB_deleteParser(parser);
}

/* Test opcode relevant only to Redis Ent (Does nothing) */
static void __test_opcode_ram_lru(void **state) {
UNUSED(state);

const char *rdbfile = DUMP_FOLDER("redis_ent_opcode_ram_lru.rdb");
//const char *jsonfile = TMP_FOLDER("empty.json");

RdbStatus status;
RdbParser *parser = RDB_createParserRdb(NULL);
RDB_setLogLevel(parser, RDB_LOG_ERR);
assert_non_null(RDBX_createReaderFile(parser, rdbfile));

while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA);
assert_int_equal( status, RDB_STATUS_OK);

RDB_deleteParser(parser);
}

static void test_examples(void **state) {
UNUSED(state);
runSystemCmd("make example > /dev/null ");
Expand Down Expand Up @@ -223,6 +241,7 @@ int group_misc(void) {
cmocka_unit_test(test_empty_rdb),
cmocka_unit_test(test_mixed_levels_registration),
cmocka_unit_test(test_checksum),
cmocka_unit_test(__test_opcode_ram_lru),
cmocka_unit_test(test_report_long_error),
cmocka_unit_test(test_not_support_future_rdb_version),
};
Expand Down