view rust/hg-core/src/dirstate_tree/owning.rs @ 49555:8ee3889bab92 stable

rust-status: save new dircache even if just invalidated There was a functional race between invalidating the cache (not acted upon until the end of the status algorithm) and populating the new cache (which relies upon an up-to-date version of the cache). We simply inform the cache populating function that we've just invalidated the cache for this particular directory since the information is present in the same scope.
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 19 Oct 2022 16:28:41 +0200
parents dd6b67d5c256
children 6cce0afc1454 e98fd81bb151
line wrap: on
line source

use crate::{DirstateError, DirstateParents};

use super::dirstate_map::DirstateMap;
use std::ops::Deref;

use ouroboros::self_referencing;

/// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it
/// borrows.
#[self_referencing]
pub struct OwningDirstateMap {
    on_disk: Box<dyn Deref<Target = [u8]> + Send>,
    #[borrows(on_disk)]
    #[covariant]
    map: DirstateMap<'this>,
}

impl OwningDirstateMap {
    pub fn new_empty<OnDisk>(on_disk: OnDisk) -> Self
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);

        OwningDirstateMapBuilder {
            on_disk,
            map_builder: |bytes| DirstateMap::empty(&bytes),
        }
        .build()
    }

    pub fn new_v1<OnDisk>(
        on_disk: OnDisk,
    ) -> Result<(Self, DirstateParents), DirstateError>
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);
        let mut parents = DirstateParents::NULL;

        Ok((
            OwningDirstateMapTryBuilder {
                on_disk,
                map_builder: |bytes| {
                    DirstateMap::new_v1(&bytes).map(|(dmap, p)| {
                        parents = p.unwrap_or(DirstateParents::NULL);
                        dmap
                    })
                },
            }
            .try_build()?,
            parents,
        ))
    }

    pub fn new_v2<OnDisk>(
        on_disk: OnDisk,
        data_size: usize,
        metadata: &[u8],
    ) -> Result<Self, DirstateError>
    where
        OnDisk: Deref<Target = [u8]> + Send + 'static,
    {
        let on_disk = Box::new(on_disk);

        OwningDirstateMapTryBuilder {
            on_disk,
            map_builder: |bytes| {
                DirstateMap::new_v2(&bytes, data_size, metadata)
            },
        }
        .try_build()
    }

    pub fn with_dmap_mut<R>(
        &mut self,
        f: impl FnOnce(&mut DirstateMap) -> R,
    ) -> R {
        self.with_map_mut(f)
    }

    pub fn get_map(&self) -> &DirstateMap {
        self.borrow_map()
    }

    pub fn on_disk(&self) -> &[u8] {
        self.borrow_on_disk()
    }
}