@@ -27,6 +27,7 @@ use std::hash::{Hash, Hasher};
27
27
use std:: convert:: TryInto ;
28
28
use datasize:: DataSize ;
29
29
use itertools:: Itertools ;
30
+ use once_cell:: sync:: OnceCell ;
30
31
31
32
pub type ObjNr = u64 ;
32
33
pub type GenNr = u64 ;
@@ -430,15 +431,24 @@ impl<T> PartialEq for MaybeRef<T> {
430
431
}
431
432
impl < T > Eq for MaybeRef < T > { }
432
433
433
- #[ derive( Debug , DataSize ) ]
434
+ #[ derive( Debug ) ]
434
435
pub struct Lazy < T > {
435
436
primitive : Primitive ,
437
+ cache : OnceCell < MaybeRef < T > > ,
436
438
_marker : PhantomData < T >
437
439
}
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
+ }
438
447
impl < T > Clone for Lazy < T > {
439
448
fn clone ( & self ) -> Self {
440
449
Lazy {
441
450
primitive : self . primitive . clone ( ) ,
451
+ cache : self . cache . clone ( ) ,
442
452
_marker : PhantomData
443
453
}
444
454
}
@@ -447,21 +457,28 @@ impl<T: Object> DeepClone for Lazy<T> {
447
457
fn deep_clone ( & self , cloner : & mut impl Cloner ) -> Result < Self > {
448
458
Ok ( Lazy {
449
459
primitive : self . primitive . deep_clone ( cloner) ?,
460
+ cache : OnceCell :: new ( ) ,
450
461
_marker : PhantomData
451
462
} )
452
463
}
453
464
}
454
465
impl < T : Object + DataSize > Lazy < T > {
455
466
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 ( )
460
473
}
461
474
}
462
475
impl < T : Object > Object for Lazy < T > {
463
476
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
+ } )
465
482
}
466
483
}
467
484
impl < T : ObjectWrite > ObjectWrite for Lazy < T > {
@@ -471,13 +488,18 @@ impl<T: ObjectWrite> ObjectWrite for Lazy<T> {
471
488
}
472
489
impl < T > Default for Lazy < T > {
473
490
fn default ( ) -> Self {
474
- Lazy { primitive : Primitive :: Null , _marker : PhantomData }
491
+ Lazy {
492
+ primitive : Primitive :: Null ,
493
+ cache : OnceCell :: new ( ) ,
494
+ _marker : PhantomData
495
+ }
475
496
}
476
497
}
477
498
impl < T : Object > From < RcRef < T > > for Lazy < T > {
478
499
fn from ( value : RcRef < T > ) -> Self {
479
500
Lazy {
480
501
primitive : Primitive :: Reference ( value. inner ) ,
502
+ cache : OnceCell :: with_value ( MaybeRef :: Direct ( value. data ) ) ,
481
503
_marker : PhantomData
482
504
}
483
505
}
0 commit comments