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

Change BITCOUNT 'end' as optional like BITPOS #118

Merged
merged 12 commits into from
May 28, 2024

Conversation

LiiNen
Copy link
Contributor

@LiiNen LiiNen commented Apr 1, 2024

This change is the thing I suggested to redis when it was BSD, and is not just migration - this is of course more advanced

Issue

There is weird difference in syntax between BITPOS and BITCOUNT:

BITPOS key bit [start [end [BYTE | BIT]]]
BITCOUNT key [start end [BYTE | BIT]]

I think this might cause confusion in terms of usability.
It was not just a syntax typo error, and really works differently.
The results below are with unstable build:

> get TEST:ABCD
"ABCD"
> BITPOS TEST:ABCD 1 0 -1
(integer) 1
> BITCOUNT TEST:ABCD 0 -1
(integer) 9
> BITPOS TEST:ABCD 1 0
(integer) 1
> BITCOUNT TEST:ABCD 0
(error) ERR syntax error

What did I fix

simply changes logic, to accept BITCOUNT also without 'end' - 'end' become optional, like BITPOS

> GET TEST:ABCD
"ABCD"
> BITPOS TEST:ABCD 1 0 -1
(integer) 1
> BITCOUNT TEST:ABCD 0 -1
(integer) 9
> BITPOS TEST:ABCD 1 0
(integer) 1
> BITCOUNT TEST:ABCD 0
(integer) 9

Of course, I also fixed syntax hint:

# ASIS 
> BITCOUNT key [start end [BYTE|BIT]]
# TOBE
> BITCOUNT key [start [end [BYTE|BIT]]]

image

Moreover ...

I hadn't noticed that there was very small dead code in these command logic, when I wrote PR to redis.
I found it now, when write code again, so I wrote it in valkey.

/* asis unstable */

/* bitcountCommand() */
if (!strcasecmp(c->argv[4]->ptr,"bit")) isbit = 1;
// ...
if (c->argc < 4) {
    if (isbit) end = (totlen<<3) + 7;
    else end = totlen-1;
}

/* bitposCommand() */
if (!strcasecmp(c->argv[5]->ptr,"bit")) isbit = 1;
// ...
if (c->argc < 5) {
    if (isbit) end = (totlen<<3) + 7;
    else end = totlen-1;
}

Bit variable (actually int) "isbit" is only being set as 1, when 'BIT' is declared.
But we were checking whether 'isbit' is true or false in this 'if' phrase, even if isbit could never be 1, because argc is always less than 4 (or 5 in bitpos).

I think this minor fixes will make valkey command operation more consistent.
Of course, this PR contains just changing args from "required" to "optional", so it will never hurt previous users.

Thanks,

@madolson madolson added the major-decision-pending Major decision pending by TSC team label Apr 2, 2024
tests/unit/bitops.tcl Outdated Show resolved Hide resolved
@LiiNen
Copy link
Contributor Author

LiiNen commented Apr 2, 2024

updated it and run COMMAND DOCS for checking it works properly
image

Note. github commit with 'commit suggestion' won't let me signoff ;-; didnt know that

LiiNen and others added 9 commits April 2, 2024 21:57
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
in case of end is not declared, BYTE|BIT cannot be used, so variable 'isbit' is always 0

Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com>
Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
@LiiNen
Copy link
Contributor Author

LiiNen commented Apr 2, 2024

rebase to avoid spellcheck issue: #139

@LiiNen
Copy link
Contributor Author

LiiNen commented Apr 2, 2024

seems like issues in testfile. I'll check it

edited)
I have missed that bitcount now accept without end. Removed it in tcl.

assert_error {ERR *syntax*} {r bitcount s 0}

