rust/hg-core/src/revlog/index.rs
author Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
Fri, 27 Oct 2023 21:48:45 +0200
changeset 51234 59183a19954e
parent 51233 ca81cd96000a
child 51235 456e0fe702e8
permissions -rw-r--r--
rust-index: use interior mutability in head revs and caches For upcoming changes in `hg-cpython` switching to the `hg-core` index in ancestors iterators, we will need to avoid excessive mutability, restricting the use of mutable references on `hg::index::Index` to methods that actually logically mutate it, whereas the maintenance of caches such as `head_revs` clearly does not. We illustrate that immediately by switching to immutable borrows in the corresponding methods of `hg-cpython::MixedIndex`
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
     1
use std::collections::hash_map::RandomState;
51220
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
     2
use std::collections::{HashMap, HashSet};
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
     3
use std::fmt::Debug;
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
     4
use std::ops::Deref;
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
     5
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
     6
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
     7
use byteorder::{BigEndian, ByteOrder};
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
     8
use bytes_cast::{unaligned, BytesCast};
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
     9
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
    10
use super::REVIDX_KNOWN_FLAGS;
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    11
use crate::errors::HgError;
51209
e9d47e2f5dcf rust-index: add missing special case for null rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51205
diff changeset
    12
use crate::node::{NODE_BYTES_LENGTH, NULL_NODE, STORED_NODE_ID_BYTES};
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45602
diff changeset
    13
use crate::revlog::node::Node;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    14
use crate::revlog::{Revision, NULL_REVISION};
51212
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
    15
use crate::{
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
    16
    dagops, BaseRevision, FastHashMap, Graph, GraphError, RevlogError,
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
    17
    RevlogIndex, UncheckedRevision,
51212
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
    18
};
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    19
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    20
pub const INDEX_ENTRY_SIZE: usize = 64;
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
    21
pub const COMPRESSION_MODE_INLINE: u8 = 2;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    22
51218
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
    23
#[derive(Debug)]
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    24
pub struct IndexHeader {
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
    25
    pub(super) header_bytes: [u8; 4],
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    26
}
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    27
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    28
#[derive(Copy, Clone)]
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    29
pub struct IndexHeaderFlags {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    30
    flags: u16,
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    31
}
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    32
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    33
/// Corresponds to the high bits of `_format_flags` in python
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    34
impl IndexHeaderFlags {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    35
    /// Corresponds to FLAG_INLINE_DATA in python
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    36
    pub fn is_inline(self) -> bool {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    37
        self.flags & 1 != 0
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    38
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    39
    /// Corresponds to FLAG_GENERALDELTA in python
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    40
    pub fn uses_generaldelta(self) -> bool {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    41
        self.flags & 2 != 0
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    42
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    43
}
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    44
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    45
/// Corresponds to the INDEX_HEADER structure,
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    46
/// which is parsed as a `header` variable in `_loadindex` in `revlog.py`
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    47
impl IndexHeader {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    48
    fn format_flags(&self) -> IndexHeaderFlags {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    49
        // No "unknown flags" check here, unlike in python. Maybe there should
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    50
        // be.
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    51
        IndexHeaderFlags {
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    52
            flags: BigEndian::read_u16(&self.header_bytes[0..2]),
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    53
        }
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    54
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    55
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    56
    /// The only revlog version currently supported by rhg.
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    57
    const REVLOGV1: u16 = 1;
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    58
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    59
    /// Corresponds to `_format_version` in Python.
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    60
    fn format_version(&self) -> u16 {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    61
        BigEndian::read_u16(&self.header_bytes[2..4])
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    62
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    63
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
    64
    pub fn parse(index_bytes: &[u8]) -> Result<Option<IndexHeader>, HgError> {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
    65
        if index_bytes.is_empty() {
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
    66
            return Ok(None);
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    67
        }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    68
        if index_bytes.len() < 4 {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    69
            return Err(HgError::corrupted(
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    70
                "corrupted revlog: can't read the index format header",
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    71
            ));
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    72
        }
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
    73
        Ok(Some(IndexHeader {
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    74
            header_bytes: {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    75
                let bytes: [u8; 4] =
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    76
                    index_bytes[0..4].try_into().expect("impossible");
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    77
                bytes
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    78
            },
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
    79
        }))
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    80
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    81
}
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
    82
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    83
/// Abstracts the access to the index bytes since they can be spread between
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    84
/// the immutable (bytes) part and the mutable (added) part if any appends
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    85
/// happened. This makes it transparent for the callers.
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    86
struct IndexData {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    87
    /// Immutable bytes, most likely taken from disk
51233
ca81cd96000a rust-index: add Sync bound to all relevant mmap-derived values
Raphaël Gomès <rgomes@octobus.net>
parents: 51229
diff changeset
    88
    bytes: Box<dyn Deref<Target = [u8]> + Send + Sync>,
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
    89
    /// Used when stripping index contents, keeps track of the start of the
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
    90
    /// first stripped revision, which is used to give a slice of the
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
    91
    /// `bytes` field.
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
    92
    truncation: Option<usize>,
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    93
    /// Bytes that were added after reading the index
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    94
    added: Vec<u8>,
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    95
}
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    96
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    97
impl IndexData {
51233
ca81cd96000a rust-index: add Sync bound to all relevant mmap-derived values
Raphaël Gomès <rgomes@octobus.net>
parents: 51229
diff changeset
    98
    pub fn new(bytes: Box<dyn Deref<Target = [u8]> + Send + Sync>) -> Self {
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
    99
        Self {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   100
            bytes,
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   101
            truncation: None,
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   102
            added: vec![],
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   103
        }
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   104
    }
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   105
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   106
    pub fn len(&self) -> usize {
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   107
        match self.truncation {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   108
            Some(truncation) => truncation + self.added.len(),
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   109
            None => self.bytes.len() + self.added.len(),
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   110
        }
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   111
    }
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   112
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   113
    fn remove(
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   114
        &mut self,
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   115
        rev: Revision,
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   116
        offsets: Option<&[usize]>,
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   117
    ) -> Result<(), RevlogError> {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   118
        let rev = rev.0 as usize;
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   119
        let truncation = if let Some(offsets) = offsets {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   120
            offsets[rev]
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   121
        } else {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   122
            rev * INDEX_ENTRY_SIZE
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   123
        };
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   124
        if truncation < self.bytes.len() {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   125
            self.truncation = Some(truncation);
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   126
            self.added.clear();
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   127
        } else {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   128
            self.added.truncate(truncation - self.bytes.len());
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   129
        }
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   130
        Ok(())
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   131
    }
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   132
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   133
    fn is_new(&self) -> bool {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   134
        self.bytes.is_empty()
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   135
    }
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   136
}
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   137
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   138
impl std::ops::Index<std::ops::Range<usize>> for IndexData {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   139
    type Output = [u8];
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   140
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   141
    fn index(&self, index: std::ops::Range<usize>) -> &Self::Output {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   142
        let start = index.start;
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   143
        let end = index.end;
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   144
        let immutable_len = match self.truncation {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   145
            Some(truncation) => truncation,
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   146
            None => self.bytes.len(),
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   147
        };
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   148
        if start < immutable_len {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   149
            if end > immutable_len {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   150
                panic!("index data cannot span existing and added ranges");
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   151
            }
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   152
            &self.bytes[index]
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   153
        } else {
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   154
            &self.added[start - immutable_len..end - immutable_len]
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   155
        }
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   156
    }
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   157
}
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   158
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   159
#[derive(Debug, PartialEq, Eq)]
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   160
pub struct RevisionDataParams {
51192
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   161
    pub flags: u16,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   162
    pub data_offset: u64,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   163
    pub data_compressed_length: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   164
    pub data_uncompressed_length: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   165
    pub data_delta_base: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   166
    pub link_rev: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   167
    pub parent_rev_1: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   168
    pub parent_rev_2: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   169
    pub node_id: [u8; NODE_BYTES_LENGTH],
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   170
    pub _sidedata_offset: u64,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   171
    pub _sidedata_compressed_length: i32,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   172
    pub data_compression_mode: u8,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   173
    pub _sidedata_compression_mode: u8,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   174
    pub _rank: i32,
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   175
}
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   176
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   177
impl Default for RevisionDataParams {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   178
    fn default() -> Self {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   179
        Self {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   180
            flags: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   181
            data_offset: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   182
            data_compressed_length: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   183
            data_uncompressed_length: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   184
            data_delta_base: -1,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   185
            link_rev: -1,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   186
            parent_rev_1: -1,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   187
            parent_rev_2: -1,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   188
            node_id: [0; NODE_BYTES_LENGTH],
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   189
            _sidedata_offset: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   190
            _sidedata_compressed_length: 0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   191
            data_compression_mode: COMPRESSION_MODE_INLINE,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   192
            _sidedata_compression_mode: COMPRESSION_MODE_INLINE,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   193
            _rank: -1,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   194
        }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   195
    }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   196
}
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   197
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   198
#[derive(BytesCast)]
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   199
#[repr(C)]
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   200
pub struct RevisionDataV1 {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   201
    data_offset_or_flags: unaligned::U64Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   202
    data_compressed_length: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   203
    data_uncompressed_length: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   204
    data_delta_base: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   205
    link_rev: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   206
    parent_rev_1: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   207
    parent_rev_2: unaligned::I32Be,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   208
    node_id: [u8; STORED_NODE_ID_BYTES],
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   209
}
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   210
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   211
fn _static_assert_size_of_revision_data_v1() {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   212
    let _ = std::mem::transmute::<RevisionDataV1, [u8; 64]>;
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   213
}
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   214
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   215
impl RevisionDataParams {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   216
    pub fn validate(&self) -> Result<(), RevlogError> {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   217
        if self.flags & !REVIDX_KNOWN_FLAGS != 0 {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   218
            return Err(RevlogError::corrupted(format!(
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   219
                "unknown revlog index flags: {}",
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   220
                self.flags
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   221
            )));
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   222
        }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   223
        if self.data_compression_mode != COMPRESSION_MODE_INLINE {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   224
            return Err(RevlogError::corrupted(format!(
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   225
                "invalid data compression mode: {}",
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   226
                self.data_compression_mode
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   227
            )));
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   228
        }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   229
        // FIXME isn't this only for v2 or changelog v2?
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   230
        if self._sidedata_compression_mode != COMPRESSION_MODE_INLINE {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   231
            return Err(RevlogError::corrupted(format!(
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   232
                "invalid sidedata compression mode: {}",
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   233
                self._sidedata_compression_mode
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   234
            )));
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   235
        }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   236
        Ok(())
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   237
    }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   238
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   239
    pub fn into_v1(self) -> RevisionDataV1 {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   240
        let data_offset_or_flags = self.data_offset << 16 | self.flags as u64;
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   241
        let mut node_id = [0; STORED_NODE_ID_BYTES];
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   242
        node_id[..NODE_BYTES_LENGTH].copy_from_slice(&self.node_id);
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   243
        RevisionDataV1 {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   244
            data_offset_or_flags: data_offset_or_flags.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   245
            data_compressed_length: self.data_compressed_length.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   246
            data_uncompressed_length: self.data_uncompressed_length.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   247
            data_delta_base: self.data_delta_base.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   248
            link_rev: self.link_rev.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   249
            parent_rev_1: self.parent_rev_1.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   250
            parent_rev_2: self.parent_rev_2.into(),
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   251
            node_id,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   252
        }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   253
    }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   254
}
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   255
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   256
/// A Revlog index
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   257
pub struct Index {
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   258
    bytes: IndexData,
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   259
    /// Offsets of starts of index blocks.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   260
    /// Only needed when the index is interleaved with data.
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   261
    offsets: RwLock<Option<Vec<usize>>>,
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   262
    uses_generaldelta: bool,
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   263
    is_inline: bool,
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   264
    /// Cache of (head_revisions, filtered_revisions)
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   265
    ///
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   266
    /// The head revisions in this index, kept in sync. Should
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   267
    /// be accessed via the [`Self::head_revs`] method.
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   268
    /// The last filtered revisions in this index, used to make sure
51216
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   269
    /// we haven't changed filters when returning the cached `head_revs`.
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   270
    head_revs: RwLock<(Vec<Revision>, HashSet<Revision>)>,
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   271
}
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   272
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   273
impl Debug for Index {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   274
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   275
        f.debug_struct("Index")
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   276
            .field("offsets", &self.offsets)
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   277
            .field("uses_generaldelta", &self.uses_generaldelta)
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   278
            .finish()
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   279
    }
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   280
}
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   281
50978
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   282
impl Graph for Index {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   283
    fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   284
        let err = || GraphError::ParentOutOfRange(rev);
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   285
        match self.get_entry(rev) {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   286
            Some(entry) => {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   287
                // The C implementation checks that the parents are valid
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   288
                // before returning
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   289
                Ok([
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   290
                    self.check_revision(entry.p1()).ok_or_else(err)?,
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   291
                    self.check_revision(entry.p2()).ok_or_else(err)?,
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   292
                ])
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   293
            }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   294
            None => Ok([NULL_REVISION, NULL_REVISION]),
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   295
        }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   296
    }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   297
}
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   298
51212
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   299
/// A cache suitable for find_snapshots
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   300
///
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   301
/// Logically equivalent to a mapping whose keys are [`BaseRevision`] and
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   302
/// values sets of [`BaseRevision`]
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   303
///
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   304
/// TODO the dubious part is insisting that errors must be RevlogError
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   305
/// we would probably need to sprinkle some magic here, such as an associated
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   306
/// type that would be Into<RevlogError> but even that would not be
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   307
/// satisfactory, as errors potentially have nothing to do with the revlog.
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   308
pub trait SnapshotsCache {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   309
    fn insert_for(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   310
        &mut self,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   311
        rev: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   312
        value: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   313
    ) -> Result<(), RevlogError>;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   314
}
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   315
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   316
impl SnapshotsCache for FastHashMap<BaseRevision, HashSet<BaseRevision>> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   317
    fn insert_for(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   318
        &mut self,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   319
        rev: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   320
        value: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   321
    ) -> Result<(), RevlogError> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   322
        let all_values = self.entry(rev).or_insert_with(HashSet::new);
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   323
        all_values.insert(value);
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   324
        Ok(())
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   325
    }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   326
}
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   327
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   328
impl Index {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   329
    /// Create an index from bytes.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   330
    /// Calculate the start of each entry when is_inline is true.
45602
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   331
    pub fn new(
51233
ca81cd96000a rust-index: add Sync bound to all relevant mmap-derived values
Raphaël Gomès <rgomes@octobus.net>
parents: 51229
diff changeset
   332
        bytes: Box<dyn Deref<Target = [u8]> + Send + Sync>,
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
   333
        default_header: IndexHeader,
47963
001d747c2baf rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents: 46887
diff changeset
   334
    ) -> Result<Self, HgError> {
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
   335
        let header =
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
   336
            IndexHeader::parse(bytes.as_ref())?.unwrap_or(default_header);
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   337
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   338
        if header.format_version() != IndexHeader::REVLOGV1 {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   339
            // A proper new version should have had a repo/store
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   340
            // requirement.
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   341
            return Err(HgError::corrupted("unsupported revlog version"));
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   342
        }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   343
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   344
        // This is only correct because we know version is REVLOGV1.
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   345
        // In v2 we always use generaldelta, while in v0 we never use
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   346
        // generaldelta. Similar for [is_inline] (it's only used in v1).
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   347
        let uses_generaldelta = header.format_flags().uses_generaldelta();
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   348
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
   349
        if header.format_flags().is_inline() {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   350
            let mut offset: usize = 0;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   351
            let mut offsets = Vec::new();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   352
45590
11f3c3f408fd hg-core: minor code style change (D8958#inline-14993 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45536
diff changeset
   353
            while offset + INDEX_ENTRY_SIZE <= bytes.len() {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   354
                offsets.push(offset);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   355
                let end = offset + INDEX_ENTRY_SIZE;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   356
                let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   357
                    bytes: &bytes[offset..end],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   358
                    offset_override: None,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   359
                };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   360
48543
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48458
diff changeset
   361
                offset += INDEX_ENTRY_SIZE + entry.compressed_len() as usize;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   362
            }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   363
45602
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   364
            if offset == bytes.len() {
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   365
                Ok(Self {
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   366
                    bytes: IndexData::new(bytes),
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   367
                    offsets: RwLock::new(Some(offsets)),
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   368
                    uses_generaldelta,
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   369
                    is_inline: true,
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   370
                    head_revs: RwLock::new((vec![], HashSet::new())),
45602
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   371
                })
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   372
            } else {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
   373
                Err(HgError::corrupted("unexpected inline revlog length"))
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   374
            }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   375
        } else {
45602
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   376
            Ok(Self {
51188
1ef4a36a934d rust-index: add an abstraction to support bytes added at runtimes
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   377
                bytes: IndexData::new(bytes),
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   378
                offsets: RwLock::new(None),
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   379
                uses_generaldelta,
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   380
                is_inline: false,
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   381
                head_revs: RwLock::new((vec![], HashSet::new())),
45602
1cef583541c0 hg-core: return Err if `offset != bytes.len()`
Antoine cezar<acezar@chwitlabs.fr>
parents: 45601
diff changeset
   382
            })
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   383
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   384
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   385
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   386
    pub fn uses_generaldelta(&self) -> bool {
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   387
        self.uses_generaldelta
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   388
    }
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
   389
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   390
    /// Value of the inline flag.
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   391
    pub fn is_inline(&self) -> bool {
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   392
        self.is_inline
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   393
    }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   394
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   395
    /// Return a slice of bytes if `revlog` is inline. Panic if not.
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   396
    pub fn data(&self, start: usize, end: usize) -> &[u8] {
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   397
        if !self.is_inline() {
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   398
            panic!("tried to access data in the index of a revlog that is not inline");
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   399
        }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   400
        &self.bytes[start..end]
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   401
    }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
   402
45536
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   403
    /// Return number of entries of the revlog index.
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   404
    pub fn len(&self) -> usize {
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   405
        if let Some(offsets) = &*self.get_offsets() {
45536
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   406
            offsets.len()
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   407
        } else {
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   408
            self.bytes.len() / INDEX_ENTRY_SIZE
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   409
        }
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   410
    }
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   411
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   412
    pub fn get_offsets(&self) -> RwLockReadGuard<Option<Vec<usize>>> {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   413
        if self.is_inline() {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   414
            {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   415
                // Wrap in a block to drop the read guard
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   416
                // TODO perf?
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   417
                let mut offsets = self.offsets.write().unwrap();
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   418
                if offsets.is_none() {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   419
                    offsets.replace(inline_scan(&self.bytes.bytes).1);
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   420
                }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   421
            }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   422
        }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   423
        self.offsets.read().unwrap()
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   424
    }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   425
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   426
    pub fn get_offsets_mut(&mut self) -> RwLockWriteGuard<Option<Vec<usize>>> {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   427
        let mut offsets = self.offsets.write().unwrap();
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   428
        if self.is_inline() && offsets.is_none() {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   429
            offsets.replace(inline_scan(&self.bytes.bytes).1);
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   430
        }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   431
        offsets
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   432
    }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   433
45536
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   434
    /// Returns `true` if the `Index` has zero `entries`.
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   435
    pub fn is_empty(&self) -> bool {
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   436
        self.len() == 0
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   437
    }
639f33f22faf hg-core: add a `ListRevTrackedFiles` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45531
diff changeset
   438
51203
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   439
    /// Return the index entry corresponding to the given revision or `None`
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   440
    /// for [`NULL_REVISION`]
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   441
    ///
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   442
    /// The specified revision being of the checked type, it always exists
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   443
    /// if it was validated by this index.
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   444
    pub fn get_entry(&self, rev: Revision) -> Option<IndexEntry> {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   445
        if rev == NULL_REVISION {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   446
            return None;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   447
        }
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   448
        Some(if let Some(offsets) = &*self.get_offsets() {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   449
            self.get_entry_inline(rev, offsets.as_ref())
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   450
        } else {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   451
            self.get_entry_separated(rev)
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   452
        })
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   453
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   454
51203
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   455
    /// Return the binary content of the index entry for the given revision
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   456
    ///
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   457
    /// See [get_entry()](`Self::get_entry()`) for cases when `None` is
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   458
    /// returned.
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   459
    pub fn entry_binary(&self, rev: Revision) -> Option<&[u8]> {
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   460
        self.get_entry(rev).map(|e| {
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   461
            let bytes = e.as_bytes();
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   462
            if rev.0 == 0 {
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   463
                &bytes[4..]
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   464
            } else {
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   465
                bytes
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   466
            }
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   467
        })
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   468
    }
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
   469
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   470
    pub fn entry_as_params(
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   471
        &self,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   472
        rev: UncheckedRevision,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   473
    ) -> Option<RevisionDataParams> {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   474
        let rev = self.check_revision(rev)?;
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   475
        self.get_entry(rev).map(|e| RevisionDataParams {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   476
            flags: e.flags(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   477
            data_offset: if rev.0 == 0 && !self.bytes.is_new() {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   478
                e.flags() as u64
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   479
            } else {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   480
                e.raw_offset()
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   481
            },
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   482
            data_compressed_length: e.compressed_len().try_into().unwrap(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   483
            data_uncompressed_length: e.uncompressed_len(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   484
            data_delta_base: e.base_revision_or_base_of_delta_chain().0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   485
            link_rev: e.link_revision().0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   486
            parent_rev_1: e.p1().0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   487
            parent_rev_2: e.p2().0,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   488
            node_id: e.hash().as_bytes().try_into().unwrap(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   489
            ..Default::default()
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   490
        })
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   491
    }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
   492
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   493
    fn get_entry_inline(
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   494
        &self,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   495
        rev: Revision,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   496
        offsets: &[usize],
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   497
    ) -> IndexEntry {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
   498
        let start = offsets[rev.0 as usize];
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   499
        let end = start + INDEX_ENTRY_SIZE;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   500
        let bytes = &self.bytes[start..end];
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   501
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   502
        // See IndexEntry for an explanation of this override.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   503
        let offset_override = Some(end);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   504
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   505
        IndexEntry {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   506
            bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   507
            offset_override,
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   508
        }
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   509
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   510
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   511
    fn get_entry_separated(&self, rev: Revision) -> IndexEntry {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
   512
        let start = rev.0 as usize * INDEX_ENTRY_SIZE;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   513
        let end = start + INDEX_ENTRY_SIZE;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   514
        let bytes = &self.bytes[start..end];
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   515
45591
f38adf8b0711 hg-core: Explain offset override of first revision
Antoine cezar<acezar@chwitlabs.fr>
parents: 45590
diff changeset
   516
        // Override the offset of the first revision as its bytes are used
f38adf8b0711 hg-core: Explain offset override of first revision
Antoine cezar<acezar@chwitlabs.fr>
parents: 45590
diff changeset
   517
        // for the index's metadata (saving space because it is always 0)
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
   518
        let offset_override = if rev == Revision(0) { Some(0) } else { None };
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   519
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   520
        IndexEntry {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   521
            bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   522
            offset_override,
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
   523
        }
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   524
    }
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   525
51218
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   526
    fn null_entry(&self) -> IndexEntry {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   527
        IndexEntry {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   528
            bytes: &[0; INDEX_ENTRY_SIZE],
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   529
            offset_override: Some(0),
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   530
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   531
    }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   532
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   533
    /// Return the head revisions of this index
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   534
    pub fn head_revs(&self) -> Result<Vec<Revision>, GraphError> {
51216
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   535
        self.head_revs_filtered(&HashSet::new())
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   536
    }
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   537
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   538
    /// Return the head revisions of this index
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   539
    pub fn head_revs_filtered(
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   540
        &self,
51216
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   541
        filtered_revs: &HashSet<Revision>,
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   542
    ) -> Result<Vec<Revision>, GraphError> {
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   543
        {
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   544
            let guard = self
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   545
                .head_revs
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   546
                .read()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   547
                .expect("RwLock on Index.head_revs should not be poisoned");
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   548
            let self_head_revs = &guard.0;
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   549
            let self_filtered_revs = &guard.1;
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   550
            if !self_head_revs.is_empty()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   551
                && filtered_revs == self_filtered_revs
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   552
            {
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   553
                return Ok(self_head_revs.to_owned());
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   554
            }
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   555
        }
51216
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   556
        let mut revs: HashSet<Revision, RandomState> =
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   557
            if filtered_revs.is_empty() {
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   558
                (0..self.len())
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   559
                    .into_iter()
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   560
                    .map(|i| Revision(i as BaseRevision))
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   561
                    .collect()
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   562
            } else {
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   563
                (0..self.len())
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   564
                    .into_iter()
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   565
                    .filter_map(|i| {
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   566
                        let r = Revision(i as BaseRevision);
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   567
                        if filtered_revs.contains(&r) {
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   568
                            None
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   569
                        } else {
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   570
                            Some(r)
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   571
                        }
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   572
                    })
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   573
                    .collect()
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Raphaël Gomès <rgomes@octobus.net>
parents: 51215
diff changeset
   574
            };
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   575
        dagops::retain_heads(self, &mut revs)?;
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   576
        if self.is_empty() {
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   577
            revs.insert(NULL_REVISION);
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   578
        }
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   579
        let mut as_vec: Vec<Revision> =
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   580
            revs.into_iter().map(Into::into).collect();
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   581
        as_vec.sort_unstable();
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   582
        *self
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   583
            .head_revs
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   584
            .write()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   585
            .expect("RwLock on Index.head_revs should not be poisoned") =
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   586
            (as_vec.to_owned(), filtered_revs.to_owned());
51215
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   587
        Ok(as_vec)
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   588
    }
a7bba7df9189 rust-index: implement headrevs
Raphaël Gomès <rgomes@octobus.net>
parents: 51213
diff changeset
   589
51213
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   590
    /// Obtain the delta chain for a revision.
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   591
    ///
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   592
    /// `stop_rev` specifies a revision to stop at. If not specified, we
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   593
    /// stop at the base of the chain.
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   594
    ///
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   595
    /// Returns a 2-tuple of (chain, stopped) where `chain` is a vec of
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   596
    /// revs in ascending order and `stopped` is a bool indicating whether
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   597
    /// `stoprev` was hit.
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   598
    pub fn delta_chain(
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   599
        &self,
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   600
        rev: Revision,
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   601
        stop_rev: Option<Revision>,
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   602
    ) -> Result<(Vec<Revision>, bool), HgError> {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   603
        let mut current_rev = rev;
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   604
        let mut entry = self.get_entry(rev).unwrap();
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   605
        let mut chain = vec![];
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   606
        while current_rev.0 != entry.base_revision_or_base_of_delta_chain().0
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   607
            && stop_rev.map(|r| r != current_rev).unwrap_or(true)
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   608
        {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   609
            chain.push(current_rev);
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   610
            let new_rev = if self.uses_generaldelta() {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   611
                entry.base_revision_or_base_of_delta_chain()
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   612
            } else {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   613
                UncheckedRevision(current_rev.0 - 1)
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   614
            };
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   615
            current_rev = self.check_revision(new_rev).ok_or_else(|| {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   616
                HgError::corrupted(format!("Revision {new_rev} out of range"))
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   617
            })?;
51218
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   618
            if current_rev.0 == NULL_REVISION.0 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   619
                break;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   620
            }
51213
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   621
            entry = self.get_entry(current_rev).unwrap()
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   622
        }
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   623
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   624
        let stopped = if stop_rev.map(|r| current_rev == r).unwrap_or(false) {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   625
            true
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   626
        } else {
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   627
            chain.push(current_rev);
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   628
            false
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   629
        };
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   630
        chain.reverse();
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   631
        Ok((chain, stopped))
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   632
    }
62e39bef36ca rust-index: add support for delta-chain computation
Raphaël Gomès <rgomes@octobus.net>
parents: 51212
diff changeset
   633
51212
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   634
    pub fn find_snapshots(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   635
        &self,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   636
        start_rev: UncheckedRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   637
        end_rev: UncheckedRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   638
        cache: &mut impl SnapshotsCache,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   639
    ) -> Result<(), RevlogError> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   640
        let mut start_rev = start_rev.0;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   641
        let mut end_rev = end_rev.0;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   642
        end_rev += 1;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   643
        let len = self.len().try_into().unwrap();
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   644
        if end_rev > len {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   645
            end_rev = len;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   646
        }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   647
        if start_rev < 0 {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   648
            start_rev = 0;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   649
        }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   650
        for rev in start_rev..end_rev {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   651
            if !self.is_snapshot_unchecked(Revision(rev))? {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   652
                continue;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   653
            }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   654
            let mut base = self
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   655
                .get_entry(Revision(rev))
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   656
                .unwrap()
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   657
                .base_revision_or_base_of_delta_chain();
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   658
            if base.0 == rev {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   659
                base = NULL_REVISION.into();
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   660
            }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   661
            cache.insert_for(base.0, rev)?;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   662
        }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   663
        Ok(())
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   664
    }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Raphaël Gomès <rgomes@octobus.net>
parents: 51211
diff changeset
   665
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   666
    fn clear_head_revs(&self) {
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   667
        self.head_revs
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   668
            .write()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   669
            .expect("RwLock on Index.head_revs should not be poisoined")
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   670
            .0
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   671
            .clear()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   672
    }
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   673
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   674
    /// TODO move this to the trait probably, along with other things
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   675
    pub fn append(
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   676
        &mut self,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   677
        revision_data: RevisionDataParams,
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   678
    ) -> Result<(), RevlogError> {
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   679
        revision_data.validate()?;
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   680
        let new_offset = self.bytes.len();
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   681
        if let Some(offsets) = &mut *self.get_offsets_mut() {
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   682
            offsets.push(new_offset)
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   683
        }
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   684
        self.bytes.added.extend(revision_data.into_v1().as_bytes());
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   685
        self.clear_head_revs();
51189
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   686
        Ok(())
b4d152a28742 rust-index: add append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51188
diff changeset
   687
    }
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   688
51198
51cc12158f97 rust-index: add `pack_header` support
Raphaël Gomès <rgomes@octobus.net>
parents: 51197
diff changeset
   689
    pub fn pack_header(&self, header: i32) -> [u8; 4] {
51cc12158f97 rust-index: add `pack_header` support
Raphaël Gomès <rgomes@octobus.net>
parents: 51197
diff changeset
   690
        header.to_be_bytes()
51cc12158f97 rust-index: add `pack_header` support
Raphaël Gomès <rgomes@octobus.net>
parents: 51197
diff changeset
   691
    }
51cc12158f97 rust-index: add `pack_header` support
Raphaël Gomès <rgomes@octobus.net>
parents: 51197
diff changeset
   692
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   693
    pub fn remove(&mut self, rev: Revision) -> Result<(), RevlogError> {
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   694
        let offsets = self.get_offsets().clone();
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   695
        self.bytes.remove(rev, offsets.as_deref())?;
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   696
        if let Some(offsets) = &mut *self.get_offsets_mut() {
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   697
            offsets.truncate(rev.0 as usize)
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   698
        }
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   699
        self.clear_head_revs();
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   700
        Ok(())
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   701
    }
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   702
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   703
    pub fn clear_caches(&self) {
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   704
        // We need to get the 'inline' value from Python at init and use this
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   705
        // instead of offsets to determine whether we're inline since we might
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   706
        // clear caches. This implies re-populating the offsets on-demand.
51234
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   707
        *self
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   708
            .offsets
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   709
            .write()
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   710
            .expect("RwLock on Index.offsets should not be poisoed") = None;
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51233
diff changeset
   711
        self.clear_head_revs();
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
   712
    }
51211
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   713
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   714
    /// Unchecked version of `is_snapshot`.
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   715
    /// Assumes the caller checked that `rev` is within a valid revision range.
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   716
    pub fn is_snapshot_unchecked(
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   717
        &self,
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   718
        mut rev: Revision,
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   719
    ) -> Result<bool, RevlogError> {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   720
        while rev.0 >= 0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   721
            let entry = self.get_entry(rev).unwrap();
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   722
            let mut base = entry.base_revision_or_base_of_delta_chain().0;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   723
            if base == rev.0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   724
                base = NULL_REVISION.0;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   725
            }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   726
            if base == NULL_REVISION.0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   727
                return Ok(true);
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   728
            }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   729
            let [mut p1, mut p2] = self
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   730
                .parents(rev)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   731
                .map_err(|_| RevlogError::InvalidRevision)?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   732
            while let Some(p1_entry) = self.get_entry(p1) {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   733
                if p1_entry.compressed_len() != 0 || p1.0 == 0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   734
                    break;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   735
                }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   736
                let parent_base =
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   737
                    p1_entry.base_revision_or_base_of_delta_chain();
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   738
                if parent_base.0 == p1.0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   739
                    break;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   740
                }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   741
                p1 = self
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   742
                    .check_revision(parent_base)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   743
                    .ok_or(RevlogError::InvalidRevision)?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   744
            }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   745
            while let Some(p2_entry) = self.get_entry(p2) {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   746
                if p2_entry.compressed_len() != 0 || p2.0 == 0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   747
                    break;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   748
                }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   749
                let parent_base =
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   750
                    p2_entry.base_revision_or_base_of_delta_chain();
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   751
                if parent_base.0 == p2.0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   752
                    break;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   753
                }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   754
                p2 = self
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   755
                    .check_revision(parent_base)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   756
                    .ok_or(RevlogError::InvalidRevision)?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   757
            }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   758
            if base == p1.0 || base == p2.0 {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   759
                return Ok(false);
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   760
            }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   761
            rev = self
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   762
                .check_revision(base.into())
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   763
                .ok_or(RevlogError::InvalidRevision)?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   764
        }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   765
        Ok(rev == NULL_REVISION)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   766
    }
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   767
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   768
    /// Return whether the given revision is a snapshot. Returns an error if
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   769
    /// `rev` is not within a valid revision range.
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   770
    pub fn is_snapshot(
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   771
        &self,
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   772
        rev: UncheckedRevision,
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   773
    ) -> Result<bool, RevlogError> {
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   774
        let rev = self
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   775
            .check_revision(rev)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   776
            .ok_or_else(|| RevlogError::corrupted("test"))?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   777
        self.is_snapshot_unchecked(rev)
b8c89957a6b7 rust-index: add `is_snapshot` method
Raphaël Gomès <rgomes@octobus.net>
parents: 51209
diff changeset
   778
    }
51218
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   779
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   780
    /// Slice revs to reduce the amount of unrelated data to be read from disk.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   781
    ///
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   782
    /// The index is sliced into groups that should be read in one time.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   783
    ///
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   784
    /// The initial chunk is sliced until the overall density
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   785
    /// (payload/chunks-span ratio) is above `target_density`.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   786
    /// No gap smaller than `min_gap_size` is skipped.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   787
    pub fn slice_chunk_to_density(
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   788
        &self,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   789
        revs: &[Revision],
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   790
        target_density: f64,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   791
        min_gap_size: usize,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   792
    ) -> Vec<Vec<Revision>> {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   793
        if revs.is_empty() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   794
            return vec![];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   795
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   796
        if revs.len() == 1 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   797
            return vec![revs.to_owned()];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   798
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   799
        let delta_chain_span = self.segment_span(revs);
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   800
        if delta_chain_span < min_gap_size {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   801
            return vec![revs.to_owned()];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   802
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   803
        let entries: Vec<_> = revs
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   804
            .iter()
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   805
            .map(|r| {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   806
                (*r, self.get_entry(*r).unwrap_or_else(|| self.null_entry()))
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   807
            })
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   808
            .collect();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   809
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   810
        let mut read_data = delta_chain_span;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   811
        let chain_payload: u32 =
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   812
            entries.iter().map(|(_r, e)| e.compressed_len()).sum();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   813
        let mut density = if delta_chain_span > 0 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   814
            chain_payload as f64 / delta_chain_span as f64
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   815
        } else {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   816
            1.0
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   817
        };
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   818
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   819
        if density >= target_density {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   820
            return vec![revs.to_owned()];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   821
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   822
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   823
        // Store the gaps in a heap to have them sorted by decreasing size
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   824
        let mut gaps = Vec::new();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   825
        let mut previous_end = None;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   826
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   827
        for (i, (_rev, entry)) in entries.iter().enumerate() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   828
            let start = entry.c_start() as usize;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   829
            let length = entry.compressed_len();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   830
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   831
            // Skip empty revisions to form larger holes
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   832
            if length == 0 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   833
                continue;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   834
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   835
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   836
            if let Some(end) = previous_end {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   837
                let gap_size = start - end;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   838
                // Only consider holes that are large enough
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   839
                if gap_size > min_gap_size {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   840
                    gaps.push((gap_size, i));
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   841
                }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   842
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   843
            previous_end = Some(start + length as usize);
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   844
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   845
        if gaps.is_empty() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   846
            return vec![revs.to_owned()];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   847
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   848
        // sort the gaps to pop them from largest to small
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   849
        gaps.sort_unstable();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   850
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   851
        // Collect the indices of the largest holes until
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   852
        // the density is acceptable
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   853
        let mut selected = vec![];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   854
        while let Some((gap_size, gap_id)) = gaps.pop() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   855
            if density >= target_density {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   856
                break;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   857
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   858
            selected.push(gap_id);
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   859
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   860
            // The gap sizes are stored as negatives to be sorted decreasingly
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   861
            // by the heap
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   862
            read_data -= gap_size;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   863
            density = if read_data > 0 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   864
                chain_payload as f64 / read_data as f64
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   865
            } else {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   866
                1.0
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   867
            };
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   868
            if density >= target_density {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   869
                break;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   870
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   871
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   872
        selected.sort_unstable();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   873
        selected.push(revs.len());
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   874
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   875
        // Cut the revs at collected indices
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   876
        let mut previous_idx = 0;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   877
        let mut chunks = vec![];
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   878
        for idx in selected {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   879
            let chunk = self.trim_chunk(&entries, previous_idx, idx);
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   880
            if !chunk.is_empty() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   881
                chunks.push(chunk.iter().map(|(rev, _entry)| *rev).collect());
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   882
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   883
            previous_idx = idx;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   884
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   885
        let chunk = self.trim_chunk(&entries, previous_idx, entries.len());
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   886
        if !chunk.is_empty() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   887
            chunks.push(chunk.iter().map(|(rev, _entry)| *rev).collect());
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   888
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   889
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   890
        chunks
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   891
    }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   892
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   893
    /// Get the byte span of a segment of sorted revisions.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   894
    ///
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   895
    /// Occurrences of [`NULL_REVISION`] are ignored at the beginning of
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   896
    /// the `revs` segment.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   897
    ///
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   898
    /// panics:
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   899
    ///  - if `revs` is empty or only made of `NULL_REVISION`
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   900
    ///  - if cannot retrieve entry for the last or first not null element of
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   901
    ///    `revs`.
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   902
    fn segment_span(&self, revs: &[Revision]) -> usize {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   903
        if revs.is_empty() {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   904
            return 0;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   905
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   906
        let last_entry = &self.get_entry(revs[revs.len() - 1]).unwrap();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   907
        let end = last_entry.c_start() + last_entry.compressed_len() as u64;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   908
        let first_rev = revs.iter().find(|r| r.0 != NULL_REVISION.0).unwrap();
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   909
        let start = if (*first_rev).0 == 0 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   910
            0
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   911
        } else {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   912
            self.get_entry(*first_rev).unwrap().c_start()
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   913
        };
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   914
        (end - start) as usize
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   915
    }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   916
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   917
    /// Returns `&revs[startidx..endidx]` without empty trailing revs
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   918
    fn trim_chunk<'a>(
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   919
        &'a self,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   920
        revs: &'a [(Revision, IndexEntry)],
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   921
        start: usize,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   922
        mut end: usize,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   923
    ) -> &'a [(Revision, IndexEntry)] {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   924
        // Trim empty revs at the end, except the very first rev of a chain
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   925
        let last_rev = revs[end - 1].0;
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   926
        if last_rev.0 < self.len() as BaseRevision {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   927
            while end > 1
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   928
                && end > start
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   929
                && revs[end - 1].1.compressed_len() == 0
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   930
            {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   931
                end -= 1
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   932
            }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   933
        }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   934
        &revs[start..end]
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
   935
    }
51220
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   936
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   937
    /// Computes the set of revisions for each non-public phase from `roots`,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   938
    /// which are the last known roots for each non-public phase.
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   939
    pub fn compute_phases_map_sets(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   940
        &self,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   941
        roots: HashMap<Phase, Vec<Revision>>,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   942
    ) -> Result<(usize, RootsPerPhase), GraphError> {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   943
        let mut phases = HashMap::new();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   944
        let mut min_phase_rev = NULL_REVISION;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   945
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   946
        for phase in Phase::non_public_phases() {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   947
            if let Some(phase_roots) = roots.get(phase) {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   948
                let min_rev =
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   949
                    self.add_roots_get_min(phase_roots, &mut phases, *phase);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   950
                if min_rev != NULL_REVISION
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   951
                    && (min_phase_rev == NULL_REVISION
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   952
                        || min_rev < min_phase_rev)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   953
                {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   954
                    min_phase_rev = min_rev;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   955
                }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   956
            } else {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   957
                continue;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   958
            };
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   959
        }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   960
        let mut phase_sets: RootsPerPhase = Default::default();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   961
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   962
        if min_phase_rev == NULL_REVISION {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   963
            min_phase_rev = Revision(self.len() as BaseRevision);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   964
        }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   965
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   966
        for rev in min_phase_rev.0..self.len() as BaseRevision {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   967
            let rev = Revision(rev);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   968
            let [p1, p2] = self.parents(rev)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   969
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   970
            const DEFAULT_PHASE: &Phase = &Phase::Public;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   971
            if p1.0 >= 0
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   972
                && phases.get(&p1).unwrap_or(DEFAULT_PHASE)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   973
                    > phases.get(&rev).unwrap_or(DEFAULT_PHASE)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   974
            {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   975
                phases.insert(rev, phases[&p1]);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   976
            }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   977
            if p2.0 >= 0
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   978
                && phases.get(&p2).unwrap_or(DEFAULT_PHASE)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   979
                    > phases.get(&rev).unwrap_or(DEFAULT_PHASE)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   980
            {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   981
                phases.insert(rev, phases[&p2]);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   982
            }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   983
            let set = match phases.get(&rev).unwrap_or(DEFAULT_PHASE) {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   984
                Phase::Public => continue,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   985
                phase => &mut phase_sets[*phase as usize - 1],
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   986
            };
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   987
            set.insert(rev);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   988
        }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   989
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   990
        Ok((self.len(), phase_sets))
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   991
    }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   992
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   993
    fn add_roots_get_min(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   994
        &self,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   995
        phase_roots: &[Revision],
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   996
        phases: &mut HashMap<Revision, Phase>,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   997
        phase: Phase,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   998
    ) -> Revision {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
   999
        let mut min_rev = NULL_REVISION;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1000
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1001
        for root in phase_roots {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1002
            phases.insert(*root, phase);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1003
            if min_rev == NULL_REVISION || min_rev > *root {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1004
                min_rev = *root;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1005
            }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1006
        }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1007
        min_rev
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1008
    }
51222
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1009
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1010
    /// Return `(heads(::(<roots> and <roots>::<heads>)))`
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1011
    /// If `include_path` is `true`, return `(<roots>::<heads>)`."""
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1012
    ///
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1013
    /// `min_root` and `roots` are unchecked since they are just used as
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1014
    /// a bound or for comparison and don't need to represent a valid revision.
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1015
    /// In practice, the only invalid revision passed is the working directory
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1016
    /// revision ([`i32::MAX`]).
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1017
    pub fn reachable_roots(
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1018
        &self,
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1019
        min_root: UncheckedRevision,
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1020
        mut heads: Vec<Revision>,
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1021
        roots: HashSet<UncheckedRevision>,
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1022
        include_path: bool,
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1023
    ) -> Result<HashSet<Revision>, GraphError> {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1024
        if roots.is_empty() {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1025
            return Ok(HashSet::new());
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1026
        }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1027
        let mut reachable = HashSet::new();
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1028
        let mut seen = HashMap::new();
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1029
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1030
        while let Some(rev) = heads.pop() {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1031
            if roots.contains(&rev.into()) {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1032
                reachable.insert(rev);
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1033
                if !include_path {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1034
                    continue;
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1035
                }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1036
            }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1037
            let parents = self.parents(rev)?;
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1038
            seen.insert(rev, parents);
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1039
            for parent in parents {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1040
                if parent.0 >= min_root.0 && !seen.contains_key(&parent) {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1041
                    heads.push(parent);
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1042
                }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1043
            }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1044
        }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1045
        if !include_path {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1046
            return Ok(reachable);
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1047
        }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1048
        let mut revs: Vec<_> = seen.keys().collect();
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1049
        revs.sort_unstable();
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1050
        for rev in revs {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1051
            for parent in seen[rev] {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1052
                if reachable.contains(&parent) {
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1053
                    reachable.insert(*rev);
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1054
                }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1055
            }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1056
        }
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1057
        Ok(reachable)
fc05dd74e907 rust-index: add support for `reachableroots2`
Raphaël Gomès <rgomes@octobus.net>
parents: 51220
diff changeset
  1058
    }
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1059
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1060
    /// Given a (possibly overlapping) set of revs, return all the
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1061
    /// common ancestors heads: `heads(::args[0] and ::a[1] and ...)`
51225
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1062
    pub fn common_ancestor_heads(
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1063
        &self,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1064
        revisions: &[Revision],
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1065
    ) -> Result<Vec<Revision>, GraphError> {
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1066
        // given that revisions is expected to be small, we find this shortcut
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1067
        // potentially acceptable, especially given that `hg-cpython` could
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1068
        // very much bypass this, constructing a vector of unique values from
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1069
        // the onset.
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1070
        let as_set: HashSet<Revision> = revisions.iter().copied().collect();
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1071
        // Besides deduplicating, the C version also implements the shortcut
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1072
        // for `NULL_REVISION`:
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1073
        if as_set.contains(&NULL_REVISION) {
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1074
            return Ok(vec![]);
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1075
        }
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1076
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1077
        let revisions: Vec<Revision> = as_set.into_iter().collect();
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1078
51229
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1079
        if revisions.len() < 8 {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1080
            self.find_gca_candidates::<u8>(&revisions)
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1081
        } else if revisions.len() < 64 {
51225
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1082
            self.find_gca_candidates::<u64>(&revisions)
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1083
        } else {
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1084
            self.find_gca_candidates::<NonStaticPoisonableBitSet>(&revisions)
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1085
        }
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1086
    }
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1087
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1088
    pub fn ancestors(
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1089
        &self,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1090
        revisions: &[Revision],
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1091
    ) -> Result<Vec<Revision>, GraphError> {
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
  1092
        self.find_deepest_revs(&self.common_ancestor_heads(revisions)?)
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1093
    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1094
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1095
    /// Given a disjoint set of revs, return all candidates for the
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1096
    /// greatest common ancestor. In revset notation, this is the set
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1097
    /// `heads(::a and ::b and ...)`
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1098
    fn find_gca_candidates<BS: PoisonableBitSet + Clone>(
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1099
        &self,
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1100
        revs: &[Revision],
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1101
    ) -> Result<Vec<Revision>, GraphError> {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1102
        if revs.is_empty() {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1103
            return Ok(vec![]);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1104
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1105
        let revcount = revs.len();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1106
        let mut candidates = vec![];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1107
        let max_rev = revs.iter().max().unwrap();
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1108
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1109
        let mut seen = BS::vec_of_empty(revs.len(), (max_rev.0 + 1) as usize);
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1110
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1111
        for (idx, rev) in revs.iter().enumerate() {
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1112
            seen[rev.0 as usize].add(idx);
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1113
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1114
        let mut current_rev = *max_rev;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1115
        // Number of revisions whose inspection in the main loop
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1116
        // will give a result or trigger inspection of other revisions
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1117
        let mut interesting = revcount;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1118
51226
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1119
        // The algorithm works on a vector of bit sets, indexed by revision
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1120
        // numbers and iterated on reverse order.
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1121
        // An entry in this vector is poisoned if and only if the corresponding
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1122
        // revision is a common, yet not maximal ancestor.
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1123
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1124
        // The principle of the algorithm is as follows:
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1125
        // For a revision `r`, when entering the loop, `seen[r]` is either
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1126
        // poisoned or the sub set of `revs` of which `r` is an ancestor.
51226
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1127
        // In this sub set is full, then `r` is a solution and its parents
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1128
        // have to be poisoned.
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1129
        //
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1130
        // At each iteration, the bit sets of the parents are updated by
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1131
        // union with `seen[r]`.
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1132
        // As we walk the index from the end, we are sure we have encountered
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1133
        // all children of `r` before `r`, hence we know that `seen[r]` is
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1134
        // fully computed.
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1135
        //
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1136
        // On top of that there are several optimizations that make reading
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1137
        // less obvious than the comment above:
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1138
        // - The `interesting` counter allows to break early
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1139
        // - The loop starts from `max(revs)`
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1140
        // - Early return in case it is detected that one of the incoming revs
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1141
        //   is a common ancestor of all of them.
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1142
        while current_rev.0 >= 0 && interesting > 0 {
51226
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1143
            let current_seen = seen[current_rev.0 as usize].clone();
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1144
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1145
            if current_seen.is_empty() {
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1146
                current_rev = Revision(current_rev.0 - 1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1147
                continue;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1148
            }
51226
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1149
            let mut poison = current_seen.is_poisoned();
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1150
            if !poison {
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1151
                interesting -= 1;
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1152
                if current_seen.is_full_range(revcount) {
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1153
                    candidates.push(current_rev);
51226
83091c14058c rust-index: avoid some cloning in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51225
diff changeset
  1154
                    poison = true;
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1155
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1156
                    // Being a common ancestor, if `current_rev` is among
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1157
                    // the input revisions, it is *the* answer.
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1158
                    for rev in revs {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1159
                        if *rev == current_rev {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1160
                            return Ok(candidates);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1161
                        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1162
                    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1163
                }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1164
            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1165
            for parent in self.parents(current_rev)? {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1166
                if parent == NULL_REVISION {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1167
                    continue;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1168
                }
51228
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1169
                let parent_seen = &mut seen[parent.0 as usize];
51227
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1170
                if poison {
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1171
                    // this block is logically equivalent to poisoning parent
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1172
                    // and counting it as non interesting if it
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1173
                    // has been seen before (hence counted then as interesting)
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1174
                    if !parent_seen.is_empty() && !parent_seen.is_poisoned() {
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1175
                        interesting -= 1;
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1176
                    }
51228
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1177
                    parent_seen.poison();
51227
e553cd209215 rust-index: avoid double negation in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
  1178
                } else {
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1179
                    if parent_seen.is_empty() {
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1180
                        interesting += 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1181
                    }
51228
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1182
                    parent_seen.union(&current_seen);
51223
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1183
                }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1184
            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1185
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1186
            current_rev = Revision(current_rev.0 - 1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1187
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1188
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1189
        Ok(candidates)
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1190
    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1191
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1192
    /// Given a disjoint set of revs, return the subset with the longest path
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1193
    /// to the root.
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1194
    fn find_deepest_revs(
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1195
        &self,
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1196
        revs: &[Revision],
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1197
    ) -> Result<Vec<Revision>, GraphError> {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1198
        // TODO replace this all with just comparing rank?
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1199
        // Also, the original implementations in C/Python are cryptic, not
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1200
        // even sure we actually need this?
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1201
        if revs.len() <= 1 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1202
            return Ok(revs.to_owned());
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1203
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1204
        let max_rev = revs.iter().max().unwrap().0;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1205
        let mut interesting = HashMap::new();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1206
        let mut seen = vec![0; max_rev as usize + 1];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1207
        let mut depth = vec![0; max_rev as usize + 1];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1208
        let mut mapping = vec![];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1209
        let mut revs = revs.to_owned();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1210
        revs.sort_unstable();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1211
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1212
        for (idx, rev) in revs.iter().enumerate() {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1213
            depth[rev.0 as usize] = 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1214
            let shift = 1 << idx;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1215
            seen[rev.0 as usize] = shift;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1216
            interesting.insert(shift, 1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1217
            mapping.push((shift, *rev));
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1218
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1219
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1220
        let mut current_rev = Revision(max_rev);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1221
        while current_rev.0 >= 0 && interesting.len() > 1 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1222
            let current_depth = depth[current_rev.0 as usize];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1223
            if current_depth == 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1224
                current_rev = Revision(current_rev.0 - 1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1225
                continue;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1226
            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1227
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1228
            let current_seen = seen[current_rev.0 as usize];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1229
            for parent in self.parents(current_rev)? {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1230
                if parent == NULL_REVISION {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1231
                    continue;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1232
                }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1233
                let parent_seen = seen[parent.0 as usize];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1234
                let parent_depth = depth[parent.0 as usize];
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1235
                if parent_depth <= current_depth {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1236
                    depth[parent.0 as usize] = current_depth + 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1237
                    if parent_seen != current_seen {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1238
                        *interesting.get_mut(&current_seen).unwrap() += 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1239
                        seen[parent.0 as usize] = current_seen;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1240
                        if parent_seen != 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1241
                            let parent_interesting =
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1242
                                interesting.get_mut(&parent_seen).unwrap();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1243
                            *parent_interesting -= 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1244
                            if *parent_interesting == 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1245
                                interesting.remove(&parent_seen);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1246
                            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1247
                        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1248
                    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1249
                } else if current_depth == parent_depth - 1 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1250
                    let either_seen = parent_seen | current_seen;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1251
                    if either_seen == parent_seen {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1252
                        continue;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1253
                    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1254
                    seen[parent.0 as usize] = either_seen;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1255
                    interesting
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1256
                        .entry(either_seen)
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1257
                        .and_modify(|v| *v += 1)
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1258
                        .or_insert(1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1259
                    *interesting.get_mut(&parent_seen).unwrap() -= 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1260
                    if interesting[&parent_seen] == 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1261
                        interesting.remove(&parent_seen);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1262
                    }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1263
                }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1264
            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1265
            *interesting.get_mut(&current_seen).unwrap() -= 1;
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1266
            if interesting[&current_seen] == 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1267
                interesting.remove(&current_seen);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1268
            }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1269
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1270
            current_rev = Revision(current_rev.0 - 1);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1271
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1272
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1273
        if interesting.len() != 1 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1274
            return Ok(vec![]);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1275
        }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1276
        let mask = interesting.keys().next().unwrap();
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1277
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1278
        Ok(mapping
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1279
            .into_iter()
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1280
            .filter_map(|(shift, rev)| {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1281
                if (mask & shift) != 0 {
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1282
                    return Some(rev);
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1283
                }
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1284
                None
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1285
            })
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1286
            .collect())
42c8dbdb88ad rust-index: core impl for find_gca_candidates and find_deepest
Raphaël Gomès <rgomes@octobus.net>
parents: 51222
diff changeset
  1287
    }
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1288
}
51220
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1289
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1290
/// The kind of functionality needed by find_gca_candidates
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1291
///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1292
/// This is a bit mask which can be declared to be "poisoned", which callers
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1293
/// interpret to break out of some loops.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1294
///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1295
/// The maximum capacity of the bit mask is up to the actual implementation
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1296
trait PoisonableBitSet: Sized + PartialEq {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1297
    /// Return a vector of exactly n elements, initialized to be empty.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1298
    ///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1299
    /// Optimization can vastly depend on implementation. Those being `Copy`
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1300
    /// and having constant capacity typically can have a very simple
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1301
    /// implementation.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1302
    fn vec_of_empty(sets_size: usize, vec_len: usize) -> Vec<Self>;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1303
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1304
    /// The size of the bit mask in memory
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1305
    fn size(&self) -> usize;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1306
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1307
    /// The number of elements that can be represented in the set.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1308
    ///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1309
    /// Another way to put it is that it is the highest integer `C` such that
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1310
    /// the set is guaranteed to always be a subset of the integer range
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1311
    /// `[0, C)`
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1312
    fn capacity(&self) -> usize;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1313
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1314
    /// Declare `n` to belong to the set
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1315
    fn add(&mut self, n: usize);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1316
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1317
    /// Declare `n` not to belong to the set
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1318
    fn discard(&mut self, n: usize);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1319
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1320
    /// Replace this bit set by its union with other
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1321
    fn union(&mut self, other: &Self);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1322
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1323
    /// Poison the bit set
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1324
    ///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1325
    /// Interpretation up to the caller
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1326
    fn poison(&mut self);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1327
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1328
    /// Is the bit set poisoned?
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1329
    ///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1330
    /// Interpretation is up to the caller
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1331
    fn is_poisoned(&self) -> bool;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1332
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1333
    /// Is the bit set empty?
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1334
    fn is_empty(&self) -> bool;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1335
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1336
    /// return `true` if and only if the bit is the full range `[0, n)`
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1337
    /// of integers
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1338
    fn is_full_range(&self, n: usize) -> bool;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1339
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1340
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1341
const U64_POISON: u64 = 1 << 63;
51229
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1342
const U8_POISON: u8 = 1 << 7;
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1343
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1344
impl PoisonableBitSet for u64 {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1345
    fn vec_of_empty(_sets_size: usize, vec_len: usize) -> Vec<Self> {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1346
        vec![0u64; vec_len]
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1347
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1348
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1349
    fn size(&self) -> usize {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1350
        8
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1351
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1352
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1353
    fn capacity(&self) -> usize {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1354
        63
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1355
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1356
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1357
    fn add(&mut self, n: usize) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1358
        (*self) |= 1u64 << n;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1359
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1360
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1361
    fn discard(&mut self, n: usize) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1362
        (*self) &= u64::MAX - (1u64 << n);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1363
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1364
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1365
    fn union(&mut self, other: &Self) {
51228
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1366
        if *self != *other {
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1367
            (*self) |= *other;
61a6ef876efd rust-index: simplification in find_gca_candidates()
Georges Racinet <georges.racinet@octobus.net>
parents: 51227
diff changeset
  1368
        }
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1369
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1370
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1371
    fn is_full_range(&self, n: usize) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1372
        *self + 1 == (1u64 << n)
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1373
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1374
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1375
    fn is_empty(&self) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1376
        *self == 0
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1377
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1378
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1379
    fn poison(&mut self) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1380
        *self = U64_POISON;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1381
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1382
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1383
    fn is_poisoned(&self) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1384
        // equality comparison would be tempting but would not resist
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1385
        // operations after poisoning (even if these should be bogus).
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1386
        *self >= U64_POISON
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1387
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1388
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1389
51229
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1390
impl PoisonableBitSet for u8 {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1391
    fn vec_of_empty(_sets_size: usize, vec_len: usize) -> Vec<Self> {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1392
        vec![0; vec_len]
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1393
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1394
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1395
    fn size(&self) -> usize {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1396
        1
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1397
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1398
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1399
    fn capacity(&self) -> usize {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1400
        7
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1401
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1402
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1403
    fn add(&mut self, n: usize) {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1404
        (*self) |= 1 << n;
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1405
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1406
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1407
    fn discard(&mut self, n: usize) {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1408
        (*self) &= u8::MAX - (1 << n);
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1409
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1410
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1411
    fn union(&mut self, other: &Self) {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1412
        if *self != *other {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1413
            (*self) |= *other;
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1414
        }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1415
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1416
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1417
    fn is_full_range(&self, n: usize) -> bool {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1418
        *self + 1 == (1 << n)
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1419
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1420
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1421
    fn is_empty(&self) -> bool {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1422
        *self == 0
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1423
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1424
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1425
    fn poison(&mut self) {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1426
        *self = U8_POISON;
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1427
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1428
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1429
    fn is_poisoned(&self) -> bool {
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1430
        // equality comparison would be tempting but would not resist
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1431
        // operations after poisoning (even if these should be bogus).
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1432
        *self >= U8_POISON
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1433
    }
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1434
}
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51228
diff changeset
  1435
51224
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1436
/// A poisonable bit set whose capacity is not known at compile time but
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1437
/// is constant after initial construction
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1438
///
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1439
/// This can be way further optimized if performance assessments (speed
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1440
/// and/or RAM) require it.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1441
/// As far as RAM is concerned, for large vectors of these, the main problem
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1442
/// would be the repetition of set_size in each item. We would need a trait
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1443
/// to abstract over the idea of a vector of such bit sets to do better.
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1444
#[derive(Clone, PartialEq)]
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1445
struct NonStaticPoisonableBitSet {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1446
    set_size: usize,
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1447
    bit_set: Vec<u64>,
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1448
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1449
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1450
/// Number of `u64` needed for a [`NonStaticPoisonableBitSet`] of given size
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1451
fn non_static_poisonable_inner_len(set_size: usize) -> usize {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1452
    1 + (set_size + 1) / 64
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1453
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1454
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1455
impl NonStaticPoisonableBitSet {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1456
    /// The index of the sub-bit set for the given n, and the index inside
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1457
    /// the latter
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1458
    fn index(&self, n: usize) -> (usize, usize) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1459
        (n / 64, n % 64)
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1460
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1461
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1462
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1463
/// Mock implementation to ensure that the trait makes sense
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1464
impl PoisonableBitSet for NonStaticPoisonableBitSet {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1465
    fn vec_of_empty(set_size: usize, vec_len: usize) -> Vec<Self> {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1466
        let tmpl = Self {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1467
            set_size,
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1468
            bit_set: vec![0u64; non_static_poisonable_inner_len(set_size)],
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1469
        };
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1470
        vec![tmpl; vec_len]
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1471
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1472
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1473
    fn size(&self) -> usize {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1474
        8 + self.bit_set.len() * 8
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1475
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1476
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1477
    fn capacity(&self) -> usize {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1478
        self.set_size
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1479
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1480
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1481
    fn add(&mut self, n: usize) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1482
        let (sub_bs, bit_pos) = self.index(n);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1483
        self.bit_set[sub_bs] |= 1 << bit_pos
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1484
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1485
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1486
    fn discard(&mut self, n: usize) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1487
        let (sub_bs, bit_pos) = self.index(n);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1488
        self.bit_set[sub_bs] |= u64::MAX - (1 << bit_pos)
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1489
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1490
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1491
    fn union(&mut self, other: &Self) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1492
        assert!(
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1493
            self.set_size == other.set_size,
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1494
            "Binary operations on bit sets can only be done on same size"
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1495
        );
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1496
        for i in 0..self.bit_set.len() - 1 {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1497
            self.bit_set[i] |= other.bit_set[i]
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1498
        }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1499
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1500
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1501
    fn is_full_range(&self, n: usize) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1502
        let (sub_bs, bit_pos) = self.index(n);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1503
        self.bit_set[..sub_bs].iter().all(|bs| *bs == u64::MAX)
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1504
            && self.bit_set[sub_bs] == (1 << (bit_pos + 1)) - 1
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1505
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1506
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1507
    fn is_empty(&self) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1508
        self.bit_set.iter().all(|bs| *bs == 0u64)
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1509
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1510
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1511
    fn poison(&mut self) {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1512
        let (sub_bs, bit_pos) = self.index(self.set_size);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1513
        self.bit_set[sub_bs] = 1 << bit_pos;
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1514
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1515
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1516
    fn is_poisoned(&self) -> bool {
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1517
        let (sub_bs, bit_pos) = self.index(self.set_size);
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1518
        self.bit_set[sub_bs] >= 1 << bit_pos
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1519
    }
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1520
}
43241f31cf5b rust-index: find_gca_candidates bit sets genericization
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51223
diff changeset
  1521
51220
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1522
/// Set of roots of all non-public phases
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1523
pub type RootsPerPhase = [HashSet<Revision>; Phase::non_public_phases().len()];
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1524
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1525
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1526
pub enum Phase {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1527
    Public = 0,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1528
    Draft = 1,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1529
    Secret = 2,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1530
    Archived = 3,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1531
    Internal = 4,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1532
}
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1533
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1534
impl TryFrom<usize> for Phase {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1535
    type Error = RevlogError;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1536
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1537
    fn try_from(value: usize) -> Result<Self, Self::Error> {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1538
        Ok(match value {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1539
            0 => Self::Public,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1540
            1 => Self::Draft,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1541
            2 => Self::Secret,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1542
            32 => Self::Archived,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1543
            96 => Self::Internal,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1544
            v => {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1545
                return Err(RevlogError::corrupted(format!(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1546
                    "invalid phase value {}",
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1547
                    v
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1548
                )))
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1549
            }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1550
        })
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1551
    }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1552
}
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1553
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1554
impl Phase {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1555
    pub const fn all_phases() -> &'static [Self] {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1556
        &[
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1557
            Self::Public,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1558
            Self::Draft,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1559
            Self::Secret,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1560
            Self::Archived,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1561
            Self::Internal,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1562
        ]
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1563
    }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1564
    pub const fn non_public_phases() -> &'static [Self] {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1565
        &[Self::Draft, Self::Secret, Self::Archived, Self::Internal]
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1566
    }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1567
}
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Raphaël Gomès <rgomes@octobus.net>
parents: 51218
diff changeset
  1568
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1569
fn inline_scan(bytes: &[u8]) -> (usize, Vec<usize>) {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1570
    let mut offset: usize = 0;
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1571
    let mut offsets = Vec::new();
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1572
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1573
    while offset + INDEX_ENTRY_SIZE <= bytes.len() {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1574
        offsets.push(offset);
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1575
        let end = offset + INDEX_ENTRY_SIZE;
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1576
        let entry = IndexEntry {
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1577
            bytes: &bytes[offset..end],
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1578
            offset_override: None,
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1579
        };
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1580
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1581
        offset += INDEX_ENTRY_SIZE + entry.compressed_len() as usize;
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1582
    }
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
  1583
    (offset, offsets)
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1584
}
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1585
46090
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1586
impl super::RevlogIndex for Index {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1587
    fn len(&self) -> usize {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1588
        self.len()
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1589
    }
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1590
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1591
    fn node(&self, rev: Revision) -> Option<&Node> {
51209
e9d47e2f5dcf rust-index: add missing special case for null rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51205
diff changeset
  1592
        if rev == NULL_REVISION {
e9d47e2f5dcf rust-index: add missing special case for null rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51205
diff changeset
  1593
            return Some(&NULL_NODE);
e9d47e2f5dcf rust-index: add missing special case for null rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51205
diff changeset
  1594
        }
46090
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1595
        self.get_entry(rev).map(|entry| entry.hash())
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1596
    }
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1597
}
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1598
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1599
#[derive(Debug)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1600
pub struct IndexEntry<'a> {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1601
    bytes: &'a [u8],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1602
    /// Allows to override the offset value of the entry.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1603
    ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1604
    /// For interleaved index and data, the offset stored in the index
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1605
    /// corresponds to the separated data offset.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1606
    /// It has to be overridden with the actual offset in the interleaved
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1607
    /// index which is just after the index block.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1608
    ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1609
    /// For separated index and data, the offset stored in the first index
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1610
    /// entry is mixed with the index headers.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1611
    /// It has to be overridden with 0.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1612
    offset_override: Option<usize>,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1613
}
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1614
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1615
impl<'a> IndexEntry<'a> {
45593
da30e4b553c3 hg-core: minor docstring update (D8958#inline-14991 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45592
diff changeset
  1616
    /// Return the offset of the data.
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1617
    pub fn offset(&self) -> usize {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1618
        if let Some(offset_override) = self.offset_override {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1619
            offset_override
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1620
        } else {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1621
            let mut bytes = [0; 8];
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1622
            bytes[2..8].copy_from_slice(&self.bytes[0..=5]);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1623
            BigEndian::read_u64(&bytes[..]) as usize
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1624
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1625
    }
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
  1626
    pub fn raw_offset(&self) -> u64 {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
  1627
        BigEndian::read_u64(&self.bytes[0..8])
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51203
diff changeset
  1628
    }
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1629
51218
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
  1630
    /// Same result (except potentially for rev 0) as C `index_get_start()`
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
  1631
    fn c_start(&self) -> u64 {
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
  1632
        self.raw_offset() >> 16
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
  1633
    }
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Raphaël Gomès <rgomes@octobus.net>
parents: 51216
diff changeset
  1634
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48543
diff changeset
  1635
    pub fn flags(&self) -> u16 {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48543
diff changeset
  1636
        BigEndian::read_u16(&self.bytes[6..=7])
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48543
diff changeset
  1637
    }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48543
diff changeset
  1638
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1639
    /// Return the compressed length of the data.
48543
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48458
diff changeset
  1640
    pub fn compressed_len(&self) -> u32 {
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48458
diff changeset
  1641
        BigEndian::read_u32(&self.bytes[8..=11])
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1642
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1643
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1644
    /// Return the uncompressed length of the data.
48543
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48458
diff changeset
  1645
    pub fn uncompressed_len(&self) -> i32 {
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48458
diff changeset
  1646
        BigEndian::read_i32(&self.bytes[12..=15])
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1647
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1648
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1649
    /// Return the revision upon which the data has been derived.
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1650
    pub fn base_revision_or_base_of_delta_chain(&self) -> UncheckedRevision {
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1651
        // TODO Maybe return an Option when base_revision == rev?
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1652
        //      Requires to add rev to IndexEntry
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1653
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1654
        BigEndian::read_i32(&self.bytes[16..]).into()
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1655
    }
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1656
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1657
    pub fn link_revision(&self) -> UncheckedRevision {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1658
        BigEndian::read_i32(&self.bytes[20..]).into()
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1659
    }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1660
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1661
    pub fn p1(&self) -> UncheckedRevision {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1662
        BigEndian::read_i32(&self.bytes[24..]).into()
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1663
    }
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1664
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1665
    pub fn p2(&self) -> UncheckedRevision {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1666
        BigEndian::read_i32(&self.bytes[28..]).into()
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1667
    }
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1668
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1669
    /// Return the hash of revision's full text.
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1670
    ///
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1671
    /// Currently, SHA-1 is used and only the first 20 bytes of this field
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1672
    /// are used.
46090
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46033
diff changeset
  1673
    pub fn hash(&self) -> &'a Node {
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45602
diff changeset
  1674
        (&self.bytes[32..52]).try_into().unwrap()
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45526
diff changeset
  1675
    }
51203
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
  1676
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
  1677
    pub fn as_bytes(&self) -> &'a [u8] {
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
  1678
        self.bytes
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Raphaël Gomès <rgomes@octobus.net>
parents: 51198
diff changeset
  1679
    }
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1680
}
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1681
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1682
#[cfg(test)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1683
mod tests {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1684
    use super::*;
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1685
    use crate::node::NULL_NODE;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1686
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1687
    #[cfg(test)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1688
    #[derive(Debug, Copy, Clone)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1689
    pub struct IndexEntryBuilder {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1690
        is_first: bool,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1691
        is_inline: bool,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1692
        is_general_delta: bool,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1693
        version: u16,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1694
        offset: usize,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1695
        compressed_len: usize,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1696
        uncompressed_len: usize,
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1697
        base_revision_or_base_of_delta_chain: Revision,
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1698
        link_revision: Revision,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1699
        p1: Revision,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1700
        p2: Revision,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1701
        node: Node,
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1702
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1703
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1704
    #[cfg(test)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1705
    impl IndexEntryBuilder {
49926
0780371d6b1e rust-clippy: tell `clippy` we don't need to declare a default here
Raphaël Gomès <rgomes@octobus.net>
parents: 49630
diff changeset
  1706
        #[allow(clippy::new_without_default)]
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1707
        pub fn new() -> Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1708
            Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1709
                is_first: false,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1710
                is_inline: false,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1711
                is_general_delta: true,
49092
d200ecb76c72 rust-revlog: change default version from 2 to 1 in test builder
Martin von Zweigbergk <martinvonz@google.com>
parents: 48546
diff changeset
  1712
                version: 1,
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1713
                offset: 0,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1714
                compressed_len: 0,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1715
                uncompressed_len: 0,
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1716
                base_revision_or_base_of_delta_chain: Revision(0),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1717
                link_revision: Revision(0),
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1718
                p1: NULL_REVISION,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1719
                p2: NULL_REVISION,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1720
                node: NULL_NODE,
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1721
            }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1722
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1723
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1724
        pub fn is_first(&mut self, value: bool) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1725
            self.is_first = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1726
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1727
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1728
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1729
        pub fn with_inline(&mut self, value: bool) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1730
            self.is_inline = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1731
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1732
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1733
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1734
        pub fn with_general_delta(&mut self, value: bool) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1735
            self.is_general_delta = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1736
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1737
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1738
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1739
        pub fn with_version(&mut self, value: u16) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1740
            self.version = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1741
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1742
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1743
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1744
        pub fn with_offset(&mut self, value: usize) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1745
            self.offset = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1746
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1747
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1748
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1749
        pub fn with_compressed_len(&mut self, value: usize) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1750
            self.compressed_len = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1751
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1752
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1753
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1754
        pub fn with_uncompressed_len(&mut self, value: usize) -> &mut Self {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1755
            self.uncompressed_len = value;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1756
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1757
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1758
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1759
        pub fn with_base_revision_or_base_of_delta_chain(
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1760
            &mut self,
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1761
            value: Revision,
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1762
        ) -> &mut Self {
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1763
            self.base_revision_or_base_of_delta_chain = value;
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1764
            self
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1765
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1766
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1767
        pub fn with_link_revision(&mut self, value: Revision) -> &mut Self {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1768
            self.link_revision = value;
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1769
            self
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1770
        }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1771
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1772
        pub fn with_p1(&mut self, value: Revision) -> &mut Self {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1773
            self.p1 = value;
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1774
            self
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1775
        }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1776
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1777
        pub fn with_p2(&mut self, value: Revision) -> &mut Self {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1778
            self.p2 = value;
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1779
            self
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1780
        }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1781
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1782
        pub fn with_node(&mut self, value: Node) -> &mut Self {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1783
            self.node = value;
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1784
            self
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1785
        }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1786
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1787
        pub fn build(&self) -> Vec<u8> {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1788
            let mut bytes = Vec::with_capacity(INDEX_ENTRY_SIZE);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1789
            if self.is_first {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1790
                bytes.extend(&match (self.is_general_delta, self.is_inline) {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1791
                    (false, false) => [0u8, 0],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1792
                    (false, true) => [0u8, 1],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1793
                    (true, false) => [0u8, 2],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1794
                    (true, true) => [0u8, 3],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1795
                });
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1796
                bytes.extend(&self.version.to_be_bytes());
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1797
                // Remaining offset bytes.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1798
                bytes.extend(&[0u8; 2]);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1799
            } else {
46887
6d5a26e94d9e unit-tests: Fix `cargo test` on 32-bit platforms
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
  1800
                // Offset stored on 48 bits (6 bytes)
6d5a26e94d9e unit-tests: Fix `cargo test` on 32-bit platforms
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
  1801
                bytes.extend(&(self.offset as u64).to_be_bytes()[2..]);
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1802
            }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1803
            bytes.extend(&[0u8; 2]); // Revision flags.
46887
6d5a26e94d9e unit-tests: Fix `cargo test` on 32-bit platforms
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
  1804
            bytes.extend(&(self.compressed_len as u32).to_be_bytes());
6d5a26e94d9e unit-tests: Fix `cargo test` on 32-bit platforms
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
  1805
            bytes.extend(&(self.uncompressed_len as u32).to_be_bytes());
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1806
            bytes.extend(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1807
                &self.base_revision_or_base_of_delta_chain.0.to_be_bytes(),
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1808
            );
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1809
            bytes.extend(&self.link_revision.0.to_be_bytes());
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1810
            bytes.extend(&self.p1.0.to_be_bytes());
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1811
            bytes.extend(&self.p2.0.to_be_bytes());
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1812
            bytes.extend(self.node.as_bytes());
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1813
            bytes.extend(vec![0u8; 12]);
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1814
            bytes
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1815
        }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1816
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1817
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1818
    pub fn is_inline(index_bytes: &[u8]) -> bool {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1819
        IndexHeader::parse(index_bytes)
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1820
            .expect("too short")
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
  1821
            .unwrap()
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1822
            .format_flags()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1823
            .is_inline()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1824
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1825
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1826
    pub fn uses_generaldelta(index_bytes: &[u8]) -> bool {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1827
        IndexHeader::parse(index_bytes)
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1828
            .expect("too short")
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
  1829
            .unwrap()
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1830
            .format_flags()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1831
            .uses_generaldelta()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1832
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1833
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1834
    pub fn get_version(index_bytes: &[u8]) -> u16 {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1835
        IndexHeader::parse(index_bytes)
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1836
            .expect("too short")
51191
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51189
diff changeset
  1837
            .unwrap()
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1838
            .format_version()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1839
    }
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1840
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1841
    #[test]
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1842
    fn flags_when_no_inline_flag_test() {
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1843
        let bytes = IndexEntryBuilder::new()
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1844
            .is_first(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1845
            .with_general_delta(false)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1846
            .with_inline(false)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1847
            .build();
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1848
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1849
        assert!(!is_inline(&bytes));
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1850
        assert!(!uses_generaldelta(&bytes));
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1851
    }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1852
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1853
    #[test]
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1854
    fn flags_when_inline_flag_test() {
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1855
        let bytes = IndexEntryBuilder::new()
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1856
            .is_first(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1857
            .with_general_delta(false)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1858
            .with_inline(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1859
            .build();
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1860
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1861
        assert!(is_inline(&bytes));
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1862
        assert!(!uses_generaldelta(&bytes));
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1863
    }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1864
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1865
    #[test]
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1866
    fn flags_when_inline_and_generaldelta_flags_test() {
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1867
        let bytes = IndexEntryBuilder::new()
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1868
            .is_first(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1869
            .with_general_delta(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1870
            .with_inline(true)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1871
            .build();
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1872
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1873
        assert!(is_inline(&bytes));
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49926
diff changeset
  1874
        assert!(uses_generaldelta(&bytes));
45601
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1875
    }
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1876
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45593
diff changeset
  1877
    #[test]
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1878
    fn test_offset() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1879
        let bytes = IndexEntryBuilder::new().with_offset(1).build();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1880
        let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1881
            bytes: &bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1882
            offset_override: None,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1883
        };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1884
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1885
        assert_eq!(entry.offset(), 1)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1886
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1887
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1888
    #[test]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1889
    fn test_with_overridden_offset() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1890
        let bytes = IndexEntryBuilder::new().with_offset(1).build();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1891
        let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1892
            bytes: &bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1893
            offset_override: Some(2),
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1894
        };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1895
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1896
        assert_eq!(entry.offset(), 2)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1897
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1898
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1899
    #[test]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1900
    fn test_compressed_len() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1901
        let bytes = IndexEntryBuilder::new().with_compressed_len(1).build();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1902
        let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1903
            bytes: &bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1904
            offset_override: None,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1905
        };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1906
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1907
        assert_eq!(entry.compressed_len(), 1)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1908
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1909
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1910
    #[test]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1911
    fn test_uncompressed_len() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1912
        let bytes = IndexEntryBuilder::new().with_uncompressed_len(1).build();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1913
        let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1914
            bytes: &bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1915
            offset_override: None,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1916
        };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1917
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1918
        assert_eq!(entry.uncompressed_len(), 1)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1919
    }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1920
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1921
    #[test]
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1922
    fn test_base_revision_or_base_of_delta_chain() {
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1923
        let bytes = IndexEntryBuilder::new()
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1924
            .with_base_revision_or_base_of_delta_chain(Revision(1))
48458
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48457
diff changeset
  1925
            .build();
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1926
        let entry = IndexEntry {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1927
            bytes: &bytes,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1928
            offset_override: None,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1929
        };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1930
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1931
        assert_eq!(entry.base_revision_or_base_of_delta_chain(), 1.into())
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1932
    }
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1933
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1934
    #[test]
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1935
    fn link_revision_test() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1936
        let bytes = IndexEntryBuilder::new()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1937
            .with_link_revision(Revision(123))
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1938
            .build();
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1939
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1940
        let entry = IndexEntry {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1941
            bytes: &bytes,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1942
            offset_override: None,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1943
        };
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1944
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1945
        assert_eq!(entry.link_revision(), 123.into());
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1946
    }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1947
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1948
    #[test]
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1949
    fn p1_test() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1950
        let bytes = IndexEntryBuilder::new().with_p1(Revision(123)).build();
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1951
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1952
        let entry = IndexEntry {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1953
            bytes: &bytes,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1954
            offset_override: None,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1955
        };
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1956
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1957
        assert_eq!(entry.p1(), 123.into());
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1958
    }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1959
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1960
    #[test]
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1961
    fn p2_test() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50978
diff changeset
  1962
        let bytes = IndexEntryBuilder::new().with_p2(Revision(123)).build();
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1963
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1964
        let entry = IndexEntry {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1965
            bytes: &bytes,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1966
            offset_override: None,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1967
        };
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1968
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
  1969
        assert_eq!(entry.p2(), 123.into());
49093
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1970
    }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1971
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1972
    #[test]
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1973
    fn node_test() {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1974
        let node = Node::from_hex("0123456789012345678901234567890123456789")
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1975
            .unwrap();
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1976
        let bytes = IndexEntryBuilder::new().with_node(node).build();
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1977
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1978
        let entry = IndexEntry {
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1979
            bytes: &bytes,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1980
            offset_override: None,
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1981
        };
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1982
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1983
        assert_eq!(*entry.hash(), node);
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1984
    }
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1985
2a9a55ffe24f rust-revlog: make `IndexEntryBuilder` build a whole entry
Martin von Zweigbergk <martinvonz@google.com>
parents: 49092
diff changeset
  1986
    #[test]
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1987
    fn version_test() {
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1988
        let bytes = IndexEntryBuilder::new()
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1989
            .is_first(true)
49092
d200ecb76c72 rust-revlog: change default version from 2 to 1 in test builder
Martin von Zweigbergk <martinvonz@google.com>
parents: 48546
diff changeset
  1990
            .with_version(2)
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1991
            .build();
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1992
49092
d200ecb76c72 rust-revlog: change default version from 2 to 1 in test builder
Martin von Zweigbergk <martinvonz@google.com>
parents: 48546
diff changeset
  1993
        assert_eq!(get_version(&bytes), 2)
48457
1fb3615dfce2 rhg: centralize index header parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48226
diff changeset
  1994
    }
45526
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1995
}
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1996
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1997
#[cfg(test)]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
  1998
pub use tests::IndexEntryBuilder;