mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 21:08:56 +00:00
Add support for manually freeing repo objects
A new method 'git_repository_object_free' allows to manually force the freeing of a repository object, even though they are still automatically managed by the repository and don't need to be freed by the user. Signed-off-by: Vicent Marti <tanoku@gmail.com>
This commit is contained in:
parent
f2408cc2ef
commit
9c9f4fc11c
@ -49,6 +49,21 @@ GIT_EXTERN(git_repository *) git_repository_alloc(git_odb *odb);
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(git_repository_object *) git_repository_lookup(git_repository *repo, const git_oid *id, git_otype type);
|
GIT_EXTERN(git_repository_object *) git_repository_lookup(git_repository *repo, const git_oid *id, git_otype type);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a reference to one of the objects in the repostory.
|
||||||
|
*
|
||||||
|
* Repository objects are managed automatically by the library,
|
||||||
|
* but this method can be used to force freeing one of the
|
||||||
|
* objects.
|
||||||
|
*
|
||||||
|
* Careful: freeing objects in the middle of a repository
|
||||||
|
* traversal will most likely cause errors.
|
||||||
|
*
|
||||||
|
* @param object the object to free
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(void) git_repository_object_free(git_repository_object *object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a previously allocated repository
|
* Free a previously allocated repository
|
||||||
* @param repo repository handle to close. If NULL nothing occurs.
|
* @param repo repository handle to close. If NULL nothing occurs.
|
||||||
|
@ -183,6 +183,37 @@ void *git_hashtable_lookup(git_hashtable *table, const void *key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_hashtable_remove(git_hashtable *table, const void *key)
|
||||||
|
{
|
||||||
|
git_hashtable_node *node, *prev_node;
|
||||||
|
uint32_t index, hash;
|
||||||
|
|
||||||
|
assert(table);
|
||||||
|
|
||||||
|
hash = table->hash(key);
|
||||||
|
index = (hash & table->size_mask);
|
||||||
|
node = table->nodes[index];
|
||||||
|
|
||||||
|
prev_node = NULL;
|
||||||
|
|
||||||
|
while (node != NULL) {
|
||||||
|
if (node->hash == hash && table->key_equal(node->object, key)) {
|
||||||
|
if (prev_node == NULL)
|
||||||
|
table->nodes[index] = node->next;
|
||||||
|
else
|
||||||
|
prev_node->next = node->next;
|
||||||
|
|
||||||
|
free(node);
|
||||||
|
return GIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_node = node;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GIT_ENOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void git_hashtable_iterator_init(git_hashtable *table, git_hashtable_iterator *it)
|
void git_hashtable_iterator_init(git_hashtable *table, git_hashtable_iterator *it)
|
||||||
|
@ -42,6 +42,7 @@ git_hashtable *git_hashtable_alloc(unsigned int min_size,
|
|||||||
git_hash_keyeq_ptr key_eq);
|
git_hash_keyeq_ptr key_eq);
|
||||||
int git_hashtable_insert(git_hashtable *h, const void *key, void *value);
|
int git_hashtable_insert(git_hashtable *h, const void *key, void *value);
|
||||||
void *git_hashtable_lookup(git_hashtable *h, const void *key);
|
void *git_hashtable_lookup(git_hashtable *h, const void *key);
|
||||||
|
int git_hashtable_remove(git_hashtable *table, const void *key);
|
||||||
void git_hashtable_free(git_hashtable *h);
|
void git_hashtable_free(git_hashtable *h);
|
||||||
void git_hashtable_clear(git_hashtable *h);
|
void git_hashtable_clear(git_hashtable *h);
|
||||||
|
|
||||||
|
@ -83,28 +83,8 @@ void git_repository_free(git_repository *repo)
|
|||||||
git_hashtable_iterator_init(repo->objects, &it);
|
git_hashtable_iterator_init(repo->objects, &it);
|
||||||
|
|
||||||
while ((object = (git_repository_object *)
|
while ((object = (git_repository_object *)
|
||||||
git_hashtable_iterator_next(&it)) != NULL) {
|
git_hashtable_iterator_next(&it)) != NULL)
|
||||||
|
git_repository_object_free(object);
|
||||||
git_obj_close(&object->dbo);
|
|
||||||
|
|
||||||
switch (object->dbo.type) {
|
|
||||||
case GIT_OBJ_COMMIT:
|
|
||||||
git_commit__free((git_commit *)object);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GIT_OBJ_TREE:
|
|
||||||
git_tree__free((git_tree *)object);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GIT_OBJ_TAG:
|
|
||||||
git_tag__free((git_tag *)object);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
free(object);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
git_hashtable_free(repo->objects);
|
git_hashtable_free(repo->objects);
|
||||||
/* TODO: free odb */
|
/* TODO: free odb */
|
||||||
@ -134,6 +114,30 @@ void git_repository__close_dbo(git_repository_object *object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void git_repository_object_free(git_repository_object *object)
|
||||||
|
{
|
||||||
|
git_hashtable_remove(object->repo->objects, &object->id);
|
||||||
|
git_obj_close(&object->dbo);
|
||||||
|
|
||||||
|
switch (object->dbo.type) {
|
||||||
|
case GIT_OBJ_COMMIT:
|
||||||
|
git_commit__free((git_commit *)object);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GIT_OBJ_TREE:
|
||||||
|
git_tree__free((git_tree *)object);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GIT_OBJ_TAG:
|
||||||
|
git_tag__free((git_tag *)object);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
free(object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
git_repository_object *git_repository_lookup(git_repository *repo, const git_oid *id, git_otype type)
|
git_repository_object *git_repository_lookup(git_repository *repo, const git_oid *id, git_otype type)
|
||||||
{
|
{
|
||||||
static const size_t object_sizes[] = {
|
static const size_t object_sizes[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user