Skip to content

Commit a064007

Browse files
committed
Made heavliy called methods global, its brings a second, which is nearly 10 percent more performance just by eliminating two method calls
1 parent 682f483 commit a064007

File tree

1 file changed

+79
-75
lines changed

1 file changed

+79
-75
lines changed

fun.py

Lines changed: 79 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,26 @@ def _move_delta_lbound(d, bytes):
8484

8585
def delta_duplicate(src):
8686
return DeltaChunk(src.to, src.ts, src.so, src.data)
87+
88+
def delta_chunk_apply(dc, bbuf, write):
89+
"""Apply own data to the target buffer
90+
:param bbuf: buffer providing source bytes for copy operations
91+
:param write: write method to call with data to write"""
92+
if dc.data is None:
93+
# COPY DATA FROM SOURCE
94+
write(buffer(bbuf, dc.so, dc.ts))
95+
elif isinstance(dc.data, DeltaChunkList):
96+
delta_list_apply(dc.data, bbuf, write, dc.so, dc.ts)
97+
else:
98+
# APPEND DATA
99+
# whats faster: if + 4 function calls or just a write with a slice ?
100+
# Considering data can be larger than 127 bytes now, it should be worth it
101+
if dc.ts < len(dc.data):
102+
write(dc.data[:dc.ts])
103+
else:
104+
write(dc.data)
105+
# END handle truncation
106+
# END handle chunk mode
87107

88108
class DeltaChunk(object):
89109
"""Represents a piece of a delta, it can either add new data, or copy existing
@@ -136,25 +156,7 @@ def set_copy_chunklist(self, dcl):
136156
self.data = dcl
137157
self.so = 0 # allows lbound moves to be virtual
138158

139-
def apply(self, bbuf, write):
140-
"""Apply own data to the target buffer
141-
:param bbuf: buffer providing source bytes for copy operations
142-
:param write: write method to call with data to write"""
143-
if self.data is None:
144-
# COPY DATA FROM SOURCE
145-
write(buffer(bbuf, self.so, self.ts))
146-
elif isinstance(self.data, DeltaChunkList):
147-
self.data.apply(bbuf, write, self.so, self.ts)
148-
else:
149-
# APPEND DATA
150-
# whats faster: if + 4 function calls or just a write with a slice ?
151-
# Considering data can be larger than 127 bytes now, it should be worth it
152-
if self.ts < len(self.data):
153-
write(self.data[:self.ts])
154-
else:
155-
write(self.data)
156-
# END handle truncation
157-
# END handle chunk mode
159+
158160

159161
#} END interface
160162

@@ -178,6 +180,59 @@ def _closest_index(dcl, absofs):
178180
# END for each delta absofs
179181
return len(dcl)-1
180182

183+
def delta_list_apply(dcl, bbuf, write, lbound_offset=0, size=0):
184+
"""Apply the chain's changes and write the final result using the passed
185+
write function.
186+
:param bbuf: base buffer containing the base of all deltas contained in this
187+
list. It will only be used if the chunk in question does not have a base
188+
chain.
189+
:param lbound_offset: offset at which to start applying the delta, relative to
190+
our lbound
191+
:param size: if larger than 0, only the given amount of bytes will be applied
192+
:param write: function taking a string of bytes to write to the output"""
193+
slen = len(dcl)
194+
if slen == 0:
195+
return
196+
# END early abort
197+
absofs = dcl.lbound() + lbound_offset
198+
if size == 0:
199+
size = dcl.rbound() - absofs
200+
# END initialize size
201+
202+
if lbound_offset or absofs + size != dcl.rbound():
203+
cdi = _closest_index(dcl, absofs)
204+
cd = dcl[cdi]
205+
if cd.to != absofs:
206+
tcd = delta_duplicate(cd)
207+
_move_delta_lbound(tcd, absofs - cd.to)
208+
_set_delta_rbound(tcd, min(tcd.ts, size))
209+
delta_chunk_apply(tcd, bbuf, write)
210+
size -= tcd.ts
211+
cdi += 1
212+
# END handle first chunk
213+
214+
# here we have to either apply full chunks, or smaller ones, but
215+
# we always start at the chunks target offset
216+
while cdi < slen and size:
217+
cd = dcl[cdi]
218+
if cd.ts <= size:
219+
delta_chunk_apply(cd, bbuf, write)
220+
size -= cd.ts
221+
else:
222+
tcd = delta_duplicate(cd)
223+
_set_delta_rbound(tcd, size)
224+
delta_chunk_apply(tcd, bbuf, write)
225+
size -= tcd.ts
226+
break
227+
# END handle bytes to apply
228+
cdi += 1
229+
# END handle rest
230+
else:
231+
for dc in dcl:
232+
delta_chunk_apply(dc, bbuf, write)
233+
# END for each dc
234+
# END handle application values
235+
181236

182237
class DeltaChunkList(list):
183238
"""List with special functionality to deal with DeltaChunks"""
@@ -211,6 +266,11 @@ def connect_with(self, bdcl):
211266
# END handle overlap
212267
# END for each dc
213268

269+
def apply(self, bbuf, write, lbound_offset=0, size=0):
270+
"""Only used by public clients, internally we only use the global routines
271+
for performance"""
272+
return delta_list_apply(self, bbuf, write, lbound_offset, size)
273+
214274
def compress(self):
215275
"""Alter the list to reduce the amount of nodes. Currently we concatenate
216276
add-chunks
@@ -255,61 +315,6 @@ def compress(self):
255315
# print "INFO: Reduced delta list len to %f %% of former size" % ((float(len(self)) / slen_orig) * 100)
256316
return self
257317

