Skip to content

Commit 2eda401

Browse files
committed
make Lazy remember the value
1 parent 0378c6d commit 2eda401

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

pdf/src/object/mod.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use std::hash::{Hash, Hasher};
2727
use std::convert::TryInto;
2828
use datasize::DataSize;
2929
use itertools::Itertools;
30+
use once_cell::sync::OnceCell;
3031

3132
pub type ObjNr = u64;
3233
pub type GenNr = u64;
@@ -430,15 +431,24 @@ impl<T> PartialEq for MaybeRef<T> {
430431
}
431432
impl<T> Eq for MaybeRef<T> {}
432433

433-
#[derive(Debug, DataSize)]
434+
#[derive(Debug)]
434435
pub struct Lazy<T> {
435436
primitive: Primitive,
437+
cache: OnceCell<MaybeRef<T>>,
436438
_marker: PhantomData<T>
437439
}
440+
impl<T: DataSize> DataSize for Lazy<T> {
441+
const IS_DYNAMIC: bool = true;
442+
const STATIC_HEAP_SIZE: usize = size_of::<Self>();
443+
fn estimate_heap_size(&self) -> usize {
444+
self.cache.get().map(|value| value.estimate_heap_size()).unwrap_or(0) + size_of::<Self>()
445+
}
446+
}
438447
impl<T> Clone for Lazy<T> {
439448
fn clone(&self) -> Self {
440449
Lazy {
441450
primitive: self.primitive.clone(),
451+
cache: self.cache.clone(),
442452
_marker: PhantomData
443453
}
444454
}
@@ -447,21 +457,28 @@ impl<T: Object> DeepClone for Lazy<T> {
447457
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
448458
Ok(Lazy {
449459
primitive: self.primitive.deep_clone(cloner)?,
460+
cache: OnceCell::new(),
450461
_marker: PhantomData
451462
})
452463
}
453464
}
454465
impl<T: Object + DataSize> Lazy<T> {
455466
pub fn load(&self, resolve: &impl Resolve) -> Result<MaybeRef<T>> {
456-
match self.primitive {
457-
Primitive::Reference(r) => resolve.get(Ref::new(r)).map(MaybeRef::Indirect),
458-
ref p => T::from_primitive(p.clone(), resolve).map(|o| MaybeRef::Direct(Arc::new(o))),
459-
}
467+
self.cache.get_or_try_init(|| {
468+
match self.primitive {
469+
Primitive::Reference(r) => resolve.get(Ref::new(r)).map(MaybeRef::Indirect),
470+
ref p => T::from_primitive(p.clone(), resolve).map(|o| MaybeRef::Direct(Arc::new(o))),
471+
}
472+
}).cloned()
460473
}
461474
}
462475
impl<T: Object> Object for Lazy<T> {
463476
fn from_primitive(p: Primitive, _: &impl Resolve) -> Result<Self> {
464-
Ok(Self { primitive: p, _marker: PhantomData })
477+
Ok(Self {
478+
primitive: p,
479+
cache: OnceCell::new(),
480+
_marker: PhantomData
481+
})
465482
}
466483
}
467484
impl<T: ObjectWrite> ObjectWrite for Lazy<T> {
@@ -471,13 +488,18 @@ impl<T: ObjectWrite> ObjectWrite for Lazy<T> {
471488
}
472489
impl<T> Default for Lazy<T> {
473490
fn default() -> Self {
474-
Lazy { primitive: Primitive::Null, _marker: PhantomData }
491+
Lazy {
492+
primitive: Primitive::Null,
493+
cache: OnceCell::new(),
494+
_marker: PhantomData
495+
}
475496
}
476497
}
477498
impl<T: Object> From<RcRef<T>> for Lazy<T> {
478499
fn from(value: RcRef<T>) -> Self {
479500
Lazy {
480501
primitive: Primitive::Reference(value.inner),
502+
cache: OnceCell::with_value(MaybeRef::Direct(value.data)),
481503
_marker: PhantomData
482504
}
483505
}

0 commit comments

Comments
 (0)