Archive mtimes: optimal complexity in all cases

[?]
Jan 8, 2021, 11:49 AM
BONBSXAUJKCMVB56LUU6PWXV7KPLB3HXZ5JF6LK43R5J4WYETUHAC

Dependencies

  • [2] I3OVP3NH Archive: set the accurate and deterministic mtime
  • [3] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [4] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump

Change contents

  • replacement in libpijul/src/output/archive.rs at line 191
    [3.694891][2.320:1210]()
    let mut latest_touch = 0;
    let mut latest_change = 0;
    for c in txn.iter_touched(output_item.pos)? {
    let (inode, change) = c?;
    if inode < output_item.pos {
    continue;
    } else if inode > output_item.pos {
    break;
    }
    if let Some(t) = txn.get_changeset(T::changes(&channel), change)? {
    if t > latest_change || latest_touch == 0 {
    latest_change = t;
    let ext = txn.get_external(change)?.unwrap();
    let c = changes.get_header(&ext).map_err(ArchiveError::P)?;
    latest_touch = c.timestamp.timestamp() as u64
    }
    }
    }
    [3.694891]
    [3.694891]
    let latest_touch = get_latest_touch(changes, txn, &channel, output_item.pos)?;
  • edit in libpijul/src/output/archive.rs at line 236
    [3.696438]
    fn get_latest_touch<
    'a,
    T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>,
    P: ChangeStore,
    A: std::error::Error + 'static,
    >(
    changes: &P,
    txn: &T,
    channel: &T::Channel,
    pos: Position<ChangeId>,
    ) -> Result<u64, ArchiveError<P::Error, T::GraphError, A>> {
    let mut latest_touch = 0;
    let mut latest_change = 0;
    let mut touch_iter = Some(txn.iter_touched(pos)?);
    let mut log_iter = changeid_rev_log(txn, &channel, None)?;
    let mut continue_ = true;
    while continue_ {
    continue_ = false;
    if let Some(ref mut it) = touch_iter {
    if let Some(c) = it.next() {
    debug!("inode, change = {:?}", c);
    let (inode, change) = c?;
    if inode > pos {
    touch_iter = None;
    } else if inode == pos {
    if let Some(t) = txn.get_changeset(T::changes(&channel), change)? {
    if t > latest_change || latest_touch == 0 {
    latest_change = t;
    let ext = txn.get_external(change)?.unwrap();
    let c = changes.get_header(&ext).map_err(ArchiveError::P)?;
    latest_touch = c.timestamp.timestamp() as u64
    }
    }
    continue_ = true;
    }
    }
    }
    if let Some(l) = log_iter.next() {
    debug!("int = {:?}", l);
    let (_, (int, _)) = l?;
    if txn.get_touched_files(pos, Some(int))?.is_some() {
    let ext = txn.get_external(int)?.unwrap();
    let c = changes.get_header(&ext).map_err(ArchiveError::P)?;
    latest_touch = c.timestamp.timestamp() as u64;
    break;
    }
    continue_ = true;
    }
    }
    Ok(latest_touch)
    }