@@ -75,18 +75,27 @@ use crate::{
75
75
TableIterator ,
76
76
} ;
77
77
78
+ pub const KB : u64 = 1 << 10 ;
79
+
80
+ pub fn round_up ( n : u64 , k : u64 ) -> u64 {
81
+ ( n + k - 1 ) / k * k
82
+ }
83
+
78
84
#[ derive( Debug , Clone , PartialEq , Eq ) ]
79
85
pub struct TableSummary {
80
86
inferred_type : CountedShape < ProdConfigWithOptionalFields > ,
81
87
total_size : i64 ,
88
+ // Used for metered billing, we charge for database storage rounded up to
89
+ // the nearest KB per document
90
+ total_size_rounded : Option < i64 > ,
82
91
}
83
92
84
93
impl fmt:: Display for TableSummary {
85
94
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
86
95
write ! (
87
96
f,
88
- "TableSummary {{ inferred_type: {}, total_size: {} }}" ,
89
- self . inferred_type, self . total_size
97
+ "TableSummary {{ inferred_type: {}, total_size: {} , total_size_rounded: {:?} }}" ,
98
+ self . inferred_type, self . total_size, self . total_size_rounded
90
99
)
91
100
}
92
101
}
@@ -96,6 +105,7 @@ impl TableSummary {
96
105
Self {
97
106
inferred_type : Shape :: empty ( ) ,
98
107
total_size : 0 ,
108
+ total_size_rounded : None ,
99
109
}
100
110
}
101
111
@@ -117,18 +127,36 @@ impl TableSummary {
117
127
118
128
pub fn insert ( & self , object : & ConvexObject ) -> Self {
119
129
let total_size = self . total_size + object. size ( ) as i64 ;
130
+ let total_size_rounded = match self . total_size_rounded {
131
+ Some ( total_size_rounded) => {
132
+ Some ( total_size_rounded + round_up ( object. size ( ) as u64 , KB ) as i64 )
133
+ } ,
134
+ None => None ,
135
+ } ;
120
136
Self {
121
137
inferred_type : self . inferred_type . insert ( object) ,
122
138
total_size,
139
+ total_size_rounded,
123
140
}
124
141
}
125
142
126
143
pub fn remove ( & self , object : & ConvexObject ) -> anyhow:: Result < Self > {
127
144
let size = object. size ( ) as i64 ;
128
- anyhow:: ensure!( self . total_size >= size, "Negative size due to {object}" ) ;
145
+ let total_size_rounded = match self . total_size_rounded {
146
+ Some ( total_size_rounded) => {
147
+ let size_rounded = round_up ( object. size ( ) as u64 , KB ) as i64 ;
148
+ anyhow:: ensure!(
149
+ total_size_rounded >= size_rounded,
150
+ "Negative size due to {object}"
151
+ ) ;
152
+ Some ( total_size_rounded - size_rounded)
153
+ } ,
154
+ None => None ,
155
+ } ;
129
156
Ok ( Self {
130
157
inferred_type : self . inferred_type . remove ( object) ?,
131
158
total_size : self . total_size - size,
159
+ total_size_rounded,
132
160
} )
133
161
}
134
162
@@ -143,10 +171,17 @@ impl TableSummary {
143
171
144
172
impl From < & TableSummary > for JsonValue {
145
173
fn from ( summary : & TableSummary ) -> Self {
146
- json ! ( {
147
- "totalSize" : JsonInteger :: encode( summary. total_size) ,
148
- "inferredTypeWithOptionalFields" : JsonValue :: from( & summary. inferred_type)
149
- } )
174
+ match summary. total_size_rounded {
175
+ Some ( total_size_rounded) => json ! ( {
176
+ "totalSize" : JsonInteger :: encode( summary. total_size) ,
177
+ "totalSizeRounded" : JsonInteger :: encode( total_size_rounded) ,
178
+ "inferredTypeWithOptionalFields" : JsonValue :: from( & summary. inferred_type)
179
+ } ) ,
180
+ None => json ! ( {
181
+ "totalSize" : JsonInteger :: encode( summary. total_size) ,
182
+ "inferredTypeWithOptionalFields" : JsonValue :: from( & summary. inferred_type)
183
+ } ) ,
184
+ }
150
185
}
151
186
}
152
187
@@ -161,13 +196,22 @@ impl TryFrom<JsonValue> for TableSummary {
161
196
_ => anyhow:: bail!( "Invalid totalSize" ) ,
162
197
} ;
163
198
anyhow:: ensure!( total_size >= 0 ) ;
199
+ let total_size_rounded = match v. remove ( "totalSizeRounded" ) {
200
+ Some ( JsonValue :: String ( s) ) => {
201
+ let total_size_rounded = JsonInteger :: decode ( s) ?;
202
+ anyhow:: ensure!( total_size_rounded >= 0 ) ;
203
+ Some ( total_size_rounded)
204
+ } ,
205
+ _ => None ,
206
+ } ;
164
207
let inferred_type = match v. remove ( "inferredTypeWithOptionalFields" ) {
165
208
Some ( v) => CountedShape :: < ProdConfigWithOptionalFields > :: try_from ( v) ?,
166
209
None => anyhow:: bail!( "Missing field inferredTypeWithOptionalFields" ) ,
167
210
} ;
168
211
Ok ( TableSummary {
169
212
inferred_type,
170
213
total_size,
214
+ total_size_rounded,
171
215
} )
172
216
} ,
173
217
_ => anyhow:: bail!( "Wrong type of json value for TableSummaryJson" ) ,
0 commit comments