Skip to content

Commit

Permalink
done packedintarray
Browse files Browse the repository at this point in the history
  • Loading branch information
JieningYu committed Feb 19, 2024
1 parent fe07e73 commit fbb7a3c
Show file tree
Hide file tree
Showing 7 changed files with 521 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/core/world/palette/src/container.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! Paletted containers.
1 change: 1 addition & 0 deletions crates/core/world/palette/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::{collections::HashMap, hash::Hash};

pub mod container;
mod iter;

pub use iter::Iter;
Expand Down
17 changes: 17 additions & 0 deletions crates/util/packed-int-array/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "rimecraft-packed-int-array"
version = "0.1.0"
edition = "2021"
authors = ["JieningYu <[email protected]>"]
description = "PackedIntegerArray in Rust"
repository = "https://github.com/rimecraft-rs/rimecraft/"
license = "AGPL-3.0-or-later"
categories = ["data-structures"]

[badges]
maintenance = { status = "passively-maintained" }

[dependencies]

[lints]
workspace = true
194 changes: 194 additions & 0 deletions crates/util/packed-int-array/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
pub const INDEX_PARAMS: [i32; 192] = [
-1,
-1,
0,
i32::MIN,
0,
0,
1431655765,
1431655765,
0,
i32::MIN,
0,
1,
858993459,
858993459,
0,
715827882,
715827882,
0,
613566756,
613566756,
0,
i32::MIN,
0,
2,
477218588,
477218588,
0,
429496729,
429496729,
0,
390451572,
390451572,
0,
357913941,
357913941,
0,
330382099,
330382099,
0,
306783378,
306783378,
0,
286331153,
286331153,
0,
i32::MIN,
0,
3,
252645135,
252645135,
0,
238609294,
238609294,
0,
226050910,
226050910,
0,
214748364,
214748364,
0,
204522252,
204522252,
0,
195225786,
195225786,
0,
186737708,
186737708,
0,
178956970,
178956970,
0,
171798691,
171798691,
0,
165191049,
165191049,
0,
159072862,
159072862,
0,
153391689,
153391689,
0,
148102320,
148102320,
0,
143165576,
143165576,
0,
138547332,
138547332,
0,
i32::MIN,
0,
4,
130150524,
130150524,
0,
126322567,
126322567,
0,
122713351,
122713351,
0,
119304647,
119304647,
0,
116080197,
116080197,
0,
113025455,
113025455,
0,
110127366,
110127366,
0,
107374182,
107374182,
0,
104755299,
104755299,
0,
102261126,
102261126,
0,
99882960,
99882960,
0,
97612893,
97612893,
0,
95443717,
95443717,
0,
93368854,
93368854,
0,
91382282,
91382282,
0,
89478485,
89478485,
0,
87652393,
87652393,
0,
85899345,
85899345,
0,
84215045,
84215045,
0,
82595524,
82595524,
0,
81037118,
81037118,
0,
79536431,
79536431,
0,
78090314,
78090314,
0,
76695844,
76695844,
0,
75350303,
75350303,
0,
74051160,
74051160,
0,
72796055,
72796055,
0,
71582788,
71582788,
0,
70409299,
70409299,
0,
69273666,
69273666,
0,
68174084,
68174084,
0,
i32::MIN,
0,
5,
];
69 changes: 69 additions & 0 deletions crates/util/packed-int-array/src/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::PackedIntArray;

#[derive(Debug)]
pub(crate) struct IterInner {
pub l: u64,
pub j: usize,
pub times: usize,
}

/// An iterator over a packed int array.
#[derive(Debug)]
pub struct Iter<'a> {
pub(crate) array: &'a PackedIntArray,
pub(crate) iter: std::slice::Iter<'a, u64>,
pub(crate) inner: IterInner,
}

impl Iterator for Iter<'_> {
type Item = u32;

fn next(&mut self) -> Option<Self::Item> {
if self.inner.times >= self.array.len() {
return None;
}

if self.inner.j < self.array.elements_per_long {
self.inner.j += 1;
let res = self.inner.l & self.array.max;
self.inner.l >>= self.array.element_bits;
self.inner.times += 1;
Some(res as u32)
} else {
self.inner.l = *self.iter.next()?;
self.next()
}
}
}

/// An iterator over a packed int array.
#[derive(Debug)]
pub struct IntoIter {
pub(crate) element_bits: usize,
pub(crate) elements_per_long: usize,
pub(crate) max: u64,
pub(crate) iter: std::vec::IntoIter<u64>,
pub(crate) inner: IterInner,
pub(crate) len: usize,
}

impl Iterator for IntoIter {
type Item = u32;

fn next(&mut self) -> Option<Self::Item> {
if self.inner.times >= self.len {
return None;
}

if self.inner.j < self.elements_per_long {
self.inner.j += 1;
let res = self.inner.l & self.max;
self.inner.l >>= self.element_bits;
self.inner.times += 1;
Some(res as u32)
} else {
self.inner.l = self.iter.next()?;
self.next()
}
}
}
Loading

0 comments on commit fbb7a3c

Please sign in to comment.