groom packet.rs, add blob.data alignment (#3763)
This commit is contained in:
parent
e57a0ab05d
commit
542bafeb71
|
@ -15,6 +15,7 @@ use std::io::Cursor;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
pub type SharedPackets = Arc<RwLock<Packets>>;
|
pub type SharedPackets = Arc<RwLock<Packets>>;
|
||||||
|
@ -24,6 +25,7 @@ pub type SharedBlobs = Vec<SharedBlob>;
|
||||||
pub const NUM_PACKETS: usize = 1024 * 8;
|
pub const NUM_PACKETS: usize = 1024 * 8;
|
||||||
pub const BLOB_SIZE: usize = (64 * 1024 - 128); // wikipedia says there should be 20b for ipv4 headers
|
pub const BLOB_SIZE: usize = (64 * 1024 - 128); // wikipedia says there should be 20b for ipv4 headers
|
||||||
pub const BLOB_DATA_SIZE: usize = BLOB_SIZE - (BLOB_HEADER_SIZE * 2);
|
pub const BLOB_DATA_SIZE: usize = BLOB_SIZE - (BLOB_HEADER_SIZE * 2);
|
||||||
|
pub const BLOB_DATA_ALIGN: usize = 64;
|
||||||
pub const NUM_BLOBS: usize = (NUM_PACKETS * PACKET_DATA_SIZE) / BLOB_SIZE;
|
pub const NUM_BLOBS: usize = (NUM_PACKETS * PACKET_DATA_SIZE) / BLOB_SIZE;
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -71,7 +73,7 @@ impl Default for Packet {
|
||||||
|
|
||||||
impl PartialEq for Packet {
|
impl PartialEq for Packet {
|
||||||
fn eq(&self, other: &Packet) -> bool {
|
fn eq(&self, other: &Packet) -> bool {
|
||||||
self.data.iter().zip(other.data.iter()).all(|(a, b)| a == b) && self.meta == other.meta
|
self.meta == other.meta && self.data.as_ref() == other.data.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,18 +143,51 @@ impl Packets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[repr(align(64))] // 64 === BLOB_DATA_ALIGN
|
||||||
pub struct Blob {
|
pub struct BlobData {
|
||||||
pub data: [u8; BLOB_SIZE],
|
pub data: [u8; BLOB_SIZE],
|
||||||
pub meta: Meta,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Blob {
|
impl Clone for BlobData {
|
||||||
fn eq(&self, other: &Blob) -> bool {
|
fn clone(&self) -> Self {
|
||||||
self.data.iter().zip(other.data.iter()).all(|(a, b)| a == b) && self.meta == other.meta
|
BlobData { data: self.data }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for BlobData {
|
||||||
|
fn default() -> Self {
|
||||||
|
BlobData {
|
||||||
|
data: [0u8; BLOB_SIZE],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for BlobData {
|
||||||
|
fn eq(&self, other: &BlobData) -> bool {
|
||||||
|
self.data.as_ref() == other.data.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this code hides _data, maps it to _data.data
|
||||||
|
impl Deref for Blob {
|
||||||
|
type Target = BlobData;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self._data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl DerefMut for Blob {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self._data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, PartialEq)]
|
||||||
|
pub struct Blob {
|
||||||
|
_data: BlobData, // hidden member, passed through by Deref
|
||||||
|
pub meta: Meta,
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Blob {
|
impl fmt::Debug for Blob {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
@ -164,16 +199,6 @@ impl fmt::Debug for Blob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//auto derive doesn't support large arrays
|
|
||||||
impl Default for Blob {
|
|
||||||
fn default() -> Blob {
|
|
||||||
Blob {
|
|
||||||
data: [0u8; BLOB_SIZE],
|
|
||||||
meta: Meta::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlobError {
|
pub enum BlobError {
|
||||||
/// the Blob's meta and data are not self-consistent
|
/// the Blob's meta and data are not self-consistent
|
||||||
|
@ -343,11 +368,11 @@ const SIZE_RANGE: std::ops::Range<usize> = range!(FLAGS_RANGE.end, u64);
|
||||||
|
|
||||||
macro_rules! align {
|
macro_rules! align {
|
||||||
($x:expr, $align:expr) => {
|
($x:expr, $align:expr) => {
|
||||||
$x + ($align * 8 - 1) & !($align * 8 - 1)
|
$x + ($align - 1) & !($align - 1)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const BLOB_HEADER_SIZE: usize = align!(SIZE_RANGE.end, 8);
|
pub const BLOB_HEADER_SIZE: usize = align!(SIZE_RANGE.end, BLOB_DATA_ALIGN);
|
||||||
|
|
||||||
pub const BLOB_FLAG_IS_LAST_IN_SLOT: u32 = 0x2;
|
pub const BLOB_FLAG_IS_LAST_IN_SLOT: u32 = 0x2;
|
||||||
|
|
||||||
|
@ -785,4 +810,29 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(result, packets);
|
assert_eq!(result, packets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_blob_data_align() {
|
||||||
|
assert_eq!(std::mem::align_of::<BlobData>(), BLOB_DATA_ALIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_packet_partial_eq() {
|
||||||
|
let p1 = Packet::default();
|
||||||
|
let mut p2 = Packet::default();
|
||||||
|
|
||||||
|
assert!(p1 == p2);
|
||||||
|
p2.data[1] = 4;
|
||||||
|
assert!(p1 != p2);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_blob_partial_eq() {
|
||||||
|
let p1 = Blob::default();
|
||||||
|
let mut p2 = Blob::default();
|
||||||
|
|
||||||
|
assert!(p1 == p2);
|
||||||
|
p2.data[1] = 4;
|
||||||
|
assert!(p1 != p2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue