LPush command - #40
Conversation
📝 WalkthroughWalkthroughAdds an LPUSH command implementation and registers it; refactors RPUSH to use an atomic compute API; introduces RedisDatabase.compute for atomic read-modify-write with expiry semantics; and adds unit tests for LPUSH behavior and interactions. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Registry as CommandRegistry
participant Cmd as LPushCommand
participant DB as RedisDatabase
participant Store as Storage
Client->>Registry: "LPUSH key v1 v2"
Registry->>Cmd: dispatch LPUSH
Cmd->>DB: compute(key, remappingFunction)
DB->>Store: ConcurrentHashMap.compute callback (read current value)
Store-->>DB: existing RedisValue or null
DB->>Store: write updated RedisValue (new LinkedList with prepended items)
Store-->>DB: ack
DB-->>Cmd: new size / updated value
Cmd-->>Client: RESP integer reply with new size
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
Docstrings generation was requested by @unikdahal. * #37 (comment) The following files were modified: * `src/main/java/com/redis/commands/CommandRegistry.java` * `src/main/java/com/redis/commands/RPushCommand.java` * `src/main/java/com/redis/server/RedisCommandHandler.java` # Conflicts: # src/main/java/com/redis/commands/RPushCommand.java
# Conflicts: # src/main/java/com/redis/commands/CommandRegistry.java
…O(n) in case of linked list
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/main/java/com/redis/storage/RedisDatabase.java`:
- Around line 206-227: The compute method currently drops TTL whenever
remappingFunction returns a new RedisValue instance; change the expiry logic in
compute (inside map.compute lambda) to preserve the existingEntry.expiryMillis
if the key existed and was not expired (use isExpired(existingEntry) check) so
updates like LPUSH/RPUSH that return new RedisValue objects keep the TTL; only
set Long.MAX_VALUE for non-existent or expired entries (and still return null
when remappingFunction returns null to remove the key). Reference: compute,
map.compute, existingEntry, isExpired(existingEntry), expiryMillis, ValueEntry,
remappingFunction, RedisValue.
🧹 Nitpick comments (1)
src/test/java/com/redis/commands/LPushCommandTest.java (1)
132-140: Avoid tying tests to internal list implementation
testLPush_UsesLinkedListlocks behavior toLinkedList, which is an internal detail and makes refactors harder without improving correctness coverage. Consider removing this test or asserting behavior only.♻️ Possible adjustment
- `@Test` - void testLPush_UsesLinkedList() { - db.remove("linkedtest"); - - command.execute(List.of("linkedtest", "element"), ctx); - - RedisValue value = db.getValue("linkedtest"); - assertTrue(value.getData() instanceof LinkedList<?>); - - db.remove("linkedtest"); - } + // Consider removing this test or validating only ordering/size behavior.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/redis/commands/CommandRegistry.java (1)
22-26: Stale Javadoc - missing LRangeCommand and LPushCommand.The constructor Javadoc lists only "SetCommand, GetCommand, DelCommand, and RPushCommand" but the registry now also includes
LRangeCommandandLPushCommand.📝 Suggested documentation update
/** * Initializes the singleton CommandRegistry and registers the built-in commands. * - * Registers the default command implementations: SetCommand, GetCommand, DelCommand, and RPushCommand. + * Registers the default command implementations: SetCommand, GetCommand, DelCommand, RPushCommand, LRangeCommand, and LPushCommand. */
LPush command
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.