Skip to content

Commit 0771b28

Browse files
committed
implement eager size checking
1 parent 4948d2a commit 0771b28

File tree

4 files changed

+91
-41
lines changed

4 files changed

+91
-41
lines changed

src/hir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod size;
1010

1111
pub use buckets::Buckets;
1212
pub use build::build;
13+
pub use size::{Size, SizeOf};
1314

1415
pub struct Hir {
1516
pub table: Table,

src/hir/size.rs

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@ use std::ops::{Add, Mul};
22

33
use crate::hir;
44

5-
#[derive(Default, Clone, Copy)]
5+
#[derive(Clone, Copy, PartialEq)]
66
pub struct Size {
77
pub min: u32,
88
pub max: Option<u32>,
99
}
1010

11+
impl Default for Size {
12+
fn default() -> Self {
13+
Self {
14+
min: 0,
15+
max: Some(0),
16+
}
17+
}
18+
}
19+
1120
impl Add<u32> for Size {
1221
type Output = Self;
1322

@@ -61,6 +70,17 @@ impl Mul<hir::Length> for Size {
6170
}
6271
}
6372

73+
impl PartialOrd for Size {
74+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
75+
match (self.max, other.max) {
76+
(Some(a), Some(b)) => Some(self.min.cmp(&other.min).then(a.cmp(&b))),
77+
(Some(_), None) => Some(std::cmp::Ordering::Less),
78+
(None, Some(_)) => Some(std::cmp::Ordering::Greater),
79+
(None, None) => Some(std::cmp::Ordering::Equal),
80+
}
81+
}
82+
}
83+
6484
impl From<u32> for Size {
6585
fn from(value: u32) -> Self {
6686
Self {
@@ -80,85 +100,99 @@ impl Size {
80100
}
81101
}
82102

83-
impl hir::Type {
84-
pub fn size(&self) -> Size {
103+
pub trait SizeOf {
104+
fn size_of(&self) -> Size;
105+
}
106+
107+
impl<T: SizeOf> SizeOf for Vec<T> {
108+
fn size_of(&self) -> Size {
109+
self.iter()
110+
.map(|item| item.size_of())
111+
.fold(Size::default(), |acc, size| acc + size)
112+
}
113+
}
114+
115+
impl SizeOf for hir::Type {
116+
fn size_of(&self) -> Size {
85117
match self {
86-
hir::Type::Boolean(ty) => ty.size(),
87-
hir::Type::Number(ty) => ty.size(),
88-
hir::Type::Vector(ty) => ty.size(),
89-
hir::Type::BinaryString(ty) => ty.size(),
90-
hir::Type::Utf8String(ty) => ty.size(),
91-
hir::Type::Array(ty) => ty.size(),
92-
hir::Type::Set(ty) => ty.size(),
93-
hir::Type::Map(ty) => ty.size(),
94-
hir::Type::Enum(ty) => ty.size(),
95-
hir::Type::Struct(ty) => ty.size(),
118+
hir::Type::Boolean(ty) => ty.size_of(),
119+
hir::Type::Number(ty) => ty.size_of(),
120+
hir::Type::Vector(ty) => ty.size_of(),
121+
hir::Type::BinaryString(ty) => ty.size_of(),
122+
hir::Type::Utf8String(ty) => ty.size_of(),
123+
hir::Type::Array(ty) => ty.size_of(),
124+
hir::Type::Set(ty) => ty.size_of(),
125+
hir::Type::Map(ty) => ty.size_of(),
126+
hir::Type::Enum(ty) => ty.size_of(),
127+
hir::Type::Struct(ty) => ty.size_of(),
96128
}
97129
}
98130
}
99131

100-
impl hir::BooleanType {
101-
pub fn size(&self) -> Size {
132+
impl SizeOf for hir::BooleanType {
133+
fn size_of(&self) -> Size {
102134
Size::from(1)
103135
}
104136
}
105137

106-
impl hir::NumberType {
107-
pub fn size(&self) -> Size {
138+
impl SizeOf for hir::NumberType {
139+
fn size_of(&self) -> Size {
108140
Size {
109141
min: self.kind.size(),
110142
max: Some(self.kind.size()),
111143
}
112144
}
113145
}
114146

115-
impl hir::VectorType {
116-
pub fn size(&self) -> Size {
117-
self.x.size() + self.y.size() + self.z.as_ref().map_or(Size::default(), |z| z.size())
147+
impl SizeOf for hir::VectorType {
148+
fn size_of(&self) -> Size {
149+
self.x.size_of()
150+
+ self.y.size_of()
151+
+ self.z.as_ref().map_or(Size::default(), |z| z.size_of())
118152
}
119153
}
120154

121-
impl hir::BinaryStringType {
122-
pub fn size(&self) -> Size {
155+
impl SizeOf for hir::BinaryStringType {
156+
fn size_of(&self) -> Size {
123157
Size::from(1) * self.len + self.len.kind().size()
124158
}
125159
}
126160

127-
impl hir::Utf8StringType {
128-
pub fn size(&self) -> Size {
161+
impl SizeOf for hir::Utf8StringType {
162+
fn size_of(&self) -> Size {
129163
Size::from(1) * self.len + self.len.kind().size()
130164
}
131165
}
132166

133-
impl hir::ArrayType {
134-
pub fn size(&self) -> Size {
135-
self.item.size() * self.len + self.len.kind().size()
167+
impl SizeOf for hir::ArrayType {
168+
fn size_of(&self) -> Size {
169+
self.item.size_of() * self.len + self.len.kind().size()
136170
}
137171
}
138172

139-
impl hir::SetType {
140-
pub fn size(&self) -> Size {
141-
self.item.size() * self.len + self.len.kind().size()
173+
impl SizeOf for hir::SetType {
174+
fn size_of(&self) -> Size {
175+
self.item.size_of() * self.len + self.len.kind().size()
142176
}
143177
}
144178

145-
impl hir::MapType {
146-
pub fn size(&self) -> Size {
147-
self.index.size() + self.value.size() * self.len + self.len.kind().size()
179+
impl SizeOf for hir::MapType {
180+
fn size_of(&self) -> Size {
181+
self.index.size_of() + self.value.size_of() * self.len + self.len.kind().size()
148182
}
149183
}
150184

151-
impl hir::EnumType {
152-
pub fn size(&self) -> Size {
153-
self.number.size()
185+
impl SizeOf for hir::EnumType {
186+
fn size_of(&self) -> Size {
187+
self.number.size_of()
154188
}
155189
}
156190

157-
impl hir::StructType {
158-
pub fn size(&self) -> Size {
191+
impl SizeOf for hir::StructType {
192+
fn size_of(&self) -> Size {
159193
self.fields
160194
.iter()
161-
.map(|(_, field_type)| field_type.size())
195+
.map(|(_, field_type)| field_type.size_of())
162196
.fold(Size::default(), |acc, size| acc + size)
163197
}
164198
}

src/mir/server/iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
hir::Event,
2+
hir::{Event, Size},
33
mir::{
44
Expr,
55
builder::{Builder, Ctx},

src/mir/server/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
hir::{Buckets, Hir, Item, Table},
2+
hir::{Buckets, Hir, Item, Size, SizeOf, Table},
33
mir::{
44
Expr,
55
builder::{Builder, Ctx, TVar},
@@ -129,13 +129,24 @@ fn remote(b: &mut Builder, serverctx: &ServerCtx, remote: &Remote, items: &[(Str
129129
item_idx: 0,
130130
};
131131

132+
let mut max_recv_size = Size::default();
133+
132134
for (path, item) in recv {
133135
recvctx.item_idx += 1;
134136

135137
match item {
136138
Item::Table(_) => unreachable!(),
137139
Item::Event(event) => iter::iter(b, &recvctx, path, event),
138140
}
141+
142+
let size = match item {
143+
Item::Table(_) => unreachable!(),
144+
Item::Event(event) => event.data.size_of(),
145+
};
146+
147+
if size > max_recv_size {
148+
max_recv_size = size;
149+
}
139150
}
140151

141152
let mut sendctx = SendCtx {
@@ -161,6 +172,10 @@ fn remote(b: &mut Builder, serverctx: &ServerCtx, remote: &Remote, items: &[(Str
161172
len: b.init(Expr::Global("buffer.len").call(vec![buf.expr()])),
162173
};
163174

175+
if let Some(max) = max_recv_size.max {
176+
b.assert(ctx.len.expr().le(max), "packet too large");
177+
}
178+
164179
let idx = b.read_k(&ctx, recv_item_kind.into());
165180
b.call(recvctx.jump_tbl.expr().index(&idx).call(vec![
166181
plr.expr(),

0 commit comments

Comments
 (0)