/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
usecrate::query::Queryable; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fmt; use std::mem::size_of;
impl From<bool> for Membership { fn from(b: bool) -> Membership { match b { true => Membership::Member, false => Membership::Nonmember,
}
}
}
/// Metadata needed to compute membership in a clubcard. #[derive(Default, Serialize, Deserialize)] pubstruct ClubcardIndexEntry { /// Description of the hash function h. pub approx_filter_m: usize, /// Description of the hash function g. pub exact_filter_m: usize, /// The number of columns in X. pub approx_filter_rank: usize, /// An offset t such that [0^t || h(u)] * X = h(u) * Xi, where i is the block identifier. pub approx_filter_offset: usize, /// An offset t such that [0^t || g(u)] * Y = g(u) * Yi, where i is the block identifier. pub exact_filter_offset: usize, /// Whether to invert the output of queries to this block. pub inverted: bool, /// A list of elements of Ui \ Ri that are not correctly encoded by this block. pub exceptions: Vec<Vec<u8>>,
}
/// Lookup table from block identifiers to block metadata. pubtype ClubcardIndex = BTreeMap</* block id */ Vec<u8>, ClubcardIndexEntry>;
/// A queryable Clubcard #[derive(Serialize, Deserialize)] pubstruct Clubcard<const W: usize, UniverseMetadata, PartitionMetadata> { /// Metadata for determining whether a Queryable is in the encoded universe. pub universe: UniverseMetadata, /// Metadata for determining the block to which a Queryable belongs. pub partition: PartitionMetadata, /// Lookup table for per-block metadata. pub index: ClubcardIndex, /// The matrix X pub approx_filter: Vec<Vec<u64>>, /// The matrix Y pub exact_filter: Vec<u64>,
}
impl<const W: usize, UniverseMetadata, PartitionMetadata>
Clubcard<W, UniverseMetadata, PartitionMetadata>
{ /// Perform a membership query without checking whether the item is in the universe. /// The result is undefined if the item is not in the universe. The result is also /// undefined if U's implementation of AsQuery differs from T's. pubfn unchecked_contains<T>(&self, item: &T) -> bool where
T: Queryable<W, PartitionMetadata = PartitionMetadata>,
{ let Some(meta) = self.index.get(item.block()) else { returnfalse;
};
let result = (|| { // All queries evaluate to 0 on an empty filter, but logically // such a filter does not include anything. So we handle it as a // special case. if meta.approx_filter_m == 0 { returnfalse;
}
// Check if h(item) * X is 0 let approx_query = item.as_approx_query(meta); for i in0..meta.approx_filter_rank { if approx_query.eval(&self.approx_filter[i]) != 0 { returnfalse;
}
}
// Check if g(item) * X is 0 let exact_query = item.as_exact_query(meta); if exact_query.eval(&self.exact_filter) != 0 { returnfalse;
}
for exception in &meta.exceptions { if exception == item.discriminant() { returnfalse;
}
} true
})();
result ^ meta.inverted
}
/// Check that the item is in the appropriate universe, and then perform a membership query. pubfn contains<T>(&self, item: &T) -> Membership where
T: Queryable<W, UniverseMetadata = UniverseMetadata, PartitionMetadata = PartitionMetadata>,
{ if !item.in_universe(&self.universe) { return Membership::NotInUniverse;
};
if !self.index.contains_key(item.block()) { return Membership::NoData;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.