difftreelog
perf O(1) std.reverse, std.range
in: master
3 files changed
crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth11};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}143144144#[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) => x151 .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}172173173#[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}183186184#[jrsonnet_macros::builtin]187#[jrsonnet_macros::builtin]432}435}433436434#[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}445444446#[jrsonnet_macros::builtin]445#[jrsonnet_macros::builtin]crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth285}285}286286287/// Specialization, provides faster TryFrom<VecVal> for Val287/// Specialization, provides faster TryFrom<VecVal> for Val288pub struct VecVal(pub Vec<Val>);288pub struct VecVal(pub Cc<Vec<Val>>);289289290impl 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;306306307 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}311311crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth178 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 }186192187 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 }195203218 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 }223244236 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 }241277263 }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 r313 }266 })314 })267 }315 }268316269 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 }277331278 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 }286343287 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 }307347308 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> {