git.delta.rocks / jrsonnet / refs/commits / 69d179bf913a

difftreelog

perf O(1) std.reverse, std.range

Yaroslav Bolyukin2022-04-20parent: #629c80c.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
11};11};
12use crate::{Either, ObjValue};12use crate::{Either, ObjValue};
13use format::{format_arr, format_obj};13use format::{format_arr, format_obj};
14use gcmodule::Cc;
14use jrsonnet_interner::IStr;15use jrsonnet_interner::IStr;
15use serde::Deserialize;16use serde::Deserialize;
16use serde_yaml::DeserializingQuirks;17use serde_yaml::DeserializingQuirks;
142}143}
143144
144#[jrsonnet_macros::builtin]145#[jrsonnet_macros::builtin]
145fn builtin_length(x: Either![IStr, VecVal, ObjValue, FuncVal]) -> Result<usize> {146fn builtin_length(x: Either![IStr, ArrValue, ObjValue, FuncVal]) -> Result<usize> {
146 use Either4::*;147 use Either4::*;
147 Ok(match x {148 Ok(match x {
148 A(x) => x.chars().count(),149 A(x) => x.chars().count(),
149 B(x) => x.0.len(),150 B(x) => x.len(),
150 C(x) => x151 C(x) => x
151 .fields_visibility()152 .fields_visibility()
152 .into_iter()153 .into_iter()
167 for i in 0..sz {168 for i in 0..sz {
168 out.push(func.evaluate_simple(&[i as f64].as_slice())?)169 out.push(func.evaluate_simple(&[i as f64].as_slice())?)
169 }170 }
170 Ok(VecVal(out))171 Ok(VecVal(Cc::new(out)))
171}172}
172173
173#[jrsonnet_macros::builtin]174#[jrsonnet_macros::builtin]
178#[jrsonnet_macros::builtin]179#[jrsonnet_macros::builtin]
179fn builtin_object_fields_ex(obj: ObjValue, inc_hidden: bool) -> Result<VecVal> {180fn builtin_object_fields_ex(obj: ObjValue, inc_hidden: bool) -> Result<VecVal> {
180 let out = obj.fields_ex(inc_hidden);181 let out = obj.fields_ex(inc_hidden);
181 Ok(VecVal(out.into_iter().map(Val::Str).collect::<Vec<_>>()))182 Ok(VecVal(Cc::new(
183 out.into_iter().map(Val::Str).collect::<Vec<_>>(),
184 )))
182}185}
183186
184#[jrsonnet_macros::builtin]187#[jrsonnet_macros::builtin]
432}435}
433436
434#[jrsonnet_macros::builtin]437#[jrsonnet_macros::builtin]
435fn builtin_range(from: i32, to: i32) -> Result<VecVal> {438fn builtin_range(from: i32, to: i32) -> Result<ArrValue> {
436 if to < from {439 if to < from {
437 return Ok(VecVal(Vec::new()));440 return Ok(ArrValue::new_eager());
438 }441 }
439 let mut out = Vec::with_capacity((1 + to as usize - from as usize).max(0));442 Ok(ArrValue::new_range(from, to))
440 for i in from as usize..=to as usize {
441 out.push(Val::Num(i as f64));
442 }
443 Ok(VecVal(out))
444}443}
445444
446#[jrsonnet_macros::builtin]445#[jrsonnet_macros::builtin]
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
285}285}
286286
287/// Specialization, provides faster TryFrom<VecVal> for Val287/// Specialization, provides faster TryFrom<VecVal> for Val
288pub struct VecVal(pub Vec<Val>);288pub struct VecVal(pub Cc<Vec<Val>>);
289289
290impl Typed for VecVal {290impl Typed for VecVal {
291 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);291 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);
296 fn try_from(value: Val) -> Result<Self> {296 fn try_from(value: Val) -> Result<Self> {
297 <Self as Typed>::TYPE.check(&value)?;297 <Self as Typed>::TYPE.check(&value)?;
298 match value {298 match value {
299 Val::Arr(a) => Ok(Self(a.evaluated()?.to_vec())),299 Val::Arr(a) => Ok(Self(a.evaluated()?)),
300 _ => unreachable!(),300 _ => unreachable!(),
301 }301 }
302 }302 }
305 type Error = LocError;305 type Error = LocError;
306306
307 fn try_from(value: VecVal) -> Result<Self> {307 fn try_from(value: VecVal) -> Result<Self> {
308 Ok(Self::Arr(value.0.into()))308 Ok(Self::Arr(ArrValue::Eager(value.0)))
309 }309 }
310}310}
311311
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
178 Lazy(Cc<Vec<LazyVal>>),178 Lazy(Cc<Vec<LazyVal>>),
179 Eager(Cc<Vec<Val>>),179 Eager(Cc<Vec<Val>>),
180 Extended(Box<(Self, Self)>),180 Extended(Box<(Self, Self)>),
181 Range(i32, i32),
182 Reversed(Box<Self>),
181}183}
182impl ArrValue {184impl ArrValue {
183 pub fn new_eager() -> Self {185 pub fn new_eager() -> Self {
184 Self::Eager(Cc::new(Vec::new()))186 Self::Eager(Cc::new(Vec::new()))
185 }187 }
188 pub fn new_range(a: i32, b: i32) -> Self {
189 assert!(a <= b);
190 Self::Range(a, b)
191 }
186192
187 pub fn len(&self) -> usize {193 pub fn len(&self) -> usize {
188 match self {194 match self {
189 Self::Bytes(i) => i.len(),195 Self::Bytes(i) => i.len(),
190 Self::Lazy(l) => l.len(),196 Self::Lazy(l) => l.len(),
191 Self::Eager(e) => e.len(),197 Self::Eager(e) => e.len(),
192 Self::Extended(v) => v.0.len() + v.1.len(),198 Self::Extended(v) => v.0.len() + v.1.len(),
199 Self::Range(a, b) => a.abs_diff(*b) as usize,
200 Self::Reversed(i) => i.len(),
193 }201 }
194 }202 }
195203
218 v.1.get(index - a_len)226 v.1.get(index - a_len)
219 }227 }
220 }228 }
229 Self::Range(a, _) => {
230 if index >= self.len() {
231 return Ok(None);
232 }
233 Ok(Some(Val::Num(((*a as isize) + index as isize) as f64)))
234 }
235 Self::Reversed(v) => {
236 let len = v.len();
237 if index >= len {
238 return Ok(None);
239 }
240 v.get(len - index - 1)
241 }
221 }242 }
222 }243 }
223244
236 v.1.get_lazy(index - a_len)257 v.1.get_lazy(index - a_len)
237 }258 }
238 }259 }
260 Self::Range(a, _) => {
261 if index >= self.len() {
262 return None;
263 }
264 Some(LazyVal::new_resolved(Val::Num(
265 ((*a as isize) + index as isize) as f64,
266 )))
267 }
268 Self::Reversed(v) => {
269 let len = v.len();
270 if index >= len {
271 return None;
272 }
273 v.get_lazy(len - index - 1)
274 }
239 }275 }
240 }276 }
241277
263 }299 }
264 Cc::new(out)300 Cc::new(out)
265 }301 }
302 Self::Range(a, b) => {
303 let mut out = Vec::with_capacity(self.len());
304 for i in *a..*b {
305 out.push(Val::Num(i as f64));
306 }
307 Cc::new(out)
308 }
309 Self::Reversed(r) => {
310 let mut r = r.evaluated()?;
311 Cc::update_with(&mut r, |v| v.reverse());
312 r
313 }
266 })314 })
267 }315 }
268316
269 pub fn iter(&self) -> impl DoubleEndedIterator<Item = Result<Val>> + '_ {317 pub fn iter(&self) -> impl DoubleEndedIterator<Item = Result<Val>> + '_ {
318 // if let Self::Reversed(v) = self {
319 // return v.iter().rev();
320 // }
270 (0..self.len()).map(move |idx| match self {321 let len = self.len();
322 (0..len).map(move |idx| match self {
271 Self::Bytes(b) => Ok(Val::Num(b[idx] as f64)),323 Self::Bytes(b) => Ok(Val::Num(b[idx] as f64)),
272 Self::Lazy(l) => l[idx].evaluate(),324 Self::Lazy(l) => l[idx].evaluate(),
273 Self::Eager(e) => Ok(e[idx].clone()),325 Self::Eager(e) => Ok(e[idx].clone()),
274 Self::Extended(_) => self.get(idx).map(|e| e.unwrap()),326 Self::Extended(_) => self.get(idx).map(|e| e.unwrap()),
327 Self::Range(..) => self.get(idx).map(|e| e.unwrap()),
328 Self::Reversed(..) => self.get(len - idx - 1).map(|e| e.unwrap()),
275 })329 })
276 }330 }
277331
278 pub fn iter_lazy(&self) -> impl DoubleEndedIterator<Item = LazyVal> + '_ {332 pub fn iter_lazy(&self) -> impl DoubleEndedIterator<Item = LazyVal> + '_ {
279 (0..self.len()).map(move |idx| match self {333 let len = self.len();
334 (0..len).map(move |idx| match self {
280 Self::Bytes(b) => LazyVal::new_resolved(Val::Num(b[idx] as f64)),335 Self::Bytes(b) => LazyVal::new_resolved(Val::Num(b[idx] as f64)),
281 Self::Lazy(l) => l[idx].clone(),336 Self::Lazy(l) => l[idx].clone(),
282 Self::Eager(e) => LazyVal::new_resolved(e[idx].clone()),337 Self::Eager(e) => LazyVal::new_resolved(e[idx].clone()),
283 Self::Extended(_) => self.get_lazy(idx).unwrap(),338 Self::Extended(_) => self.get_lazy(idx).unwrap(),
339 Self::Range(..) => self.get_lazy(idx).unwrap(),
340 Self::Reversed(..) => self.get_lazy(len - idx - 1).unwrap(),
284 })341 })
285 }342 }
286343
287 pub fn reversed(self) -> Self {344 pub fn reversed(self) -> Self {
288 match self {
289 Self::Bytes(b) => {345 Self::Reversed(Box::new(self))
290 let mut out = b.to_vec();
291 out.reverse();
292 Self::Bytes(out.into())
293 }
294 Self::Lazy(vec) => {
295 let mut out = (&vec as &Vec<_>).clone();
296 out.reverse();
297 Self::Lazy(Cc::new(out))
298 }
299 Self::Eager(vec) => {
300 let mut out = (&vec as &Vec<_>).clone();
301 out.reverse();
302 Self::Eager(Cc::new(out))
303 }
304 Self::Extended(b) => Self::Extended(Box::new((b.1.reversed(), b.0.reversed()))),
305 }
306 }346 }
307347
308 pub fn map(self, mapper: impl Fn(Val) -> Result<Val>) -> Result<Self> {348 pub fn map(self, mapper: impl Fn(Val) -> Result<Val>) -> Result<Self> {