I’m stuck on stage 26. Would it be possible to get RDB file for proper parsing? I am following RDB File Format and it would be helpful to get file for local test.
FB # Indicates a resizedb field
$length-encoded-int # Size of the corresponding hash table
$length-encoded-int # Size of the corresponding expire hash table
As per this block, I am expecting 2 integers however as per my logs, second integer is of value 0.
Here are my logs:
remote: [your_program] REDIS version: 0003
remote: [your_program] read_key_value, key: "redis-ver", value: "7.2.0"
remote: [your_program] 0xFA block, key: "redis-ver", value: "7.2.0"
remote: [your_program] read_key_value, key: "redis-bits", value: "@"
remote: [your_program] 0xFA block, key: "redis-bits", value: "@"
remote: [your_program] 0XFE block - DB Number: 0
remote: [your_program] Found first integer of length: 1
remote: [your_program] Found second integer of length: 0
remote: [your_program] 0xFB block, value1: 0, value2: 0
And here’s a snippet of my code:
println!("REDIS version: {}", String::from_utf8(signature[5..].to_vec()).unwrap());
let mut db_num = [0; 1];
loop {
//read next byte to interpret what type it is?
let mut opcode = [0; 1];
reader.read_exact(&mut opcode)?;
match opcode[0] {
0xFA => {
if let Ok((key, value)) = Self::read_key_value(&mut reader) {
println!("0xFA block, key: {:?}, value: {:?}",
String::from_utf8_lossy(&key),
String::from_utf8_lossy(&value));
}
},
0xFB => {
// read length encoded int
if let Ok(len1) = Self::encoded_length(&mut reader) {
println!("Found first integer of length: {}", len1);
let mut value1 = vec![0; len1];
reader.read_exact(&mut value1)?;
let hash_table_sz = match len1 {
1 => value1[0] as usize,
2 => 110, //u16::from_ne_bytes(value1) as usize,
4 => 220, //u32::from_ne_bytes(value1) as usize,
_ => 0,
};
if let Ok(len2) = Self::encoded_length(&mut reader) {
println!("Found second integer of length: {}", len2);
let mut value2 = vec![0; len2];
reader.read_exact(&mut value2)?;
let expire_hash_tbl_sz = match len2 {
1 => value2[0] as usize,
2 => 110, //u16::from_ne_bytes(value2) as usize,
4 => 220, //u32::from_ne_bytes(value2) as usize,
_ => 0,
};
println!("0xFB block, value1: {:?}, value2: {:?}", hash_table_sz, expire_hash_tbl_sz);
}
}
},
0xFC => {
println!("FC Block - please decode me!");
let mut expiry_time_ms_db = [0; 8];
reader.read_exact(&mut expiry_time_ms_db)?;
let expiry_time_ms = u64::from_ne_bytes(expiry_time_ms_db);
if let Ok((key, value)) = Self::read_key_value_with_type(&mut reader) {
println!("0xFC block - key: {}, value: {}, expiry: {} ms to be added in DB",
String::from_utf8_lossy(&key), String::from_utf8_lossy(&value), expiry_time_ms);
}
},
0xFD => {
println!("FD Block - please decode me!");
let mut expiry_time_sec_db = [0; 4];
reader.read_exact(&mut expiry_time_sec_db)?;
let expiry_time_sec = u32::from_ne_bytes(expiry_time_sec_db) as usize;
if let Ok((key, value)) = Self::read_key_value_with_type(&mut reader) {
println!("0xFD block - key: {}, value: {} with expiry {} sec to be added in DB",
String::from_utf8_lossy(&key), String::from_utf8_lossy(&value), expiry_time_sec);
}
},
0xFE => {
reader.read_exact(&mut db_num)?;
println!("0XFE block - DB Number: {}", db_num[0]);
},
0xFF => {
println!("0xFE block - received EOF opcode!!!");
break;
},
_ => {
println!("Invalid Opcode found: {}", opcode[0]);
return Err(std::io::Error::new(std::io::ErrorKind::Other,
format!("Invalid RDB Opcode found: {}", opcode[0])));
}
}
}