I’m stuck on Stage #LA7
I’ve tried debugging the code with some print statement.
The program suddenly stops when no expiry time is provided but works fine when the expiry time is given.
Here are my logs:
[tester::#LA7] Running tests for Stage #LA7 (Implement the SET & GET commands)
[tester::#LA7] $ ./your_program.sh
[your_program] Server started. Logs will appear here!
[tester::#LA7] Setting key raspberry to mango
[tester::#LA7] $ redis-cli SET raspberry mango
[tester::#LA7] Sent bytes: "*3\r\n$3\r\nSET\r\n$9\r\nraspberry\r\n$5\r\nmango\r\n"
[your_program] Received: *3
[your_program] Received: $3
[your_program] Received: SET
[your_program] Going to read time variable size
[tester::#LA7] Received: "" (no content received)
[tester::#LA7] ^ error
[tester::#LA7] Error: Expected start of a new RESP2 value (either +, -, :, $ or *)
[tester::#LA7] Test failed
[tester::#LA7] Terminating program
[tester::#LA7] Program terminated successfully
I have tried creating a client at my side and sent the string to set command i.e
String setCommand = “*5\r\n$3\r\nSET\r\n$6\r\norange\r\n$6\r\nbanana\r\n”;
I have mentioned the code for get & set and the client which I have created to test the set command
The test case ran successfully here are my logs
harsh@ubuntu:~/Desktop/codecrafters-redis-java/src/main/java$ java Main
Server started. Logs will appear here!
Received: *5
Received: $3
Received: SET
Going to read time variable size
No valid expiry provided
setting up no expiry time
Received: $3
Received: GET
in 1st if condition
value is banana
Here is the code for client that i have made
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
String hostname = "localhost"; // Assuming the server is running on localhost
int port = 6379;
try (Socket socket = new Socket(hostname, port)) {
// OutputStream to send data to the server
OutputStream outputStream = socket.getOutputStream();
// InputStream to read response from the server
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Send the SET command with expiry argument (PX) in RESP2 format
// String setCommand = "*5\r\n$3\r\nSET\r\n$6\r\norange\r\n$6\r\nbanana\r\n$2\r\npx\r\n$3\r\n100\r\n";
String setCommand = "*5\r\n$3\r\nSET\r\n$6\r\norange\r\n$6\r\nbanana\r\n";
outputStream.write(setCommand.getBytes());
outputStream.flush();
// Send the GET command in RESP2 format
String getCommand = "*2\r\n$3\r\nGET\r\n$6\r\norange\r\n";
outputStream.write(getCommand.getBytes());
outputStream.flush();
// Now start reading the server's response
String response;
while ((response = in.readLine()) != null) {
System.out.println("Server Response: " + response);
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Here’s a snippet of my code for get and set :
import java.util.Map;
public class GetSet {
// method to get value based on key if key is not expired
public static Object getValue(Map<String, Object[]> map, String key) {
Object[] value = map.get(key);
if(value.length == 1){
System.out.println("in 1st if condition");
return value[0];
}
// check if key got expired
else if (checkKeyExpiry((long)value[1], (long) value[2])) {
//return value
System.out.println("in elif condtion");
return value[0];
} else {
System.out.println("in else condtion");
map.remove(key);
return null;
}
}
// Method for inserting the key with expiry time
public static void setKeyWithExpiry(Map<String,Object[]> map, String key,String value, long expiryTime){
if(expiryTime !=-1){
long insertionTimeOfKey = System.currentTimeMillis();
map.put(key,new Object[]{value,expiryTime,insertionTimeOfKey});
}else{
System.out.println("setting up no expiry time ");
map.put(key,new Object[]{value});
}
}
// method to check weather the key has expired or not
private static boolean checkKeyExpiry(long expiryTime , long insertionTimeOfKey){
return System.currentTimeMillis() - insertionTimeOfKey < expiryTime;
}
}
and here is the code from where the set and get are being called
for set
else if("SET".equalsIgnoreCase(inputLine)){
in.readLine(); // skipping size of key --> $9
String key = in.readLine(); // extracting the actual key --> raspberry
in.readLine(); // skipping size of value --> $6
String value = in.readLine(); // extracting the actual value --> banana
System.out.println("Going to read time variable size");
String sizeOfTimeVariable = in.readLine();// skipping size of time variable --> $2
if(sizeOfTimeVariable !=null && sizeOfTimeVariable.startsWith("$"))
{
in.readLine(); // skipping time variable --> px
in.readLine(); // skipping size of time in millisecond --> $3
try{
long expTime= Long.parseLong(in.readLine()); // extracting the actual time
GetSet.setKeyWithExpiry(map,key,value,expTime);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
else{
System.out.println("No valid expiry provided");
GetSet.setKeyWithExpiry(map,key,value,-1);
}
clientSocket.getOutputStream().write("+OK\r\n".getBytes());
clientSocket.getOutputStream().flush();
}
for get
else if ("GET".equalsIgnoreCase(inputLine)) {
in.readLine(); // Read size of key
String key = in.readLine(); // Read key
Object value = GetSet.getValue(map, key);
System.out.println("value is " + value);
if (value != null) {
clientSocket.getOutputStream().write(
String.format("$%d\r\n%s\r\n", value.toString().length(), value).getBytes());
} else {
clientSocket.getOutputStream().write("$-1\r\n".getBytes()); // Correctly formatted null response
}
clientSocket.getOutputStream().flush();
}