Skip to content

feat: implement KEYS command#68

Merged
AlexJuca merged 3 commits intoAlexJuca:mainfrom
ithustle:feat/keys-command
May 8, 2026
Merged

feat: implement KEYS command#68
AlexJuca merged 3 commits intoAlexJuca:mainfrom
ithustle:feat/keys-command

Conversation

@ithustle
Copy link
Copy Markdown
Contributor

@ithustle ithustle commented Mar 1, 2026

Summary

  • Add KEYS command (CMD 0x0D) that lists all non-expired keys in numbered format (1) key1\n2) key2\n)
  • Dedicated send_keys_reply() tags the response frame with CMD_KEYS so the client correctly handles empty lists ((empty list)) vs key listings (raw text, no quotes)
  • Server handler iterates hash table with safe next pointer caching, lazy expiration via check_and_expire(), and dynamic buffer with realloc growth (max ~65500 bytes)
  • 4 integration tests: empty store, multiple keys, expired key exclusion, key after DEL

Files changed (11)

  • command_defs.h — #define CMD_KEYS 0x0D
  • command_parser.h/c — construct_keys_command()
  • command_registry.h/c — send_keys_reply()
  • server_command_handlers.h/c — handle_keys_command() + registration
  • client_command_handlers.h/c — cmd_keys(), command_table[], cmd_unknown() filter, CMD_KEYS response branch
  • README.md — KEYS added to Server commands table
  • test_integration.c — 4 new tests

Test plan

  • make -f Makefile.fkvs build — compiles without new warnings
  • ctest --output-on-failure — all 3 test suites pass (39 tests total)

Test project /Users/ithustle/dev/server/fkvs
Start 1: CounterTest
1/3 Test #1: CounterTest ...................... Passed 0.00 sec
Start 2: StringUtilsTest
2/3 Test #2: StringUtilsTest .................. Passed 0.00 sec
Start 3: IntegrationTest
3/3 Test #3: IntegrationTest .................. Passed 18.77 sec

100% tests passed, 0 tests failed out of 3

Total Test time (real) = 18.77 sec

Add KEYS command that returns all non-expired keys in numbered format.
Uses dedicated send_keys_reply() with CMD_KEYS tag in the response frame
so the client can distinguish KEYS responses (empty list vs key listing)
from generic replies. Server-side handler iterates the hash table with
safe next-pointer caching and lazy expiration, using a dynamic buffer
with realloc growth up to the 65500-byte frame limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AlexJuca
Copy link
Copy Markdown
Owner

@ithustle I will have a look at these during this week.

@AlexJuca AlexJuca added enhancement New feature or request labels Apr 27, 2026
@AlexJuca AlexJuca assigned ithustle and unassigned ithustle Apr 27, 2026
@AlexJuca AlexJuca self-requested a review April 27, 2026 10:22
@AlexJuca
Copy link
Copy Markdown
Owner

AlexJuca commented May 4, 2026

@ithustle Did you test this implementation?

@ithustle
Copy link
Copy Markdown
Contributor Author

ithustle commented May 4, 2026

@ithustle Did you test this implementation?

@AlexJuca yes I did. In fact, I’m using this feature on fkvs locally

@AlexJuca
Copy link
Copy Markdown
Owner

AlexJuca commented May 8, 2026

@ithustle Did you test this implementation?

@AlexJuca yes I did. In fact, I’m using this feature on fkvs locally

Cool, I found and fixed a few issues while reviewing the PR.

  • The branch was out of date with main, which made the PR unmergeable.
  • KEYS accepted malformed frames instead of validating the exact command shape.
  • The CLI treated any command starting with KEYS as valid, for example KEYSPACE.
  • Large KEYS responses could silently truncate instead of returning an error.
  • Sanitizers found a use-after-free when KEYS expired keys while iterating the store.

These are the fixes I applied:

  • Merged the latest main.
  • Added strict server-side validation for KEYS frames.
  • Tightened CLI command matching so only KEYS is accepted.
  • Changed oversized KEYS responses to return an error instead of partial output.
  • Fixed expiry deletion order to avoid using a freed key pointer.
  • Added regression tests for malformed KEYS frames and oversized output.

@AlexJuca
Copy link
Copy Markdown
Owner

AlexJuca commented May 8, 2026

@ithustle I've added several improvements to harden the implement. Thanks a bunch for the preliminary implementation. 💪🏾

Merging.

@AlexJuca AlexJuca merged commit d00cb33 into AlexJuca:main May 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants