# Rust: Stuck on Redis stage #SM4 (RDB Persistence - Read value with expiry)

**URL:** <https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140>\
**Category:** Challenges\
**Tags:** challenge:redis\
**Created:** [October 3, 2024, 12:18pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140 "2024-10-03T12:18:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 3, 2024, 12:18pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/1 "2024-10-03T12:18:37Z")

</div>

I have no idea why this is not working. My tests pass the earlier expiry stage, but when reading the expiry from the rdb file the same code is failing. Can anyone suggest how to fix this?

```auto
pub fn is_key_expired(created_timestamp: SystemTime, expiry: u128) -> bool {
 SystemTime::now().duration_since(created_timestamp).unwrap_or(Duration::from_secs(0)) >= Duration::from_millis(expiry as u64)
}

```

```auto
//read expiry, if any
    let mut expiry_indicator = [0; 1];
    reader.read_exact(&mut expiry_indicator)?;

    match expiry_indicator[0] {
        0xFC => {
            let mut expiry = [0; 8];
            reader.read_exact(&mut expiry)?;

            let expiry = u64::from_le_bytes(expiry) as u128;
            //let expiry = reader.read_u64::<LittleEndian>()? as u128;
            kv.expiry = Some(expiry);
        }
        0xFD => {
            let mut expiry = [0; 4];
            reader.read_exact(&mut expiry)?;
            let expiry = u32::from_le_bytes(expiry) as u128;
            //let expiry = reader.read_u64::<LittleEndian>()? as u128;
            kv.expiry = Some(expiry * 1000);
        }
        _ => {
            let _ = reader.seek(std::io::SeekFrom::Current(-1));
        }
       
    }

```

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [October 3, 2024, 4:48pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/2 "2024-10-03T16:48:29Z")

</div>

Full disclosure: I can barely read Rust, so I will try to help as best as I can.

I ran your code, and the first thing I noticed is that in the **Expiry #yz1** stage, `expiry` values ~~were way smaller than they should be~~ :

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/0/063a68581509980e38bb33857480eb2a789154d8.jpeg)

The correct `expiry` values ~~should be much bigger~~ , like those in **Read value with expiry #sm4**

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/0/0ed7ba295f3b39c0a28a1dc681a53667a9ece45b.jpeg)

@paebanks Could you try to check the parsing logic for `expiry`, making sure they look like the big number in **#sm4** but still pass **#yz1**?

---

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 3, 2024, 8:38pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/3 "2024-10-03T20:38:43Z")

</div>

The expiry values in $yz1 are read from command line and are supplied as values in milliseconds. Those value are exactly as passed in, with the “px” option. The values in #sm4 are timestamp values and thats where I’m not sure my parsing is correct

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [October 4, 2024, 12:59am UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/4 "2024-10-04T00:59:37Z")

</div>

@paebanks Got it! I can confirm you’re parsing the `expiry` values in **#sm4** correctly, but they’re probably not handled in the way intended.

Let’s look at this line:

```auto
# `expired_at` might not be a fitting name for the `px` option
if let Some(expired_at) = value.expiry

```

and this function:

```auto
pub fn is_key_expired(created_timestamp: SystemTime, expiry: u128) -> bool {
    SystemTime::now().duration_since(created_timestamp).unwrap_or(Duration::from_secs(0)) >= Duration::from_millis(expiry as u64)
}

```

It can handle the case where `px` represents a **duration** (as a delta value, but not a timestamp).

So it won’t work for the `expiry` values in **#sm4** , which are timestamps and can be fittingly named `expired_at`.

Suggestion:

- Either transform `px` durations into timestamps, and adjust `is_key_expired` accordingly,
- Or transform the `expiry` timestamps in **#sm4** into durations before storing them.

---

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 4, 2024, 12:07pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/5 "2024-10-04T12:07:53Z")

</div>

Thanks so much for your help. Still haven’t fixed it and I’m guessing it must be something simple. I converted the “px” values to timestamps with this function:

```auto
fn to_timestamp(expiry: u128) -> u128 {
    let exp_timestamp = SystemTime::now() + Duration::from_millis(expiry as u64);
    exp_timestamp.duration_since(UNIX_EPOCH).unwrap().as_millis() as u128
}

```

and my function to check expiry is this:

```auto
pub fn is_key_expired(expiry: u128) -> bool {
    let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u128;
    current_time >= expiry
}

```

Passes #yz1, but still fails #sm4

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [October 4, 2024, 12:37pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/6 "2024-10-04T12:37:47Z")

</div>

How do the logs look like now?

---

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 4, 2024, 12:40pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/7 "2024-10-04T12:40:19Z")

</div>

![Screenshot 2024-10-04 at 8.37.19 AM](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/0/0f5f76ef492bd18246ceddadec158c95b2019e0a.png)

---

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 4, 2024, 12:42pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/8 "2024-10-04T12:42:17Z")

</div>

I grabbed that expiry value and converted it with an online tool. I can confirm it is indeed expired. The date it represents is Saturday January 1, 2022.

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [October 4, 2024, 5:17pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/10 "2024-10-04T17:17:41Z")

</div>

@paebanks There may be multiple issues at play here, but here’s one fix you can try first:

The `expiry` values (if any) are located at the **beginning** of the key-value pairs, not at the end.

 ![0f34d49e92cd25da3fffb90361905ec5813dc42e](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/e/e1b530948a40f18972851f64add669d38bebb96c.jpeg)

Namely, the `expiry` for **orange: raspberry** shouldn’t be None, but instead should be 1956528000000, in the example above.

* * *

In our instructions, the examples are grouped like this:

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/3/30d65c1f73eb159516b52ef5159bf106871d66d4.png)

* * *

Feel free to use this snippet to print out the hex dump:

> **Click me**
>
> ```rust
> // Open the file
> let mut file = File::open(&path)?;
> let mut buffer = Vec::new();
> 
> // Read the file content into the buffer
> file.read_to_end(&mut buffer)?;
> 
> // Process the file buffer to mimic `xxd` output with extra newlines for readability
> for (i, chunk) in buffer.chunks(16).enumerate() {
> // Print the offset at the beginning of each line
> print!("{:08x}: ", i * 16);
> 
> // Print hex values for each byte in the chunk
> for byte in chunk {
> print!("{:02x} ", byte);
> }
> 
> // Pad hex column if the last chunk is less than 16 bytes
> if chunk.len() < 16 {
> for _ in 0..(16 - chunk.len()) {
> print!(" ");
> }
> }
> 
> // Print ASCII representation for each byte in the chunk
> print!("|");
> for byte in chunk {
> let ch = if *byte == 0x0c || !byte.is_ascii_graphic() {
> '.'
> } else {
> *byte as char
> };
> print!("{}", ch);
> }
> print!("|\n"); // Newline after each chunk for readability
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![paebanks](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/paebanks/32/2091_2.png) [@paebanks](https://forum.codecrafters.io/u/paebanks)\
**Post date:** [October 4, 2024, 8:14pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/11 "2024-10-04T20:14:07Z")

</div>

This has been so helpful. Thanks! I was assuming expiry values came AFTER the kv, not before

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [October 9, 2024, 8:14pm UTC](https://forum.codecrafters.io/t/rust-stuck-on-redis-stage-sm4-rdb-persistence-read-value-with-expiry/2140/12 "2024-10-09T20:14:36Z")

</div>

Closed on October 9, 2024, 8:14pm UTC

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.
