From af7489886dab9362e4661a3015ac606025710686 Mon Sep 17 00:00:00 2001 From: guybe7 Date: Thu, 18 Nov 2021 10:47:49 +0200 Subject: Obliterate STRALGO! add LCS (which only works on keys) (#9799) Drop the STRALGO command, now LCS is a command of its own and it only works on keys (not input strings). The motivation is that STRALGO's syntax was really messed-up... - assumes all (future) string algorithms will take similar arguments - mixes command that takes keys and one that doesn't in the same command. - make it nearly impossible to expose the right key spec in COMMAND INFO (issues cluster clients) - hard for cluster clients to determine the key names (firstkey, lastkey, etc) - hard for ACL / flags (is it a read command?) This is a breaking change. --- src/t_string.c | 89 +++++++++++++++------------------------------------------- 1 file changed, 23 insertions(+), 66 deletions(-) (limited to 'src/t_string.c') diff --git a/src/t_string.c b/src/t_string.c index e1917958b..d4334b1eb 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -726,40 +726,33 @@ void strlenCommand(client *c) { addReplyLongLong(c,stringObjectLen(o)); } - -/* STRALGO -- Implement complex algorithms on strings. - * - * STRALGO ... arguments ... */ -void stralgoLCS(client *c); /* This implements the LCS algorithm. */ -void stralgoCommand(client *c) { - char *subcmd = c->argv[1]->ptr; - - if (c->argc == 2 && !strcasecmp(subcmd,"help")) { - const char *help[] = { -"LCS", -" Run the longest common subsequence algorithm.", -NULL - }; - addReplyHelp(c, help); - } else if (!strcasecmp(subcmd,"lcs")) { - stralgoLCS(c); - } else { - addReplySubcommandSyntaxError(c); - return; - } -} - -/* STRALGO [IDX] [LEN] [MINMATCHLEN ] [WITHMATCHLEN] - * STRINGS | KEYS - */ -void stralgoLCS(client *c) { +/* LCS key1 key2 [LEN] [IDX] [MINMATCHLEN ] [WITHMATCHLEN] */ +void lcsCommand(client *c) { uint32_t i, j; long long minmatchlen = 0; sds a = NULL, b = NULL; int getlen = 0, getidx = 0, withmatchlen = 0; robj *obja = NULL, *objb = NULL; - for (j = 2; j < (uint32_t)c->argc; j++) { + obja = lookupKeyRead(c->db,c->argv[1]); + objb = lookupKeyRead(c->db,c->argv[2]); + if ((obja && obja->type != OBJ_STRING) || + (objb && objb->type != OBJ_STRING)) + { + addReplyError(c, + "The specified keys must contain string values"); + /* Don't cleanup the objects, we need to do that + * only after calling getDecodedObject(). */ + obja = NULL; + objb = NULL; + goto cleanup; + } + obja = obja ? getDecodedObject(obja) : createStringObject("",0); + objb = objb ? getDecodedObject(objb) : createStringObject("",0); + a = obja->ptr; + b = objb->ptr; + + for (j = 3; j < (uint32_t)c->argc; j++) { char *opt = c->argv[j]->ptr; int moreargs = (c->argc-1) - j; @@ -774,37 +767,6 @@ void stralgoLCS(client *c) { != C_OK) goto cleanup; if (minmatchlen < 0) minmatchlen = 0; j++; - } else if (!strcasecmp(opt,"STRINGS") && moreargs > 1) { - if (a != NULL) { - addReplyError(c,"Either use STRINGS or KEYS"); - goto cleanup; - } - a = c->argv[j+1]->ptr; - b = c->argv[j+2]->ptr; - j += 2; - } else if (!strcasecmp(opt,"KEYS") && moreargs > 1) { - if (a != NULL) { - addReplyError(c,"Either use STRINGS or KEYS"); - goto cleanup; - } - obja = lookupKeyRead(c->db,c->argv[j+1]); - objb = lookupKeyRead(c->db,c->argv[j+2]); - if ((obja && obja->type != OBJ_STRING) || - (objb && objb->type != OBJ_STRING)) - { - addReplyError(c, - "The specified keys must contain string values"); - /* Don't cleanup the objects, we need to do that - * only after calling getDecodedObject(). */ - obja = NULL; - objb = NULL; - goto cleanup; - } - obja = obja ? getDecodedObject(obja) : createStringObject("",0); - objb = objb ? getDecodedObject(objb) : createStringObject("",0); - a = obja->ptr; - b = objb->ptr; - j += 2; } else { addReplyErrorObject(c,shared.syntaxerr); goto cleanup; @@ -812,14 +774,9 @@ void stralgoLCS(client *c) { } /* Complain if the user passed ambiguous parameters. */ - if (a == NULL) { - addReplyError(c,"Please specify two strings: " - "STRINGS or KEYS options are mandatory"); - goto cleanup; - } else if (getlen && getidx) { + if (getlen && getidx) { addReplyError(c, - "If you want both the length and indexes, please " - "just use IDX."); + "If you want both the length and indexes, please just use IDX."); goto cleanup; } -- cgit v1.2.1