@@ -92,10 +92,10 @@ typedef unsigned char uchar;
9292typedef uchar bool ;
9393
9494// Constants
95- const ull gDVC_grow_by = 50 ;
95+ const ull gDVC_grow_by = 100 ;
9696
9797#ifdef DEBUG
98- #define DBG_check (vec ) asser (DCV_dbg_check_integrity(vec))
98+ #define DBG_check (vec ) assert (DCV_dbg_check_integrity(vec))
9999#else
100100#define DBG_check (vec )
101101#endif
@@ -233,13 +233,19 @@ typedef struct {
233233
234234// Reserve enough memory to hold the given amount of delta chunks
235235// 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
236238inline
237239int DCV_reserve_memory (DeltaChunkVector * vec , uint num_dc )
238240{
239241 if (num_dc <= vec -> reserved_size ){
240242 return 1 ;
241243 }
242244
245+ if (num_dc - vec -> reserved_size ){
246+ num_dc += gDVC_grow_by ;
247+ }
248+
243249#ifdef DEBUG
244250 bool was_null = vec -> mem == NULL ;
245251#endif
@@ -381,25 +387,6 @@ void DCV_reset(DeltaChunkVector* vec)
381387 vec -> size = 0 ;
382388}
383389
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- }
403390
404391// Append one chunk to the end of the list, and return a pointer to it
405392// It will not have been initialized !
@@ -838,6 +825,7 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
838825 const unsigned long rbound = cp_off + cp_size ;
839826 if (rbound < cp_size ||
840827 rbound > base_size ){
828+ assert (0 );
841829 break ;
842830 }
843831
@@ -849,6 +837,8 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
849837 // NOTE: Compression only necessary for all other deltas, not
850838 // for the first one, as we will share the data. It really depends
851839 // What's faster
840+ // Compression reduces fragmentation though, which is why we do it
841+ // in all cases.
852842 DeltaChunk * dc = DCV_append (& dcv );
853843 DC_init (dc , tbw , cmd , 0 );
854844 DC_set_data (dc , data , cmd , is_shared_data );
@@ -860,7 +850,10 @@ static PyObject* connect_deltas(PyObject *self, PyObject *dstreams)
860850 goto loop_end ;
861851 }
862852 }// 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+ }
864857
865858 if (!is_first_run ){
866859 DCV_connect_with_base (& tdcv , & dcv , & tmpl );
0 commit comments