@@ -2,6 +2,7 @@ use std::collections::VecDeque;
22
33use crate :: hashbrown;
44use crate :: internal:: alias;
5+ use crate :: internal:: pickle:: Builder ;
56use crate :: internal:: utils;
67use crate :: policies:: traits;
78use crate :: policies:: traits:: HandleExt ;
@@ -524,4 +525,83 @@ impl PolicyExt for TTLPolicy {
524525 front_offset : self . front_offset ,
525526 }
526527 }
528+
529+ fn build_pickle (
530+ & self ,
531+ tuple : & mut crate :: internal:: pickle:: TupleBuilder <
532+ ' _ ,
533+ crate :: internal:: pickle:: PickleBuilder ,
534+ > ,
535+ ) -> pyo3:: PyResult < ( ) > {
536+ let mut list = tuple. begin_list ( ) ?;
537+
538+ for handle in self . entries . iter ( ) {
539+ let mut tuple = list. begin_tuple ( 3 ) ?;
540+ tuple. push ( handle. key ( ) . as_ref ( ) ) ?;
541+ tuple. push ( handle. value ( ) ) ?;
542+ tuple. push (
543+ handle
544+ . expires_at
545+ . duration_since ( std:: time:: UNIX_EPOCH )
546+ . unwrap ( ) ,
547+ ) ?;
548+ tuple. end ( ) ?;
549+ }
550+
551+ list. end ( )
552+ }
553+
554+ fn from_pickle (
555+ maxsize : usize ,
556+ getsizeof : Option < crate :: internal:: alias:: PyObject > ,
557+ global_ttl : Option < std:: time:: Duration > ,
558+ builded : pyo3:: Bound < ' _ , pyo3:: types:: PyTuple > ,
559+ ) -> pyo3:: PyResult < ( Self :: Shared , Self ) > {
560+ use pyo3:: types:: PyAnyMethods ;
561+ use pyo3:: types:: PyListMethods ;
562+ use pyo3:: types:: PyTupleMethods ;
563+
564+ if global_ttl. is_none_or ( |x| x. is_zero ( ) ) {
565+ return Err ( new_py_error ! ( PyValueError , "global_ttl is zero" ) ) ;
566+ }
567+
568+ let list = builded. get_item ( 0 ) ?. cast_into :: < pyo3:: types:: PyList > ( ) ?;
569+ let list_length = list. len ( ) ;
570+
571+ if list_length > maxsize {
572+ return Err ( new_py_error ! (
573+ PyValueError ,
574+ "list size is incompatible with maxsize"
575+ ) ) ;
576+ }
577+
578+ let shared = Shared :: with_ttl ( maxsize, getsizeof, global_ttl) ;
579+ let mut slf = Self :: new ( list. len ( ) ) ;
580+
581+ for bound in list. iter ( ) {
582+ let ( key, value, timestamp) =
583+ bound. extract :: < ( alias:: PyObject , alias:: PyObject , f64 ) > ( ) ?;
584+
585+ let handle = ExpiringHandle :: new (
586+ bound. py ( ) ,
587+ shared. getsizeof ( ) ,
588+ ( std:: time:: UNIX_EPOCH + std:: time:: Duration :: from_secs_f64 ( timestamp) ) . into ( ) ,
589+ key,
590+ value,
591+ ) ?;
592+
593+ slf. currsize = slf. currsize . saturating_add ( handle. size ( ) ) ;
594+
595+ unsafe {
596+ slf. table . insert_no_grow (
597+ handle. key ( ) . hash ( ) ,
598+ // Adding `slf.front_offset` is unnecessary here
599+ slf. entries . len ( ) ,
600+ ) ;
601+ }
602+ slf. entries . push_back ( handle) ;
603+ }
604+
605+ Ok ( ( shared, slf) )
606+ }
527607}
0 commit comments