Drop the GLibc implementation of Merge Sort and replace it with Timsort.
The algorithm has been tuned to work on arrays of pointers (void **),
so there's no longer a need to abstract the byte-width of each element
in the array.
All the comparison callbacks now take pointers-to-elements, not
pointers-to-pointers, so there's now one less level of dereferencing.
E.g.
int index_cmp(const void *a, const void *b)
{
- const git_index_entry *entry_a = *(const git_index_entry **)(a);
+ const git_index_entry *entry_a = (const git_index_entry *)(a);
The result is up to a 40% speed-up when sorting vectors. Memory usage
remains lineal.
A new `bsearch` implementation has been added, whose callback also
supplies pointer-to-elements, to uniform the Vector API again.
`git_futils_rmdir_r`: rename, clean up.
`git_reference_rename`: cleanup. Do not use 3x4096 buffers on the stack
or things will get ugly very fast. We can reuse the same buffer.
MSYS/MinGW uses winsock but obviously doesn't set _MSC_VER. Use _WIN32
to decide whether to use winsock or BSD headers. Also remove these
headers from src/transport_git.c altogether, as they are not needed.
MSYS is very conservative, so we have to tell it that we don't care
about versions of Windows lower than WindowsXP. We also need to tell
CMake to add ws2_32 to the libraries list and we shouldn't add the
-fPIC option, to MSYS because it complains that it does it anyway.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
So far libgit2 didn't handle the following scenarios:
* Rename of reference m -> m/m
* Rename of reference n/n -> n
Fixed.
Since we don't write reflogs, we have to delete any old reflog for the
renamed reference. Otherwise git.git will possibly fail when it finds
invalid logs.
Reported-by: nulltoken <emeric.fermas@gmail.com>
Signed-off-by: schu <schu-github@schulog.org>
git_futils_rmdir_recurs() shall remove the given directory and all
subdirectories. This happens only if the directories are empty.
Signed-off-by: schu <schu-github@schulog.org>
the old name succeeds, e.g. refs/heads/foo -> refs/heads/foo/bar
Reported-by: nulltoken <emeric.fermas@gmail.com>
Signed-off-by: schu <schu-github@schulog.org>
Run `make -f Makefile.embed` to get a `libgit2.a` with no dependencies
and no configuration on any Unix-like system.
The generated library can be linked with any piece of software without
licensing issues.
Have fun.
Removing a section variable doesn't remove its section
header. Overwrite the config10 file so there are no changes after the
test is run.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
It removes all entries with equal path except last added.
On large indexes git_index_append() + git_index_uniq() before writing is
*much* faster, than git_index_add().
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
The routine remove duplictes from the vector. Only the last added element
of elements with equal keys remains in the vector.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Index operation use git_vector_sort() to sort index entries. Since index
support adding duplicates (two or more entries with the same path), it's
important to preserve order of elements. Preserving order of elements
allows to make decisions based on order. For example it's possible to
implement function witch removes all duplicates except last added.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
In some cases it's important to preserve order of elements with equal
keys (stable sort). qsort(3) doesn't define order of elements with
equal keys.
git__msort() implements merge sort which is stable sort.
Implementation taken from git. Function renamed git_qsort() -> git__msort().
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
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>
Check if the window structure has actually been allocated before
trying to access it, and don't leak said structure if the map fails.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
Without this, hashtable.h doesn't know what uint32_t is and the
compiler thinks that it's a function type.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
examples/general.c:402:5: warning: enumeration value ‘GIT_REF_INVALID’ not handled in switch [-Wswitch]
examples/general.c:402:5: warning: enumeration value ‘GIT_REF_PACKED’ not handled in switch [-Wswitch]
examples/general.c:402:5: warning: enumeration value ‘GIT_REF_HAS_PEEL’ not handled in switch [-Wswitch]
examples/general.c:402:5: warning: enumeration value ‘GIT_REF_LISTALL’ not handled in switch [-Wswitch]
Signe-off-by: Kirill A. Shutemov <kirill@shutemov.name>
general.c:208: warning: passing argument 7 of 'git_commit_create_v' from incompatible pointer type
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>