forked from mirrors/jj
build: conditionally use map_first_last
feature if available
This commit is contained in:
parent
dd3272fe90
commit
9202aae8b1
8 changed files with 75 additions and 34 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -618,6 +618,7 @@ dependencies = [
|
|||
"test-case",
|
||||
"thiserror",
|
||||
"uuid",
|
||||
"version_check",
|
||||
"whoami",
|
||||
"zstd",
|
||||
]
|
||||
|
|
|
@ -14,6 +14,7 @@ readme = "../README.md"
|
|||
|
||||
[build-dependencies]
|
||||
protobuf-codegen-pure = "2.27.1"
|
||||
version_check = "0.9.4"
|
||||
|
||||
[dependencies]
|
||||
backoff = "0.4.0"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
extern crate protobuf_codegen_pure;
|
||||
extern crate version_check;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -45,4 +46,8 @@ fn main() {
|
|||
for file in input {
|
||||
println!("cargo:rerun-if-changed={}", file);
|
||||
}
|
||||
|
||||
if let Some(true) = version_check::supports_feature("map_first_last") {
|
||||
println!("cargo:rustc-cfg=feature=\"map_first_last\"");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ pub(crate) fn unchanged_ranges(
|
|||
|
||||
let max_occurrences = 100;
|
||||
let mut left_histogram = Histogram::calculate(left, left_ranges, max_occurrences);
|
||||
if *left_histogram.count_to_words.ext_first_key().unwrap() > max_occurrences {
|
||||
if *left_histogram.count_to_words.first_key().unwrap() > max_occurrences {
|
||||
// If there are very many occurrences of all words, then we just give up.
|
||||
return vec![];
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ pub(crate) fn unchanged_ranges(
|
|||
// the LCS.
|
||||
let mut uncommon_shared_words = vec![];
|
||||
while !left_histogram.count_to_words.is_empty() && uncommon_shared_words.is_empty() {
|
||||
let left_words = left_histogram.count_to_words.ext_pop_first_value().unwrap();
|
||||
let left_words = left_histogram.count_to_words.pop_first_value().unwrap();
|
||||
for left_word in left_words {
|
||||
if right_histogram.word_to_positions.contains_key(left_word) {
|
||||
uncommon_shared_words.push(left_word);
|
||||
|
|
|
@ -34,6 +34,8 @@ use thiserror::Error;
|
|||
use crate::backend::{ChangeId, CommitId};
|
||||
use crate::commit::Commit;
|
||||
use crate::file_util::persist_content_addressed_temp_file;
|
||||
|
||||
#[cfg(not(feature = "map_first_last"))]
|
||||
use crate::nightly_shims::BTreeSetExt;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||
|
@ -813,25 +815,25 @@ impl<'a> CompositeIndex<'a> {
|
|||
|
||||
let mut result = BTreeSet::new();
|
||||
while !(items1.is_empty() || items2.is_empty()) {
|
||||
let entry1 = items1.ext_last().unwrap();
|
||||
let entry2 = items2.ext_last().unwrap();
|
||||
let entry1 = items1.last().unwrap();
|
||||
let entry2 = items2.last().unwrap();
|
||||
match entry1.cmp(entry2) {
|
||||
Ordering::Greater => {
|
||||
let entry1 = items1.ext_pop_last().unwrap();
|
||||
let entry1 = items1.pop_last().unwrap();
|
||||
for parent_entry in entry1.0.parents() {
|
||||
items1.insert(IndexEntryByGeneration(parent_entry));
|
||||
}
|
||||
}
|
||||
Ordering::Less => {
|
||||
let entry2 = items2.ext_pop_last().unwrap();
|
||||
let entry2 = items2.pop_last().unwrap();
|
||||
for parent_entry in entry2.0.parents() {
|
||||
items2.insert(IndexEntryByGeneration(parent_entry));
|
||||
}
|
||||
}
|
||||
Ordering::Equal => {
|
||||
result.insert(entry1.0.pos);
|
||||
items1.ext_pop_last();
|
||||
items2.ext_pop_last();
|
||||
items1.pop_last();
|
||||
items2.pop_last();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#![deny(unused_must_use)]
|
||||
#![cfg_attr(feature = "map_first_last", feature(map_first_last))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
|
|
@ -1,60 +1,91 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
#[cfg(feature = "map_first_last")]
|
||||
pub trait BTreeMapExt<K, V> {
|
||||
fn ext_first_key(&self) -> Option<&K>;
|
||||
fn ext_last_key(&self) -> Option<&K>;
|
||||
fn ext_pop_first_key(&mut self) -> Option<K>;
|
||||
fn ext_pop_last_key(&mut self) -> Option<K>;
|
||||
fn ext_pop_first_value(&mut self) -> Option<V>;
|
||||
fn ext_pop_last_value(&mut self) -> Option<V>;
|
||||
fn first_key(&self) -> Option<&K>;
|
||||
fn last_key(&self) -> Option<&K>;
|
||||
fn pop_first_value(&mut self) -> Option<V>;
|
||||
fn pop_last_value(&mut self) -> Option<V>;
|
||||
}
|
||||
|
||||
impl<K: Ord + Clone, V> BTreeMapExt<K, V> for BTreeMap<K, V> {
|
||||
fn ext_first_key(&self) -> Option<&K> {
|
||||
#[cfg(feature = "map_first_last")]
|
||||
impl<K: Ord + Clone, V> BTreeMapExt<K, V> for std::collections::BTreeMap<K, V> {
|
||||
fn first_key(&self) -> Option<&K> {
|
||||
self.keys().next()
|
||||
}
|
||||
|
||||
fn ext_last_key(&self) -> Option<&K> {
|
||||
fn last_key(&self) -> Option<&K> {
|
||||
self.keys().next_back()
|
||||
}
|
||||
fn pop_first_value(&mut self) -> Option<V> {
|
||||
self.first_entry().map(|x| x.remove())
|
||||
}
|
||||
|
||||
fn pop_last_value(&mut self) -> Option<V> {
|
||||
self.last_entry().map(|x| x.remove())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "map_first_last"))]
|
||||
pub trait BTreeMapExt<K, V> {
|
||||
fn first_key(&self) -> Option<&K>;
|
||||
fn last_key(&self) -> Option<&K>;
|
||||
fn pop_first_key(&mut self) -> Option<K>;
|
||||
fn pop_last_key(&mut self) -> Option<K>;
|
||||
fn pop_first_value(&mut self) -> Option<V>;
|
||||
fn pop_last_value(&mut self) -> Option<V>;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "map_first_last"))]
|
||||
impl<K: Ord + Clone, V> BTreeMapExt<K, V> for std::collections::BTreeMap<K, V> {
|
||||
fn first_key(&self) -> Option<&K> {
|
||||
self.keys().next()
|
||||
}
|
||||
|
||||
fn last_key(&self) -> Option<&K> {
|
||||
self.keys().next_back()
|
||||
}
|
||||
|
||||
fn ext_pop_first_key(&mut self) -> Option<K> {
|
||||
let key = self.ext_first_key()?;
|
||||
fn pop_first_key(&mut self) -> Option<K> {
|
||||
let key = self.first_key()?;
|
||||
let key = key.clone(); // ownership hack
|
||||
Some(self.remove_entry(&key).unwrap().0)
|
||||
}
|
||||
|
||||
fn ext_pop_last_key(&mut self) -> Option<K> {
|
||||
let key = self.ext_last_key()?;
|
||||
fn pop_last_key(&mut self) -> Option<K> {
|
||||
let key = self.last_key()?;
|
||||
let key = key.clone(); // ownership hack
|
||||
Some(self.remove_entry(&key).unwrap().0)
|
||||
}
|
||||
|
||||
fn ext_pop_first_value(&mut self) -> Option<V> {
|
||||
let key = self.ext_first_key()?;
|
||||
fn pop_first_value(&mut self) -> Option<V> {
|
||||
let key = self.first_key()?;
|
||||
let key = key.clone(); // ownership hack
|
||||
Some(self.remove_entry(&key).unwrap().1)
|
||||
}
|
||||
|
||||
fn ext_pop_last_value(&mut self) -> Option<V> {
|
||||
let key = self.ext_last_key()?;
|
||||
fn pop_last_value(&mut self) -> Option<V> {
|
||||
let key = self.last_key()?;
|
||||
let key = key.clone(); // ownership hack
|
||||
Some(self.remove_entry(&key).unwrap().1)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "map_first_last")]
|
||||
pub trait BTreeSetExt<K> {}
|
||||
|
||||
#[cfg(not(feature = "map_first_last"))]
|
||||
pub trait BTreeSetExt<K> {
|
||||
fn ext_last(&self) -> Option<&K>;
|
||||
fn ext_pop_last(&mut self) -> Option<K>;
|
||||
fn last(&self) -> Option<&K>;
|
||||
fn pop_last(&mut self) -> Option<K>;
|
||||
}
|
||||
|
||||
impl<K: Ord + Clone> BTreeSetExt<K> for BTreeSet<K> {
|
||||
fn ext_last(&self) -> Option<&K> {
|
||||
#[cfg(not(feature = "map_first_last"))]
|
||||
impl<K: Ord + Clone> BTreeSetExt<K> for std::collections::BTreeSet<K> {
|
||||
fn last(&self) -> Option<&K> {
|
||||
self.iter().next_back()
|
||||
}
|
||||
|
||||
fn ext_pop_last(&mut self) -> Option<K> {
|
||||
let key = self.ext_last()?;
|
||||
fn pop_last(&mut self) -> Option<K> {
|
||||
let key = self.last()?;
|
||||
let key = key.clone(); // ownership hack
|
||||
self.take(&key)
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ impl<'revset, 'repo> RevsetGraphIterator<'revset, 'repo> {
|
|||
}
|
||||
|
||||
fn next_index_entry(&mut self) -> Option<IndexEntry<'repo>> {
|
||||
if let Some(index_entry) = self.look_ahead.ext_pop_last_value() {
|
||||
if let Some(index_entry) = self.look_ahead.pop_last_value() {
|
||||
return Some(index_entry);
|
||||
}
|
||||
self.input_set_iter.next()
|
||||
|
|
Loading…
Reference in a new issue