p.s. I have changed it when I made PR to redis, but just missed it in here by human(my) fault 😅

Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
@zuiderkwast zuiderkwast added the enhancement New feature or request label Apr 2, 2024
assert_equal [r bitcount s 0] [count_bits "foobar"]
assert_equal [r bitcount s 1] [count_bits "oobar"]
assert_equal [r bitcount s -1] [count_bits "r"]
assert_equal [r bitcount s -2] [count_bits "ar"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add several special cases which include larger value of start, such as start = 10 or 50, Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add some new test cases in near days. thxs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added more testcases; 843c84a

  1. Larger value of start as you said
  2. Larger negative value of start.
  3. Also added large negative value in BITCOUNT with start, end
  4. fix [count_bits ""] -> 0, when start > end if it is in the range of string (line 147)

Copy link
Contributor Author

@LiiNen LiiNen Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: you said larger value as 10 or 50 for example, but the value 1000 is already used from others, so I also use 1000 :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hwware gently ping, just wondered if you didn't receive above comments alarm.
i hope it didn't bother you.

"type": "pure-token",
"token": "BYTE"
"name": "end",
"type": "integer"
Copy link
Contributor Author

@LiiNen LiiNen Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end is in optional block, so this is useless I think.
I saw syntax again and below is what I have changed.

BITPOS key bit [start [end [BYTE | BIT]]]
BITCOUNT key [start end [BYTE | BIT]] -> BITCOUNT key [start [end [BYTE | BIT]]]

If end is also optional, then the syntax should be like below:

BITCOUNT key [start [[end] [BYTE | BIT]]]

I didn't think it before, and it seems this is also maybe reasonable - allowing using just 'start' and '[BYTE | BIT]'.
But in this case, it is harmful for backwards compatibility, and maybe critical to client libraries.

ex. BITCOUNT key start BYTE will be think as BITCOUNT key start end in client libraries, and will be return error because end is just string 'BYTE'.

It will be a quiet issue. Is this what you meant?

@hwware
Copy link
Member

hwware commented Apr 24, 2024

You are right. Just ignore my suggestion code changes and keep current json file.
For this PR, just add more several edge cases and I will approve it, Thanks

@hwware
Copy link
Member

hwware commented Apr 24, 2024

But I doubt, maybe for BITPOS and BITCOUNT, the command format:
BITPOS key bit start BYTE | BIT
BITCOUNT key start BYTE | BIT
should be acceptable as well in the future because end is optional

Let us discuss this later

@LiiNen
Copy link
Contributor Author

LiiNen commented Apr 25, 2024

I agree. If there is no need to consider backward compatibility, then me also want to change: using BYTE|BIT without end.
This might also affect aof, so this have to be discussed later 😢

In case of testcase, I'll work on it asap when i have time :)

Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Copy link

codecov bot commented Apr 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 70.19%. Comparing base (e4ead94) to head (153625c).

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable     #118      +/-   ##
============================================
- Coverage     70.22%   70.19%   -0.04%     
============================================
  Files           109      109              
  Lines         59880    59879       -1     
============================================
- Hits          42051    42030      -21     
- Misses        17829    17849      +20     
Files Coverage Δ
src/bitops.c 94.03% <100.00%> (+0.29%) ⬆️
src/commands.def 100.00% <ø> (ø)

... and 8 files with indirect coverage changes

@madolson madolson requested a review from hwware May 27, 2024 14:18
@madolson madolson added major-decision-approved Major decision approved by TSC team and removed major-decision-pending Major decision pending by TSC team labels May 27, 2024
@madolson
Copy link
Member

But I doubt, maybe for BITPOS and BITCOUNT, the command format:
BITPOS key bit start BYTE | BIT
BITCOUNT key start BYTE | BIT
should be acceptable as well in the future because end is optional

We can solve this problem in the future.

Discussed in separate meeting, directionally LGTM, just need someone to review the code and merge.

@madolson madolson added the release-notes This issue should get a line item in the release notes label May 27, 2024
@LiiNen
Copy link
Contributor Author

LiiNen commented May 27, 2024

seems like conflicts came out due to modifying language format (#323)
I'll resolve it in my branch and commit once more

Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
@LiiNen
Copy link
Contributor Author

LiiNen commented May 27, 2024

update done.

while fixing conflict, found small typo against lint, so it also have been fixed.

/* line 798 in src/bitops.c */
// before fix
if (c-> argc == 3 

// after fix ( remove space between '>' and 'a' )
if (c->argc == 3 

@hwware hwware merged commit 96dcd11 into valkey-io:unstable May 28, 2024
18 checks passed
@srgsanky
Copy link
Contributor

There is a clang-format issue from this commit found while trying to submit another commit - https://github.com/valkey-io/valkey/actions/runs/9279101016/job/25531813775. Can you fix it?

diff --git a/src/bitops.c b/src/bitops.c
index 7a385812d..2094bb0ea 100644
--- a/src/bitops.c
+++ b/src/bitops.c
@@ -808,10 +808,9 @@ void bitcountCommand(client *c) {
             }
         }
         if (c->argc >= 4) {
-            if (getLongLongFromObjectOrReply(c,c->argv[3],&end,NULL) != C_OK)
-                return;
+            if (getLongLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK) return;
         }
-
+
         /* Lookup, check for type. */
         o = lookupKeyRead(c->db, c->argv[1]);
         if (checkType(c, o, OBJ_STRING)) return;
@@ -821,7 +820,7 @@ void bitcountCommand(client *c) {
         /* Make sure we will not overflow */
         serverAssert(totlen <= LLONG_MAX >> 3);

-        if (c->argc < 4) end = totlen-1;
+        if (c->argc < 4) end = totlen - 1;

         /* Convert negative indexes */
         if (start < 0 && end < 0 && start > end) {

@LiiNen
Copy link
Contributor Author

LiiNen commented May 29, 2024

@srgsanky sorry I dont know why but i missed it.
but this PR already closed (merged) today, so I write a simple change as PR #570
I'll left this also in your PR. thanks that let me know about it.

PingXie pushed a commit that referenced this pull request May 29, 2024
ref:
- #118 (my pervious change)
- #461 (issuing that clang
format checker fails due to my change)

There was an issue that clang-format cheker failed.
I don't know why I missed it and why it didn't catch.

just running `clang-format -i bitops.c` was all.

Signed-off-by: LiiNen <kjeonghoon065@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request major-decision-approved Major decision approved by TSC team release-notes This issue should get a line item in the release notes
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants