D8098: rust-nodemap: a method for full invalidation
Closed by commit rHGbbc61f36733c: rust-nodemap: a method for full invalidation (authored by gracinet). This revision was automatically updated to reflect the committed changes. This revision was not accepted when it landed; it landed in state "Needs Review". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D8098?vs=20285=20314 CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -575,11 +575,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len(); +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1060,6 +1074,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers, kevincox Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
Alphare updated this revision to Diff 20285. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D8098?vs=20280=20285 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -575,11 +575,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len(); +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1060,6 +1074,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers, kevincox Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
kevincox added inline comments. kevincox accepted this revision. INLINE COMMENTS > nodemap.rs:577 > +/// immutable part. > +pub fn invalidate_all( self) -> () { > +self.root = Block::new(); `-> ()` is unnecessary. > nodemap.rs:580 > +self.growable = Vec::new(); > +self.masked_inner_blocks = self.readonly.len() > +} End the line with a `;`. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 To: marmoute, #hg-reviewers, kevincox Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
Alphare updated this revision to Diff 20280. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D8098?vs=20239=20280 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -572,11 +572,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) -> () { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len() +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1057,6 +1071,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
Alphare updated this revision to Diff 20239. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D8098?vs=20220=20239 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -572,11 +572,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) -> () { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len() +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1057,6 +1071,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
Alphare updated this revision to Diff 20220. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D8098?vs=20030=20220 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D8098/new/ REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -553,11 +553,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) -> () { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len() +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1035,6 +1049,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8098: rust-nodemap: a method for full invalidation
marmoute created this revision. Herald added subscribers: mercurial-devel, kevincox. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This will be used for exceptional operations, such as a `__delitem__` on the `MixedIndex` with Rust nodemap. In principle, `NodeTree` should also be able to forget an entry in an efficient way, by accepting to insert `Element::None` instead of only `Element::Rev(r)`, but that seems really overkill at this point. We need to support exceptional operations such as `__delitem__`, only for completeness of the revlog index as seen from Python. The Python callers don't seem to even really need it, deciding to drop the nodemap inconditionnally at at higher level when calling `hg strip`. Also, `hg strip` is very costly for reasons that are unrelated to nodemap aspects. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D8098 AFFECTED FILES rust/hg-core/src/revlog/nodemap.rs CHANGE DETAILS diff --git a/rust/hg-core/src/revlog/nodemap.rs b/rust/hg-core/src/revlog/nodemap.rs --- a/rust/hg-core/src/revlog/nodemap.rs +++ b/rust/hg-core/src/revlog/nodemap.rs @@ -544,11 +544,25 @@ Ok(()) } +/// Make the whole `NodeTree` logically empty, without touching the +/// immutable part. +pub fn invalidate_all( self) -> () { +self.root = Block::new(); +self.growable = Vec::new(); +self.masked_inner_blocks = self.readonly.len() +} + /// Return the number of blocks in the readonly part that are currently /// masked in the mutable part. /// /// The `NodeTree` structure has no efficient way to know how many blocks /// are already unreachable in the readonly part. +/// +/// After a call to `invalidate_all()`, the returned number can be actually +/// bigger than the whole readonly part, a conventional way to mean that +/// all the readonly blocks have been masked. This is what is really +/// useful to the caller and does not require to know how many were +/// actually unreachable to begin with. pub fn masked_readonly_blocks() -> usize { if let Some(readonly_root) = self.readonly.last() { if readonly_root == { @@ -1025,6 +1039,27 @@ } #[test] +fn test_invalidate_all() -> Result<(), NodeMapError> { +let mut idx = TestNtIndex::new(); +idx.insert(0, "1234")?; +idx.insert(1, "1235")?; +idx.insert(2, "131")?; +idx.insert(3, "cafe")?; +let mut idx = idx.commit(); + +idx.nt.invalidate_all(); + +assert_eq!(idx.find_hex("1234")?, None); +assert_eq!(idx.find_hex("1235")?, None); +assert_eq!(idx.find_hex("131")?, None); +assert_eq!(idx.find_hex("cafe")?, None); +// all the readonly blocks have been masked, this is the +// conventional expected response +assert_eq!(idx.nt.masked_readonly_blocks(), idx.nt.readonly.len() + 1); +Ok(()) +} + +#[test] fn test_into_added_empty() { assert!(sample_nodetree().into_readonly_and_added().1.is_empty()); assert!(sample_nodetree() To: marmoute, #hg-reviewers Cc: kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel