³ò
OÉcIc           @   sç   d  Z  d d k l Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k	 Z	 d d k
 Z
 d „  Z d „  Z d e i f d „  ƒ  YZ d „  Z d	 d d
 „  ƒ  YZ d d d „  ƒ  YZ d d d „  ƒ  YZ d S(   s¬  Operations on Iterators of Read Only Remote Paths

The main structure will be an iterator that yields RORPaths.
Every RORPath has a "raw" form that makes it more amenable to
being turned into a file.  The raw form of the iterator yields
each RORPath in the form of the tuple (index, data_dictionary,
files), where files is the number of files attached (usually 1 or
0).  After that, if a file is attached, it yields that file.

iÿÿÿÿ(   t
   generatorsNc             sƒ   t  ˆ ƒ ‰ ˆ d j o t ˆ d ˆ d ƒ Sn d g ˆ } | } ‡ ‡ f d †  ‰  d „  ‰ ‡  ‡ f d †  } | ˆ | | ƒ S(   sÜ   Collate RORPath iterators by index

	So it takes two or more iterators of rorps and returns an
	iterator yielding tuples like (rorp1, rorp2) with the same
	index.  If one or the other lacks that index, it will be None

	i   i    i   c            s~   xw t  ˆ  ƒ D]i } |  | oW | | d j oF y ˆ | i ƒ  | | <Wqv t j
 o d |  | <d | | <qv Xq q Wd S(   s   Set the overflow and rorps listi   N(   t   ranget   Nonet   nextt   StopIteration(   t   overflowt   rorpst   i(   t   iter_numt
   rorp_iters(    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   setrorps4   s      
c         S   s"   t  t d „  t d „  |  ƒ ƒ ƒ S(   s;   Return the first index in rorps, assuming rorps isn't emptyc         S   s   |  i  S(    (   t   index(   t   rorp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   <lambda>?   s    c         S   s   |  S(    (    (   t   x(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR   @   s    (   t   mint   mapt   filter(   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   getleastindex=   s    c         3   s«   x¤ ˆ  | | ƒ d  | j o Pn ˆ | ƒ } g  } x_ t |  ƒ D]Q } | | o3 | | i | j o | i | | ƒ d  | | <qA | i d  ƒ qA Wt | | ƒ Vq d  S(   N(   R   R   R   t   appendt   IndexedTuple(   R   R   R   R   t   yieldvalR   (   R
   R   (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   yield_tuplesB   s      N(   t   lent   Collate2ItersR   (   R	   R   R   R   (    (   R
   R   R   R	   s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   CollateIterators$   s    
		c         c   sK  d \ } } x8| pf y |  i ƒ  } WnF t j
 o: | o d | f Vn x | D] } d | f VqT WPn X| i } n | pf y | i ƒ  } WnF t j
 o: | o | d f Vn x |  D] } | d f VqÁ WPn X| i } n | | j  o | d f Vd } q | | j o | | f Vd \ } } q d | f Vd } q d S(   sÁ   Special case of CollateIterators with 2 arguments

	This does the same thing but is faster because it doesn't have
	to consider the >2 iterator case.  Profiler says speed is
	important here.

	N(   NN(   NN(   R   R   R   R   (   t   riter1t   riter2t   relem1t   relem2t   index1t   index2(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR   Q   s@          
R   c           B   sq   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z RS(   ss   Like a tuple, but has .index

	This is used by CollateIterator above, and can be passed to the
	IterTreeReducer.

	c         C   s   | |  _  t | ƒ |  _ d  S(   N(   R   t   tuplet   data(   t   selfR   t   sequence(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __init__~   s    	c         C   s   t  |  i ƒ S(   N(   R   R!   (   R"   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __len__‚   s    c         C   s   |  i  | S(   s4   This only works for numerical keys (easier this way)(   R!   (   R"   t   key(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __getitem__„   s    c         C   s   |  i  | ƒ d j S(   Niÿÿÿÿ(   t   __cmp__(   R"   t   other(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __lt__ˆ   s    c         C   s   |  i  | ƒ d j S(   Ni   (   R(   (   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __le__‰   s    c         C   s   |  i  | ƒ S(   N(   t   __eq__(   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __ne__Š   s    c         C   s   |  i  | ƒ d j S(   Ni   (   R(   (   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __gt__‹   s    c         C   s   |  i  | ƒ d j S(   Niÿÿÿÿ(   R(   (   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __ge__Œ   s    c         C   sU   t  | t ƒ p t ‚ |  i | i j  o d Sn  |  i | i j o d Sn d Sd  S(   Niÿÿÿÿi    i   (   t
   isinstanceR   t   AssertionErrorR   (   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR(   Ž   s      c         C   sf   t  | t ƒ o' |  i | i j o |  i | i j Sn, t | ƒ t i j o |  i | j Sn d  Sd  S(   N(   R0   R   R   R!   t   typet   typest	   TupleTypeR   (   R"   R)   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR,   ”   s
    'c         C   s&   d d i  t t |  i ƒ ƒ |  i f S(   Ns   (%s).%ss   , (   t   joinR   t   strR!   R   (   R"   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __str__›   s    (   t   __name__t
   __module__t   __doc__R$   R%   R'   R*   R+   R-   R.   R/   R(   R,   R7   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR   w   s   										c         c   s&  |  i  ƒ  } | i } x, t t | ƒ ƒ D] } | i | |  ƒ Vq( W| V~ | } xÍ |  D]Å } | i } | d  | d  j p– x“ t d t | ƒ ƒ D]x } | |  | |  j o] | i | |  ƒ } | i ƒ  p4 t i d | i | i	 ƒ  f d ƒ | i
 | ƒ n | Vq“ q“ Wn | V| } qY Wd S(   s=  Given ordered rpiter and rootrp, fill in missing indicies with rpaths

	For instance, suppose rpiter contains rpaths with indicies (),
	(1,2), (2,5).  Then return iter with rpaths (), (1,), (1,2), (2,),
	(2,5).  This is used when we need to process directories before or
	after processing a file in that directory.

	iÿÿÿÿi   s|   Warning: expected %s to be a directory but found %s instead.
This is probably caused by a bug in versions 1.0.0 and earlier.i   N(   R   R   R   R   t	   new_indext   isdirt   logt   Logt   patht   lstatt   make_zero_dir(   t   rpitert   rootrpt   first_rpt	   cur_indexR   t	   old_indext   rpt	   filler_rp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt
   FillInIterŸ   s.    
	   	 	t   IterTreeReducerc           B   s;   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   sž  Tree style reducer object for iterator

	The indicies of a RORPIter form a tree type structure.  This class
	can be used on each element of an iter in sequence and the result
	will be as if the corresponding tree was reduced.  This tries to
	bridge the gap between the tree nature of directories, and the
	iterator nature of the connection between hosts and the temporal
	order in which the files are processed.

	c         C   sF   | |  _  | |  _ d |  _ | | Œ  |  _ |  i g |  _ d |  _ d S(   s   ITR initializerN(   t   branch_classt   branch_argsR   R   t   root_brancht   branchest   root_fast_processed(   R"   RK   RL   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR$   Í   s    			c         C   sv   |  i  } xf | d } | i } | | t | ƒ  j o5 | i ƒ  | d =| p d Sn | d i | ƒ q d Sq d S(   sø   Run Finish() on all branches index has passed

		When we pass out of a branch, delete it and process it with
		the parent.  The innermost branches will be the last in the
		list.  Return None if we are out of the entire tree, and 1
		otherwise.

		iÿÿÿÿi   N(   RN   t
   base_indexR   t   end_processR   t   branch_process(   R"   R   RN   t   to_be_finishedRP   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   finish_branchesÖ   s    		
	
 c         C   s/   |  i  |  i Œ  } | | _ |  i i | ƒ | S(   s;   Return branch of type self.branch_class, add to branch list(   RK   RL   RP   RN   R   (   R"   R   t   branch(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt
   add_branchë   s    	c         C   sh   |  i  d j p
 |  i o d Sn x? |  i i ƒ  } | i ƒ  |  i p Pn |  i d i | ƒ q% d S(   s,   Call at end of sequence to tie everything upNiÿÿÿÿ(   R   R   RO   RN   t   popRQ   RR   (   R"   RS   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   Finishò   s     

 c         G   sI  | d } |  i  d j o] | |  i _ |  i i | Œ  o |  i i | Œ  d |  _ n |  i i | Œ  | |  _  d Sn | |  i  j o t i	 d | f d ƒ n› | |  i  j  o" d p t
 d |  i  | f ‚ ni |  i | ƒ d j o d Sn |  i d } | i | Œ  o | i | Œ  n |  i | ƒ } | i | Œ  | |  _  d S(   s@  Process args, where args[0] is current position in iterator

		Returns true if args successfully processed, false if index is
		not in the current tree and thus the final result is
		available.

		Also note below we set self.index after doing the necessary
		start processing, in case there is a crash in the middle.

		i    i   s+   Warning, repeated index %s, bad filesystem?i   s   Bad index order: %s >= %siÿÿÿÿN(   R   R   RM   RP   t   can_fast_processt   fast_processRO   t   start_processR=   R>   R1   RT   RN   RV   (   R"   t   argsR   t   last_branchRU   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __call__û   s.    
		"	(   R8   R9   R:   R$   RT   RV   RX   R^   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyRJ   Â   s   
						t	   ITRBranchc           B   sE   e  Z d  Z d Z Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 RS(   s÷   Helper class for IterTreeReducer above

	There are five stub functions below: start_process, end_process,
	branch_process, can_fast_process, and fast_process.  A class that
	subclasses this one will probably fill in these functions to do
	more.

	c         G   s   d S(   s!   Do some initial processing (stub)N(    (   R"   R\   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR[   ,  s    c         C   s   d S(   s4   Do any final processing before leaving branch (stub)N(    (   R"   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyRQ   0  s    c         C   s   d S(   s2   Process a branch right after it is finished (stub)N(    (   R"   RU   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyRR   4  s    c         G   s   d S(   s9   True if object can be processed without new branch (stub)N(   R   (   R"   R\   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyRY   8  s    c         G   s   d S(   s,   Process args without new child branch (stub)N(    (   R"   R\   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyRZ   <  s    N(   R8   R9   R:   R   RP   R   R[   RQ   RR   RY   RZ   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR_   "  s   
				t   CacheIndexablec           B   s5   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z RS(   sn  Cache last few indexed elements in iterator

	This class should be initialized with an iterator yielding
	.index'd objects.  It looks like it is just the same iterator as
	the one that initialized it.  Luckily, it does more, caching the
	last few elements iterated, which can be retrieved using the
	.get() method.

	If the index is not in the cache, return None.

	c         C   s(   | |  _  | |  _ h  |  _ g  |  _ d S(   s8   Make new CacheIndexable.  Cache_size is max cache lengthN(   t
   cache_sizet   itert
   cache_dictt   cache_indicies(   R"   t   indexed_iterRa   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR$   M  s    			c         C   s©   |  i  i ƒ  } | i } | |  i | <|  i i | ƒ t |  i ƒ |  i j oW y |  i |  i d =Wn1 t j
 o% t	 i
 d |  i d f d ƒ n X|  i d =n | S(   s=   Return next elem, add to cache.  StopIteration passed upwardsi    s-   Warning: index %s missing from iterator cachei   (   Rb   R   R   Rc   Rd   R   R   Ra   t   KeyErrorR=   R>   (   R"   t	   next_elemt
   next_index(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR   T  s    		c         C   s   |  S(   N(    (   R"   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   __iter__e  s    c         C   sb   y |  i  | SWnL t j
 o@ | |  i d j p! t d t | |  i d f ƒ ‚ d Sn Xd S(   s*   Return element with index index from cachei    s   Index out of order: N(   Rc   Rf   Rd   R1   t   reprR   (   R"   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyt   getg  s     N(   R8   R9   R:   R   R$   R   Ri   Rk   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pyR`   A  s
   		(    (    (    (   R:   t
   __future__R    t   ost   tempfilet   UserListR3   t   Globalst   rpatht   iterfileR=   R   R   R   RI   RJ   R_   R`   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/rorpiter.pys   <module>   s   00	-	&(	#`