Repository: meilisearch/meilisearch
File: dump/src/reader/v3/mod.rs (Rust)

Code before:
        tasks: BufReader<File>,
    ) -> Result<Self> {
        let meta = File::open(path.join("meta.json"))?;
        let meta: DumpMeta = serde_json::from_reader(meta)?;

        let mut created_entry = (u64::MAX, None);
        let mut updated_entry = (u64::MIN, None);

        for line in tasks.lines() {
            let task: Task = serde_json::from_str(&line?)?;

            if &task.uuid == &index_uuid.uuid {
                let update_id = task.update.id();

                if update_id <= created_entry.0 {
                    created_entry.0 = update_id;
                    created_entry.1 = task.update.created_at();
                }

                if update_id >= updated_entry.0 {
                    updated_entry.0 = update_id;
                    updated_entry.1 = task.update.processed_at();
                }
            }
        }

        let current_time = OffsetDateTime::now_utc();

        let metadata = IndexMetadata {
            uid: name,
            primary_key: meta.primary_key,
            created_at: created_entry.1.unwrap_or(current_time),
            updated_at: updated_entry.1.unwrap_or(current_time),
        };

        let ret = V3IndexReader {
            metadata,
            settings: meta.settings.check(),
            documents: BufReader::new(File::open(path.join("documents.jsonl"))?),
        };

        Ok(ret)
    }

    pub fn metadata(&self) -> &IndexMetadata {
        &self.metadata
    }

    pub fn documents(&mut self) -> Result<impl Iterator<Item = Result<Document>> + '_> {
        Ok((&mut self.documents)
            .lines()

Review comment (bug):
```suggestion
        let mut created_at = None;
        let mut updated_at = None;

        // The tasks are sorted
        // But we have no indication on what created the index thus we need to iterate over the whole task queue
        for line in tasks.lines() {
            let task: Task = serde_json::from_str(&line?)?;

            match task {
                // The only three kind of tasks that can create an index.
                // The documentAddition and Settings can create it even if they fails, they’ll do it anytime they starts processing the task
                // PS: I didn’t do it but you should also set the `updated_at`
                IndexCreation if created_at == None => created_at = Some(task.processed_at()),
                DocumentAddition if created_at == None => created_at = Some(task.started_processing()),
                Settings if created_at == None => created_at = Some(task.started_processing()),
                
                // We reset both markers
                IndexDeletion => { created_at = None; updated_at = None; }
                
                // Anything else => it’s an update but not a creation;
                task => updated_at = Some(task.processed_at()),
            }
        }
```

Hey, that’s not ideal but I went back to read what informations were available to us in the dump-v3 and I realised we had nothing and thus your implementation was kind of wrong.
So I made a code sample and tried to make it as clear as possible so you can get a general idea of what you could do, but don’t hesitate to ask if something is not clear.

Code after:

        for line in tasks.lines() {
            let task: Task = serde_json::from_str(&line?)?;

            if !(task.uuid == index_uuid.uuid && task.is_finished()) {
                continue;
            }

            let new_created_at = match task.update.meta() {
                Kind::DocumentAddition { .. } | Kind::Settings(_) => task.update.finished_at(),
                _ => None,
            };
            let new_updated_at = task.update.finished_at();

            if created_at.is_none() || created_at > new_created_at {
                created_at = new_created_at;
            }

            if updated_at.is_none() || updated_at < new_updated_at {
                updated_at = new_updated_at;
            }
        }

        let current_time = OffsetDateTime::now_utc();

        let metadata = IndexMetadata {
            uid: index_uuid.uid.clone(),
            primary_key: meta.primary_key,
            created_at: created_at.unwrap_or(current_time),
            updated_at: updated_at.unwrap_or(current_time),
        };

        let ret = V3IndexReader {
            metadata,
            settings: meta.settings.check(),
            documents: BufReader::new(File::open(path.join("documents.jsonl"))?),
        };

        Ok(ret)
    }

    pub fn metadata(&self) -> &IndexMetadata {
        &self.metadata
    }

    pub fn documents(&mut self) -> Result<impl Iterator<Item = Result<Document>> + '_> {
        Ok((&mut self.documents)
            .lines()
            .map(|line| -> Result<_> { Ok(serde_json::from_str(&line?)?) }))
    }