mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-02-17 08:10:14 +08:00
SmallBitmap: Consistently panic on incoherent universe lengths
This commit is contained in:
parent
3524bd1257
commit
ef084ef042
@ -51,10 +51,7 @@ impl<T> SmallBitmap<T> {
|
|||||||
///
|
///
|
||||||
/// The universe length is always a multiple of 64, and may be higher than the value passed to [`Self::new`].
|
/// The universe length is always a multiple of 64, and may be higher than the value passed to [`Self::new`].
|
||||||
pub fn universe_length(&self) -> u16 {
|
pub fn universe_length(&self) -> u16 {
|
||||||
match &self.internal {
|
self.internal.universe_length()
|
||||||
SmallBitmapInternal::Tiny(_) => 64,
|
|
||||||
SmallBitmapInternal::Small(xs) => 64 * xs.len() as u16,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `SmallBitmap<T>` with an universe large enough to hold all elements
|
/// Constructs a new `SmallBitmap<T>` with an universe large enough to hold all elements
|
||||||
@ -211,37 +208,71 @@ impl SmallBitmapInternal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn contains(&self, mut x: u16) -> bool {
|
pub fn universe_length(&self) -> u16 {
|
||||||
let set = match self {
|
match &self {
|
||||||
SmallBitmapInternal::Tiny(set) => *set,
|
SmallBitmapInternal::Tiny(_) => 64,
|
||||||
SmallBitmapInternal::Small(set) => {
|
SmallBitmapInternal::Small(xs) => 64 * xs.len() as u16,
|
||||||
let idx = x / 64;
|
}
|
||||||
x %= 64;
|
}
|
||||||
set[idx as usize]
|
|
||||||
|
fn get_set_index(&self, x: u16) -> (u64, u16) {
|
||||||
|
match self {
|
||||||
|
SmallBitmapInternal::Tiny(set) => {
|
||||||
|
assert!(
|
||||||
|
x < 64,
|
||||||
|
"index out of bounds: the universe length is 64 but the index is {}",
|
||||||
|
x
|
||||||
|
);
|
||||||
|
(*set, x)
|
||||||
}
|
}
|
||||||
};
|
SmallBitmapInternal::Small(set) => {
|
||||||
|
let idx = (x as usize) / 64;
|
||||||
|
assert!(
|
||||||
|
idx < set.len(),
|
||||||
|
"index out of bounds: the universe length is {} but the index is {}",
|
||||||
|
self.universe_length(),
|
||||||
|
x
|
||||||
|
);
|
||||||
|
(set[idx], x % 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_set_index_mut(&mut self, x: u16) -> (&mut u64, u16) {
|
||||||
|
match self {
|
||||||
|
SmallBitmapInternal::Tiny(set) => {
|
||||||
|
assert!(
|
||||||
|
x < 64,
|
||||||
|
"index out of bounds: the universe length is 64 but the index is {}",
|
||||||
|
x
|
||||||
|
);
|
||||||
|
(set, x)
|
||||||
|
}
|
||||||
|
SmallBitmapInternal::Small(set) => {
|
||||||
|
let idx = (x as usize) / 64;
|
||||||
|
assert!(
|
||||||
|
idx < set.len(),
|
||||||
|
"index out of bounds: the universe length is {} but the index is {}",
|
||||||
|
64 * set.len() as u16,
|
||||||
|
x
|
||||||
|
);
|
||||||
|
(&mut set[idx], x % 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, x: u16) -> bool {
|
||||||
|
let (set, x) = self.get_set_index(x);
|
||||||
set & 0b1 << x != 0
|
set & 0b1 << x != 0
|
||||||
}
|
}
|
||||||
pub fn insert(&mut self, mut x: u16) {
|
|
||||||
let set = match self {
|
pub fn insert(&mut self, x: u16) {
|
||||||
SmallBitmapInternal::Tiny(set) => set,
|
let (set, x) = self.get_set_index_mut(x);
|
||||||
SmallBitmapInternal::Small(set) => {
|
|
||||||
let idx = x / 64;
|
|
||||||
x %= 64;
|
|
||||||
&mut set[idx as usize]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*set |= 0b1 << x;
|
*set |= 0b1 << x;
|
||||||
}
|
}
|
||||||
pub fn remove(&mut self, mut x: u16) {
|
|
||||||
let set = match self {
|
pub fn remove(&mut self, x: u16) {
|
||||||
SmallBitmapInternal::Tiny(set) => set,
|
let (set, x) = self.get_set_index_mut(x);
|
||||||
SmallBitmapInternal::Small(set) => {
|
|
||||||
let idx = x / 64;
|
|
||||||
x %= 64;
|
|
||||||
&mut set[idx as usize]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*set &= !(0b1 << x);
|
*set &= !(0b1 << x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,13 +290,22 @@ impl SmallBitmapInternal {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(a, *b),
|
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(a, *b),
|
||||||
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
||||||
assert!(a.len() == b.len(),);
|
assert!(
|
||||||
|
a.len() == b.len(),
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
a.len() * 64,
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
for (a, b) in a.iter_mut().zip(b.iter()) {
|
for (a, b) in a.iter_mut().zip(b.iter()) {
|
||||||
op(a, *b);
|
op(a, *b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
(this, other) => {
|
||||||
panic!();
|
panic!(
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
this.universe_length(),
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,7 +313,12 @@ impl SmallBitmapInternal {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(*a, *b),
|
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(*a, *b),
|
||||||
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
||||||
assert!(a.len() == b.len());
|
assert!(
|
||||||
|
a.len() == b.len(),
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
a.len() * 64,
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
for (a, b) in a.iter().zip(b.iter()) {
|
for (a, b) in a.iter().zip(b.iter()) {
|
||||||
if !op(*a, *b) {
|
if !op(*a, *b) {
|
||||||
return false;
|
return false;
|
||||||
@ -282,7 +327,11 @@ impl SmallBitmapInternal {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!();
|
panic!(
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
self.universe_length(),
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +339,12 @@ impl SmallBitmapInternal {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(*a, *b),
|
(SmallBitmapInternal::Tiny(a), SmallBitmapInternal::Tiny(b)) => op(*a, *b),
|
||||||
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
(SmallBitmapInternal::Small(a), SmallBitmapInternal::Small(b)) => {
|
||||||
assert!(a.len() == b.len());
|
assert!(
|
||||||
|
a.len() == b.len(),
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
a.len() * 64,
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
for (a, b) in a.iter().zip(b.iter()) {
|
for (a, b) in a.iter().zip(b.iter()) {
|
||||||
if op(*a, *b) {
|
if op(*a, *b) {
|
||||||
return true;
|
return true;
|
||||||
@ -299,7 +353,11 @@ impl SmallBitmapInternal {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!();
|
panic!(
|
||||||
|
"universe length mismatch: left is {}, but right is {}",
|
||||||
|
self.universe_length(),
|
||||||
|
other.universe_length()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user