@@ -81,6 +81,30 @@ int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
81
81
git__strncasecmp );
82
82
}
83
83
84
+ /**
85
+ * Allocate a tree entry, borrowing the filename from the tree which
86
+ * owns it. This is useful when reading trees, so we don't allocate a
87
+ * ton of small strings but can use the pool.
88
+ */
89
+ static git_tree_entry * alloc_entry_pooled (git_pool * pool , const char * filename )
90
+ {
91
+ git_tree_entry * entry = NULL ;
92
+ size_t filename_len = strlen (filename ), tree_len ;
93
+
94
+ if (GIT_ADD_SIZET_OVERFLOW (& tree_len , sizeof (git_tree_entry ), filename_len ) ||
95
+ GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , 1 ) ||
96
+ !(entry = git_pool_malloc (pool , tree_len )))
97
+ return NULL ;
98
+
99
+ memset (entry , 0x0 , sizeof (git_tree_entry ));
100
+ memcpy (entry -> filename , filename , filename_len );
101
+ entry -> filename [filename_len ] = 0 ;
102
+ entry -> filename_len = filename_len ;
103
+ entry -> pooled = true;
104
+
105
+ return entry ;
106
+ }
107
+
84
108
static git_tree_entry * alloc_entry (const char * filename )
85
109
{
86
110
git_tree_entry * entry = NULL ;
@@ -198,7 +222,7 @@ static int tree_key_search(
198
222
199
223
void git_tree_entry_free (git_tree_entry * entry )
200
224
{
201
- if (entry == NULL )
225
+ if (entry == NULL || entry -> pooled )
202
226
return ;
203
227
204
228
git__free (entry );
@@ -233,6 +257,7 @@ void git_tree__free(void *_tree)
233
257
git_tree_entry_free (e );
234
258
235
259
git_vector_free (& tree -> entries );
260
+ git_pool_clear (& tree -> pool );
236
261
git__free (tree );
237
262
}
238
263
@@ -385,6 +410,7 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
385
410
const char * buffer = git_odb_object_data (odb_obj );
386
411
const char * buffer_end = buffer + git_odb_object_size (odb_obj );
387
412
413
+ git_pool_init (& tree -> pool , 1 );
388
414
if (git_vector_init (& tree -> entries , DEFAULT_TREE_SIZE , entry_sort_cmp ) < 0 )
389
415
return -1 ;
390
416
@@ -403,13 +429,11 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
403
429
404
430
/** Allocate the entry and store it in the entries vector */
405
431
{
406
- entry = alloc_entry ( buffer );
432
+ entry = alloc_entry_pooled ( & tree -> pool , buffer );
407
433
GITERR_CHECK_ALLOC (entry );
408
434
409
- if (git_vector_insert (& tree -> entries , entry ) < 0 ) {
410
- git__free (entry );
435
+ if (git_vector_insert (& tree -> entries , entry ) < 0 )
411
436
return -1 ;
412
- }
413
437
414
438
entry -> attr = attr ;
415
439
}
0 commit comments