prefix look up - use fast path for the full hashes

Summary:
It would be better to make the underlying implementation faster for full hash
cases than check when it is used.

Reviewed By: krallin

Differential Revision: D19905033

fbshipit-source-id: 2d9a77099dc614e80fdb1c0ee715c576a56ba09c
This commit is contained in:
Liubov Dmitrieva 2020-02-18 04:13:15 -08:00 committed by Facebook Github Bot
parent 182b50f25e
commit 1e50a66174
6 changed files with 50 additions and 1 deletions

View File

@ -201,6 +201,7 @@ impl BonsaiHgMapping for CachingBonsaiHgMapping {
.boxify()
}
/// Use caching for the full changeset ids and slower path otherwise.
fn get_many_hg_by_prefix(
&self,
ctx: CoreContext,
@ -208,6 +209,15 @@ impl BonsaiHgMapping for CachingBonsaiHgMapping {
cs_prefix: HgChangesetIdPrefix,
limit: usize,
) -> BoxFuture<HgChangesetIdsResolvedFromPrefix, Error> {
if let Some(id) = cs_prefix.into_hg_changeset_id() {
return self
.get(ctx, repo_id, id.into())
.map(move |result| match result.into_iter().next() {
Some(_) if limit > 0 => HgChangesetIdsResolvedFromPrefix::Single(id),
_ => HgChangesetIdsResolvedFromPrefix::NoMatch,
})
.boxify();
}
self.mapping
.get_many_hg_by_prefix(ctx, repo_id, cs_prefix, limit)
}

View File

@ -175,6 +175,7 @@ impl Changesets for CachingChangesets {
.boxify()
}
/// Use caching for the full changeset ids and slower path otherwise.
fn get_many_by_prefix(
&self,
ctx: CoreContext,
@ -182,6 +183,15 @@ impl Changesets for CachingChangesets {
cs_prefix: ChangesetIdPrefix,
limit: usize,
) -> BoxFuture<ChangesetIdsResolvedFromPrefix, Error> {
if let Some(id) = cs_prefix.into_changeset_id() {
return self
.get(ctx, repo_id, id)
.map(move |res| match res {
Some(_) if limit > 0 => ChangesetIdsResolvedFromPrefix::Single(id),
_ => ChangesetIdsResolvedFromPrefix::NoMatch,
})
.boxify();
}
self.changesets
.get_many_by_prefix(ctx, repo_id, cs_prefix, limit)
.boxify()

View File

@ -217,6 +217,16 @@ impl Sha1Prefix {
self.1.as_ref()
}
/// Convert into sha1 if it is the full prefix of the hash.
#[inline]
pub fn into_sha1(self) -> Option<Sha1> {
if self.0 == self.1 {
Some(self.0)
} else {
None
}
}
pub fn to_hex(&self) -> AsciiString {
let mut v_min_hex = vec![0; SHA1_HASH_LENGTH_HEX];
hex_encode(self.0.as_ref(), &mut v_min_hex).expect("failed to hex encode");

View File

@ -40,7 +40,6 @@ pub const NULL_CSID: HgChangesetId = HgChangesetId(NULL_HASH);
pub struct HgNodeHash(pub(crate) Sha1);
impl HgNodeHash {
#[deprecated(note = "This constructor is only used in creation of HgNodeHash mocks")]
pub const fn new(sha1: Sha1) -> Self {
HgNodeHash(sha1)
}
@ -339,6 +338,11 @@ impl HgChangesetIdPrefix {
pub fn max_as_ref(&self) -> &[u8] {
self.0.max_as_ref()
}
#[inline]
pub fn into_hg_changeset_id(self) -> Option<HgChangesetId> {
self.0.into_sha1().map(HgNodeHash).map(HgChangesetId)
}
}
impl FromStr for HgChangesetIdPrefix {

View File

@ -254,6 +254,16 @@ impl Blake2Prefix {
self.1.as_ref()
}
/// Convert into blake2 if it is the full prefix of the hash.
#[inline]
pub fn into_blake2(self) -> Option<Blake2> {
if self.0 == self.1 {
Some(self.0)
} else {
None
}
}
pub fn to_hex(&self) -> AsciiString {
let mut v_min_hex = vec![0; BLAKE2_HASH_LENGTH_HEX];
hex_encode(self.0.as_ref(), &mut v_min_hex).expect("failed to hex encode");

View File

@ -461,6 +461,11 @@ impl ChangesetIdPrefix {
pub fn max_as_ref(&self) -> &[u8] {
self.0.max_as_ref()
}
#[inline]
pub fn into_changeset_id(self) -> Option<ChangesetId> {
self.0.into_blake2().map(ChangesetId)
}
}
impl FromStr for ChangesetIdPrefix {