258-
def apply(self, bbuf, write, lbound_offset=0, size=0):
259-
"""Apply the chain's changes and write the final result using the passed
260-
write function.
261-
:param bbuf: base buffer containing the base of all deltas contained in this
262-
list. It will only be used if the chunk in question does not have a base
263-
chain.
264-
:param lbound_offset: offset at which to start applying the delta, relative to
265-
our lbound
266-
:param size: if larger than 0, only the given amount of bytes will be applied
267-
:param write: function taking a string of bytes to write to the output"""
268-
slen = len(self)
269-
if slen == 0:
270-
return
271-
# END early abort
272-
absofs = self.lbound() + lbound_offset
273-
if size == 0:
274-
size = self.rbound() - absofs
275-
# END initialize size
276-
277-
dapply = DeltaChunk.apply
278-
if lbound_offset or absofs + size != self.rbound():
279-
cdi = _closest_index(self, absofs)
280-
cd = self[cdi]
281-
if cd.to != absofs:
282-
tcd = delta_duplicate(cd)
283-
_move_delta_lbound(tcd, absofs - cd.to)
284-
_set_delta_rbound(tcd, min(tcd.ts, size))
285-
dapply(tcd, bbuf, write)
286-
size -= tcd.ts
287-
cdi += 1
288-
# END handle first chunk
289-
290-
# here we have to either apply full chunks, or smaller ones, but
291-
# we always start at the chunks target offset
292-
while cdi < slen and size:
293-
cd = self[cdi]
294-
if cd.ts <= size:
295-
dapply(cd, bbuf, write)
296-
size -= cd.ts
297-
else:
298-
tcd = delta_duplicate(cd)
299-
_set_delta_rbound(tcd, size)
300-
dapply(tcd, bbuf, write)
301-
size -= tcd.ts
302-
break
303-
# END handle bytes to apply
304-
cdi += 1
305-
# END handle rest
306-
assert size == 0
307-
else:
308-
for dc in self:
309-
dapply(dc, bbuf, write)
310-
# END for each dc
311-
# END handle application values
312-
313318
def check_integrity(self, target_size=-1):
314319
"""Verify the list has non-overlapping chunks only, and the total size matches
315320
target_size
@@ -380,7 +385,6 @@ def __getslice__(self, absofs, size):
380385
# END hadle size
381386
cdi += 1
382387
# END for each chunk
383-
assert size == 0, "size was %i" % size
384388

385389
# ndcl.check_integrity()
386390
return ndcl

0 commit comments

Comments
 (0)