mς TγΈEc@s½dZdkZdklZdklZlZlZdkl Z dk l Z l Z l Z lZde fd„ƒYZde fd „ƒYZd efd „ƒYZd e fd „ƒYZdS(sοFileStorage helper to perform pack. A storage contains an ordered set of object revisions. When a storage is packed, object revisions that are not reachable as of the pack time are deleted. The notion of reachability is complicated by backpointers -- object revisions that point to earlier revisions of the same object. An object revisions is reachable at a certain time if it is reachable from the revision of the root at that time or if it is reachable from a backpointer after that time. N(s referencesf(sp64su64sz64(sfsIndex(sFileStorageFormattersCorruptedDataErrors DataHeaders TRANS_HDR_LENt DataCopiercBs;tZdZd„Zd„Zd„Zd„Zd„ZRS(sαMixin class for copying transactions into a storage. The restore() and pack() methods share a need to copy data records and update pointers to data in earlier transaction records. This class provides the shared logic. The mixin extends the FileStorageFormatter with a copy() method. It also requires that the concrete class provides the following attributes: _file -- file with earlier destination data _tfile -- destination file for copied data _pos -- file pos of destination transaction _tindex -- maps oid to data record file pos _tvindex -- maps version name to data record file pos _tindex and _tvindex are updated by copy(). The copy() method does not do any locking. cCsΗ|i}x¨|djoš|ii|dƒ|t|iidƒƒd}|ii|ƒ|iitƒ}|d }||jo|Sn|o|ddjoPq―q q Wt ddƒ‚dS(NiiitpsInvalid transaction id(tselft_postpost_filetseektu64treadt TRANS_HDR_LENtht_tidttidt stop_at_packt UndoErrortNone(RR R R RR ((t6/data/zmath/zope/lib/python/ZODB/FileStorage/fspack.pyt _txn_find;s     cCsθ|i|ƒ}||i}|iiƒ}xΆ||jo¨|i |ƒ}|i |jou|i djo|Sn|i t |ƒjotd|ƒdSn|ii|i ƒ}||jodSn|Sn||iƒ7}q.WdS(Nis+Mismatch between data and backpointer at %d(Rt_read_txn_headerttposR ttlenttendRttellRt_read_data_headertoidtplentlentdataterrorRt_datat recordlen(RRRRR RRR((Rt _data_findKs$    cCs†|pdSnd}|i||ƒ}|io |iSnG|o?|i||ƒ}|io |iSq‚t d||ƒdSndS(Ns<restore could not find previous non-version data at %d or %d( tprevRtpnvRRRR tversiontbpth2twarn(RRR R"R#R$R R!((Rt _restore_pnvos     cCsMd}|dj o6|i|dƒ}|o|i|||ƒ}qIn|S(Ni( tprev_postprev_txnRRRt prev_txn_posRRR(RR(RRR)R'((Rt_resolve_backpointerŠs  cCs˜|i|||ƒ} |ii|dƒ}|} | |i |<| o d}n|djo d} n t|ƒ} t||||t|ƒ| ƒ} |o“|| _|i|||| ƒ} | dj o | | _n || _|ii|dƒ| _| ip|ii|dƒ| _n| |i|R?RNRPRTRQRRRSRo(((RRAΌs  8  3t PackCopiercBs,tZd„Zd„Zd„Zd„ZRS(NcCsC||_||_||_||_||_ ||_ d|_ dS(N(tfRRR8tindexR+tvindexR7ttindexR0ttvindexR5RR(RRvRwRxRyRz((RRNˆs      cCs ||_dS(N(RRR(RR((Rt setTxnPos‘scCsA|iiƒ}zti||||ƒSWd|ii |ƒXdS(N( RR8RRRR*R(RRR(RR(RRR((RR*”s cCsD|iiƒ}zti|||||ƒSWd|ii |ƒXdS(N( RR8RRRR&RR R"R#R(RRR R"R#R((RR&›s (R>R?RNR{R*R&(((RRu}s  tFileStoragePackercBsPtZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z RS( NcCsΣ||_t|dƒ|_||_||_d|_||_ t |i|i |iƒ|_ ||_||_||_||_tƒ|_h|_h|_h|_h|_h|_h|_tƒ|_dS(Ntrbi(tpathRRDtopenRt_pathtstopt_stoptlockedt current_sizetfile_endRAtgctlat _lock_acquiretlrt _lock_releasetclat_commit_lock_acquiretclrt_commit_lock_releaseRHRwRxRyRztoid2tidttoid2tidttoid2tid_deletetnvindex(RR~RR‡R‰R‹RR„((RRN«s&               cCsΒ|iiƒt|iddƒ|_|iidƒ|ii|ii |i ƒƒt |i|i |i |i|iƒ|_|iƒ\}}||iijpt‚||jo6|iiƒ|iiƒti|idƒdSn|iƒd|_|iƒzN|iiƒt|iddƒ|_|iiddƒ|iiƒ|_Wd|i ƒX||ijo|i!|ƒn|iiƒ}|ii#ƒ|iiƒ|iiƒ|S(Ns.packsw+biiR}i($RR†RTRRDR8RRR9Rt_metadata_sizeRuRwRxRyRzt_copiertcopyToPacktimetipostoposRGtAssertionErrortclosetostremoveRRŒRƒRˆR€RR…RŠtcopyRestRtflush(RRR–R—((RtpackΤs<            cCs'd}|i}|}x||iijoρ|i|ƒ}|i ||ƒ\}}|oy|i i ƒd}||d}|i i|dƒ|i it|ƒƒ|i i|dƒ|i it|ƒƒn|i|ƒ}||i jo|i|d||i ƒn|d7}qW||fS(NlisPredundant transaction length does not match initial transaction length: %d != %d(toffsetRR“Rtnew_posR†RGRRXtcopyDataRecordstnew_tposR8RRRR9R;R`Ra(RR RRRXRŸR’((RR•s(  cCs4|djodSn|i||dƒ\}}|S(sΦReturn data and refs backpointer `back` to object `oid. If `back` is 0 or ultimately resolves to 0, return None and None. In this case, the transaction undoes the object creation. iN(RqRRt _loadBackTxnRRR (RRRqR R((RtfetchBackpointer2s  c CsId}d}||i}||iƒ7}x||jo|i|ƒ}|i i |i |ƒp||i ƒ7}q,n||i ƒ7}|pNd|_|iƒ}|iiƒ}|ii|ƒ|t|ƒ}d}n|io|ii|iƒ} n|i|i |iƒ} |i|| |ƒ|iiƒ}q,W||fS(sοCopy any current data records between pos and tend. Returns position of txn header in output file and position of next record in the input file. If any data records are copied, also write txn header (th). ilRiN(R=R’RRXRRR]RRR R†RPRRRZR:tsR8RR9RR RRRRR€RqtwritePackedDataRecord( RRRXR’R R RR₯R=R((RR‘>s2      cCs|djo d}nd|_d|_t|ƒ|_||_|i i ƒ}|i oJ|ii|idƒ|_|ii|i dƒ|_||i|i R?RNRžR•R€R‘R¦RœR©(((RR|’s ) B  +  (R@RštZODB.serializeRtt ZODB.utilsR;RR<t ZODB.fsIndexRHtZODB.FileStorage.formattFileStorageFormatterRbR2R RRARuR|(R²R R;RRbRR|RHR2RtRARuRšR<((Rt?s   —Α%