@@ -237,7 +237,13 @@ def delta_list_apply(dcl, bbuf, write, lbound_offset=0, size=0):
237237
238238
239239class DeltaChunkList (list ):
240- """List with special functionality to deal with DeltaChunks"""
240+ """List with special functionality to deal with DeltaChunks.
241+ There are two types of lists we represent. The one was created bottom-up, working
242+ towards the latest delta, the other kind was created top-down, working from the
243+ latest delta down to the earliest ancestor. This attribute is queryable
244+ after all processing with is_reversed."""
245+
246+ __slots__ = tuple ()
241247
242248 def rbound (self ):
243249 """:return: rightmost extend in bytes, absolute"""
@@ -255,24 +261,18 @@ def size(self):
255261 """:return: size of bytes as measured by our delta chunks"""
256262 return self .rbound () - self .lbound ()
257263
258- def connect_with (self , bdcl , tdcl ):
264+ def connect_with (self , bdcl ):
259265 """Connect this instance's delta chunks virtually with the given base.
260266 This means that all copy deltas will simply apply to the given region
261267 of the given base. Afterwards, the base is optimized so that add-deltas
262268 will be truncated to the region actually used, or removed completely where
263269 adequate. This way, memory usage is reduced.
264- :param bdcl: DeltaChunkList to serve as base
265- :param tdcl: topmost delta chunk list. If set, reverse order is assumed
266- and the list is connected more efficiently"""
267- if tdcl is None :
268- for dc in self :
269- if not dc .has_data ():
270- dc .set_copy_chunklist (bdcl [dc .so :dc .ts ])
271- # END handle overlap
272- # END for each dc
273- else :
274- raise NotImplementedError ("todo" )
275- # END handle order
270+ :param bdcl: DeltaChunkList to serve as base"""
271+ for dc in self :
272+ if not dc .has_data ():
273+ dc .set_copy_chunklist (bdcl [dc .so :dc .ts ])
274+ # END handle overlap
275+ # END for each dc
276276
277277 def apply (self , bbuf , write , lbound_offset = 0 , size = 0 ):
278278 """Only used by public clients, internally we only use the global routines
@@ -396,8 +396,37 @@ def __getslice__(self, absofs, size):
396396
397397 # ndcl.check_integrity()
398398 return ndcl
399-
400-
399+
400+
401+ class TopdownDeltaChunkList (DeltaChunkList ):
402+ """Represents a list which is generated by feeding its ancestor streams one by
403+ one"""
404+ __slots__ = ('frozen' , ) # if True, the list is frozen and can reproduce all data
405+ # Will only be set in lists which where processed top-down
406+
407+ def __init__ (self ):
408+ self .frozen = False
409+
410+ def connect_with_next_base (self , bdcl ):
411+ """Connect this chain with the next level of our base delta chunklist.
412+ The goal in this game is to mark as many of our chunks rigid, hence they
413+ cannot be changed by any of the upcoming bases anymore. Once all our
414+ chunks are marked like that, we can stop all processing
415+ :param bdcl: data chunk list being one of our bases. They must be fed in
416+ consequtively and in order, towards the earliest ancestor delta
417+ :return: True if processing was done. Use it to abort processing of
418+ remaining streams"""
419+ if self .frozen == 1 :
420+ # Can that ever be hit ?
421+ return False
422+ # END early abort
423+ # mark us so that the is_reversed method returns True, without us thinking
424+ # we are frozen
425+ self .frozen = - 1
426+
427+ raise NotImplementedError ("todo" )
428+ return True
429+
401430
402431#} END structures
403432
@@ -540,8 +569,14 @@ def connect_deltas(dstreams, reverse):
540569 If True, deltas are ordered so that the one to be applied last comes first.
541570 :return: DeltaChunkList, containing all operations to apply"""
542571 bdcl = None # data chunk list for initial base
543- dcl = DeltaChunkList ()
544572 tdcl = None # topmost dcl, only effective if reverse is True
573+
574+ if reverse :
575+ dcl = tdcl = TopdownDeltaChunkList ()
576+ else :
577+ dcl = DeltaChunkList ()
578+ # END handle type of first chunk list
579+
545580 for dsi , ds in enumerate (dstreams ):
546581 # print "Stream", dsi
547582 db = ds .read ()
@@ -603,13 +638,14 @@ def connect_deltas(dstreams, reverse):
603638
604639 dcl .compress ()
605640
606- if reverse and tdcl is None :
607- tdcl = dcl
608- # END handle reverse
609-
610641 # merge the lists !
611642 if bdcl is not None :
612- dcl .connect_with (bdcl , tdcl )
643+ if tdcl :
644+ if not tdcl .connect_with_next_base (dcl ):
645+ break
646+ # END early abort
647+ else :
648+ dcl .connect_with (bdcl )
613649 # END handle merge
614650
615651 # dcl.check_integrity()
@@ -619,7 +655,10 @@ def connect_deltas(dstreams, reverse):
619655 dcl = DeltaChunkList ()
620656 # END for each delta stream
621657
622- return bdcl
658+ if tdcl :
659+ return tdcl
660+ else :
661+ return bdcl
623662
624663
625664def apply_delta_data (src_buf , src_buf_size , delta_buf , delta_buf_size , write ):
0 commit comments