-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
168 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,95 @@ | ||
use crate::{ | ||
get_packed_orientation, get_packed_piece_or_permutation, set_packed_orientation, | ||
set_packed_piece_or_permutation, set_packed_piece_or_permutation_and_orientation, | ||
}; | ||
use std::alloc::{alloc, dealloc}; | ||
|
||
use super::{PackedKPuzzle, PackedKTransformation}; | ||
use super::{packed_kpuzzle::PackedKPuzzleOrbitInfo, PackedKPuzzle, PackedKTransformation}; | ||
|
||
pub struct PackedKState { | ||
// pub packed_kpuzzle: PackedKPuzzle, | ||
pub bytes: [u8; 52], | ||
pub packed_kpuzzle: PackedKPuzzle, | ||
// pub bytes: [u8; 52], | ||
pub bytes: *mut u8, | ||
} | ||
|
||
impl Drop for PackedKState { | ||
fn drop(&mut self) { | ||
unsafe { dealloc(self.bytes, self.packed_kpuzzle.data.layout) } | ||
} | ||
} | ||
|
||
impl PackedKState { | ||
pub fn new(packed_kpuzzle: PackedKPuzzle) -> Self { | ||
let bytes = unsafe { alloc(packed_kpuzzle.data.layout) }; | ||
Self { | ||
packed_kpuzzle, | ||
bytes, | ||
} | ||
} | ||
|
||
pub fn get_piece_or_permutation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize) -> u8 { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.pieces_or_pemutations_offset + i) | ||
.read() | ||
} | ||
} | ||
|
||
pub fn get_orientation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize) -> u8 { | ||
unsafe { self.bytes.add(orbit_info.orientations_offset + i).read() } | ||
} | ||
|
||
pub fn set_piece_or_permutation( | ||
&self, | ||
orbit_info: &PackedKPuzzleOrbitInfo, | ||
i: usize, | ||
value: u8, | ||
) { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.pieces_or_pemutations_offset + i) | ||
.write(value) | ||
} | ||
} | ||
|
||
pub fn set_orientation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize, value: u8) { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.orientations_offset + i) | ||
.write(value) | ||
} | ||
} | ||
|
||
// Adapted from https://github.com/cubing/cubing.rs/blob/b737c6a36528e9984b45b29f9449a9a330c272fb/src/kpuzzle/state.rs#L31-L82 | ||
// TODO: dedup the implementation (but avoid runtime overhead for the shared abstraction). | ||
pub fn apply_transformation( | ||
&self, | ||
packed_kpuzzle: &PackedKPuzzle, | ||
transformation: &PackedKTransformation, | ||
) -> PackedKState { | ||
let mut bytes: [u8; 52] = [0; 52]; | ||
let new_state = PackedKState::new(self.packed_kpuzzle.clone()); | ||
for orbit_info in &packed_kpuzzle.data.orbit_iteration_info { | ||
// TODO: optimization when either value is the identity. | ||
for i in 0..orbit_info.num_pieces { | ||
let transformation_idx = std::convert::Into::<usize>::into( | ||
get_packed_piece_or_permutation!(transformation.bytes, orbit_info, i), | ||
let transformation_idx = transformation.get_piece_or_permutation(orbit_info, i); | ||
|
||
let new_piece_permutation = self.get_piece_or_permutation( | ||
orbit_info, | ||
std::convert::Into::<usize>::into(transformation_idx), | ||
); | ||
self.set_piece_or_permutation(orbit_info, i, new_piece_permutation); | ||
|
||
let new_piece_permutation = | ||
get_packed_piece_or_permutation!(self.bytes, orbit_info, transformation_idx); | ||
let previous_piece_orientation = | ||
get_packed_orientation!(self.bytes, orbit_info, transformation_idx); | ||
let new_piece_orientation = orbit_info.table[std::convert::Into::<usize>::into( | ||
previous_piece_orientation | ||
+ get_packed_orientation!(transformation.bytes, orbit_info, i), | ||
)]; | ||
set_packed_piece_or_permutation_and_orientation!( | ||
bytes, | ||
let previous_piece_orientation = self.get_orientation( | ||
orbit_info, | ||
i, | ||
new_piece_permutation, | ||
new_piece_orientation | ||
std::convert::Into::<usize>::into(transformation_idx), | ||
); | ||
let new_piece_orientation = orbit_info.table[std::convert::Into::<usize>::into( | ||
previous_piece_orientation + transformation.get_orientation(orbit_info, i), | ||
)]; | ||
self.set_orientation(orbit_info, i, new_piece_orientation); | ||
} | ||
} | ||
|
||
PackedKState { bytes } | ||
new_state | ||
} | ||
|
||
pub fn hash(&self) -> u64 { | ||
cityhash::city_hash_64(&self.bytes) | ||
} | ||
// pub fn hash(&self) -> u64 { | ||
// cityhash::city_hash_64(&self.bytes) | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,59 @@ | ||
use std::alloc::{alloc, dealloc}; | ||
|
||
use super::{packed_kpuzzle::PackedKPuzzleOrbitInfo, PackedKPuzzle}; | ||
pub struct PackedKTransformation { | ||
pub bytes: Vec<u8>, | ||
pub packed_kpuzzle: PackedKPuzzle, | ||
pub bytes: *mut u8, | ||
} | ||
|
||
impl Drop for PackedKTransformation { | ||
fn drop(&mut self) { | ||
unsafe { dealloc(self.bytes, self.packed_kpuzzle.data.layout) } | ||
} | ||
} | ||
|
||
impl PackedKTransformation { | ||
pub fn new(packed_kpuzzle: PackedKPuzzle) -> Self { | ||
let bytes = unsafe { alloc(packed_kpuzzle.data.layout) }; | ||
Self { | ||
packed_kpuzzle, | ||
bytes, | ||
} | ||
} | ||
// TODO: dedup with PackedKTransformation, or at least implement as a trait? | ||
pub fn get_piece_or_permutation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize) -> u8 { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.pieces_or_pemutations_offset + i) | ||
.read() | ||
} | ||
} | ||
|
||
// TODO: dedup with PackedKTransformation, or at least implement as a trait? | ||
pub fn get_orientation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize) -> u8 { | ||
unsafe { self.bytes.add(orbit_info.orientations_offset + i).read() } | ||
} | ||
|
||
// TODO: dedup with PackedKTransformation, or at least implement as a trait? | ||
pub fn set_piece_or_permutation( | ||
&self, | ||
orbit_info: &PackedKPuzzleOrbitInfo, | ||
i: usize, | ||
value: u8, | ||
) { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.pieces_or_pemutations_offset + i) | ||
.write(value) | ||
} | ||
} | ||
|
||
// TODO: dedup with PackedKTransformation, or at least implement as a trait? | ||
pub fn set_orientation(&self, orbit_info: &PackedKPuzzleOrbitInfo, i: usize, value: u8) { | ||
unsafe { | ||
self.bytes | ||
.add(orbit_info.orientations_offset + i) | ||
.write(value) | ||
} | ||
} | ||
} |
Oops, something went wrong.