@@ -92,10 +92,10 @@ typedef unsigned char uchar;
92
92
typedef uchar bool ;
93
93
94
94
// Constants
95
- const ull gDVC_grow_by = 50 ;
95
+ const ull gDVC_grow_by = 100 ;
96
96
97
97
#ifdef DEBUG
98
- #define DBG_check (vec ) asser (DCV_dbg_check_integrity(vec))
98
+ #define DBG_check (vec ) assert (DCV_dbg_check_integrity(vec))
99
99
#else
100
100
#define DBG_check (vec )
101
101
#endif
@@ -233,13 +233,19 @@ typedef struct {
233
233
234
234
// Reserve enough memory to hold the given amount of delta chunks
235
235
// Return 1 on success
236
+ // NOTE: added a minimum allocation to assure reallocation is not done
237
+ // just for a single additional entry. DCVs change often, and reallocs are expensive
236
238
inline
237
239
int DCV_reserve_memory (DeltaChunkVector * vec , uint num_dc )
238
240
{
239
241
if (num_dc <= vec -> reserved_size ){
240
242
return 1 ;
241
243
}
242
244
245
+ if (num_dc - vec -> reserved_size ){
246
+ num_dc += gDVC_grow_by ;
247
+ }
248
+
243
249
#ifdef DEBUG
244
250
bool was_null = vec -> mem == NULL ;
245
251
#endif
@@ -381,25 +387,6 @@ void DCV_reset(DeltaChunkVector* vec)
381
387
vec -> size = 0 ;
382
388
}
383
389
384
- // Append num-chunks to the end of the list, possibly reallocating existing ones
385
- // Return a pointer to the first of the added items. They are already null initialized
386
- // If num-chunks == 0, it returns the end pointer of the allocated memory
387
- static inline
388
- DeltaChunk * DCV_append_multiple (DeltaChunkVector * vec , uint num_chunks )
389
- {
390
- if (vec -> size + num_chunks > vec -> reserved_size ){
391
- DCV_grow_by (vec , (vec -> size + num_chunks ) - vec -> reserved_size );
392
- }
393
- Py_FatalError ("Could not allocate memory for append operation" );
394
- Py_ssize_t old_size = vec -> size ;
395
- vec -> size += num_chunks ;
396
-
397
- for (;old_size < vec -> size ; ++ old_size ){
398
- DC_init (DCV_get (vec , old_size ), 0 , 0 , 0 );
399
- }
400
-
401
- return & vec -> mem [old_size ];
402
- }
403
390
404
391
// Append one chunk to the end of the list, and return a pointer to it
405
392
// It will not have been initialized !
@@ -838,6 +825,7 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
838
825
const unsigned long rbound = cp_off + cp_size ;
839
826
if (rbound < cp_size ||
840
827
rbound > base_size ){
828
+ assert (0 );
841
829
break ;
842
830
}
843
831
@@ -849,6 +837,8 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
849
837
// NOTE: Compression only necessary for all other deltas, not
850
838
// for the first one, as we will share the data. It really depends
851
839
// What's faster
840
+ // Compression reduces fragmentation though, which is why we do it
841
+ // in all cases.
852
842
DeltaChunk * dc = DCV_append (& dcv );
853
843
DC_init (dc , tbw , cmd , 0 );
854
844
DC_set_data (dc , data , cmd , is_shared_data );
@@ -860,7 +850,10 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
860
850
goto loop_end ;
861
851
}
862
852
}// END handle command opcodes
863
- assert (tbw == target_size );
853
+ if (tbw != target_size ){
854
+ PyErr_SetString (PyExc_RuntimeError , "Failed to parse delta stream" );
855
+ error = 1 ;
856
+ }
864
857
865
858
if (!is_first_run ){
866
859
DCV_connect_with_base (& tdcv , & dcv , & tmpl );
0 commit comments