From eaa7a7bb93c1ac6dbf347e1c29ac719a12a75158 Mon Sep 17 00:00:00 2001 From: Huang Zhw Date: Mon, 7 Jun 2021 19:43:36 +0800 Subject: [PATCH] Fix XTRIM or XADD with LIMIT may delete more entries than Count. (#9048) The decision to stop trimming due to LIMIT in XADD and XTRIM was after the limit was reached. i.e. the code was deleting **at least** that count of records (from the LIMIT argument's perspective, not the MAXLEN), instead of **up to** that count of records. see #9046 --- src/t_stream.c | 8 ++++---- tests/unit/type/stream.tcl | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/t_stream.c b/src/t_stream.c index 7c8a288c8ed8..678fceeee62b 100644 --- a/src/t_stream.c +++ b/src/t_stream.c @@ -702,16 +702,16 @@ int64_t streamTrim(stream *s, streamAddTrimArgs *args) { int64_t deleted = 0; while (raxNext(&ri)) { - /* Check if we exceeded the amount of work we could do */ - if (limit && deleted >= limit) - break; - if (trim_strategy == TRIM_STRATEGY_MAXLEN && s->length <= maxlen) break; unsigned char *lp = ri.data, *p = lpFirst(lp); int64_t entries = lpGetInteger(p); + /* Check if we exceeded the amount of work we could do */ + if (limit && (deleted + entries) > limit) + break; + /* Check if we can remove the whole node. */ int remove_node; streamID master_id = {0}; /* For MINID */ diff --git a/tests/unit/type/stream.tcl b/tests/unit/type/stream.tcl index a89a6529973f..f1ee56a8a2c9 100644 --- a/tests/unit/type/stream.tcl +++ b/tests/unit/type/stream.tcl @@ -199,6 +199,15 @@ start_server { assert {[r EXISTS otherstream] == 0} } + test {XADD with LIMIT delete entries no more than limit} { + r del yourstream + for {set j 0} {$j < 3} {incr j} { + r XADD yourstream * xitem v + } + r XADD yourstream MAXLEN ~ 0 limit 1 * xitem v + assert {[r XLEN yourstream] == 4} + } + test {XRANGE COUNT works as expected} { assert {[llength [r xrange mystream - + COUNT 10]] == 10} } @@ -525,6 +534,16 @@ start_server { } assert_error ERR* {r XTRIM mystream MAXLEN 1 LIMIT 30} } + + test {XTRIM with LIMIT delete entries no more than limit} { + r del mystream + r config set stream-node-max-entries 2 + for {set j 0} {$j < 3} {incr j} { + r XADD mystream * xitem v + } + assert {[r XTRIM mystream MAXLEN ~ 0 LIMIT 1] == 0} + assert {[r XTRIM mystream MAXLEN ~ 0 LIMIT 2] == 2} + } } start_server {tags {"stream"} overrides {appendonly yes}} {