mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-04 14:33:04 +00:00
index: speedup git_index_append()/git_index_append2()
git_index_find() in index_insert() is useless if replace is not requested (append). Do not call it in this case. It speedup git_index_append() *dramatically* on large indexes. $ cat index_test.c int main(int argc, char **argv) { git_index *index; git_repository *repo; git_odb *odb; struct git_index_entry entry; git_oid tree_oid; char tree_hex[41]; int i; git_repository_init(&repo, "/tmp/myrepo", 0); odb = git_repository_database(repo); git_repository_index(&index, repo); memset(&entry, 0, sizeof(entry)); git_odb_write(&entry.oid, odb, "", 0, GIT_OBJ_BLOB); entry.path = "test.file"; for (i = 0; i < 50000; i++) git_index_append2(index, &entry); git_tree_create_fromindex(&tree_oid, index); git_oid_fmt(tree_hex, &tree_oid); tree_hex[40] = '\0'; printf("tree: %s\n", tree_hex); git_index_free(index); git_repository_free(repo); return 0; } Before: $ time ./index_test tree: 43f73659c43b651588cc81459d9e25b08721b95d ./index_test 151.19s user 0.05s system 99% cpu 2:31.78 total After: $ time ./index_test tree: 43f73659c43b651588cc81459d9e25b08721b95d ./index_test 0.05s user 0.00s system 94% cpu 0.059 total About 2573 times speedup on this test :) Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
This commit is contained in:
parent
178376025c
commit
8cc16e29e8
34
src/index.c
34
src/index.c
@ -348,6 +348,7 @@ static int index_insert(git_index *index, const git_index_entry *source_entry, i
|
|||||||
git_index_entry *entry;
|
git_index_entry *entry;
|
||||||
size_t path_length;
|
size_t path_length;
|
||||||
int position;
|
int position;
|
||||||
|
git_index_entry **entry_array;
|
||||||
|
|
||||||
assert(index && source_entry);
|
assert(index && source_entry);
|
||||||
|
|
||||||
@ -375,27 +376,28 @@ static int index_insert(git_index *index, const git_index_entry *source_entry, i
|
|||||||
else
|
else
|
||||||
entry->flags |= GIT_IDXENTRY_NAMEMASK;;
|
entry->flags |= GIT_IDXENTRY_NAMEMASK;;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* replacing is not requested: just insert entry at the end;
|
||||||
|
* the index is no longer sorted
|
||||||
|
*/
|
||||||
|
if (!replace)
|
||||||
|
return git_vector_insert(&index->entries, entry);
|
||||||
|
|
||||||
/* look if an entry with this path already exists */
|
/* look if an entry with this path already exists */
|
||||||
position = git_index_find(index, source_entry->path);
|
position = git_index_find(index, source_entry->path);
|
||||||
|
|
||||||
/* if no entry exists and replace is not set,
|
/*
|
||||||
* add the entry at the end;
|
* if no entry exists add the entry at the end;
|
||||||
* the index is no longer sorted */
|
* the index is no longer sorted
|
||||||
if (!replace || position == GIT_ENOTFOUND) {
|
*/
|
||||||
if (git_vector_insert(&index->entries, entry) < GIT_SUCCESS)
|
if (position == GIT_ENOTFOUND)
|
||||||
return GIT_ENOMEM;
|
return git_vector_insert(&index->entries, entry);
|
||||||
|
|
||||||
/* if a previous entry exists and replace is set,
|
/* exists, replace it */
|
||||||
* replace it */
|
entry_array = (git_index_entry **) index->entries.contents;
|
||||||
} else {
|
free((char *)entry_array[position]->path);
|
||||||
git_index_entry **entry_array = (git_index_entry **)index->entries.contents;
|
free(entry_array[position]);
|
||||||
|
entry_array[position] = entry;
|
||||||
free((char *)entry_array[position]->path);
|
|
||||||
free(entry_array[position]);
|
|
||||||
|
|
||||||
entry_array[position] = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user