Skip to content

Commit

Permalink
vector: Timsort all of the things
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vmg committed Jul 7, 2011
1 parent c63aa49 commit de18f27
Show file tree
Hide file tree
Showing 11 changed files with 424 additions and 85 deletions.
4 changes: 2 additions & 2 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ void git_config_free(git_config *cfg)

static int config_backend_cmp(const void *a, const void *b)
{
const file_internal *bk_a = *(const file_internal **)(a);
const file_internal *bk_b = *(const file_internal **)(b);
const file_internal *bk_a = (const file_internal *)(a);
const file_internal *bk_b = (const file_internal *)(b);

return bk_b->priority - bk_a->priority;
}
Expand Down
12 changes: 6 additions & 6 deletions src/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,31 +109,31 @@ static int write_index(git_index *index, git_filebuf *file);
int index_srch(const void *key, const void *array_member)
{
const char *filename = (const char *)key;
const git_index_entry *entry = *(const git_index_entry **)(array_member);
const git_index_entry *entry = (const git_index_entry *)(array_member);

return strcmp(filename, entry->path);
}

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_b = *(const git_index_entry **)(b);
const git_index_entry *entry_a = (const git_index_entry *)(a);
const git_index_entry *entry_b = (const git_index_entry *)(b);

return strcmp(entry_a->path, entry_b->path);
}

int unmerged_srch(const void *key, const void *array_member)
{
const char *path = (const char *) key;
const git_index_entry_unmerged *entry = *(const git_index_entry_unmerged **) (array_member);
const git_index_entry_unmerged *entry = (const git_index_entry_unmerged *)(array_member);

return strcmp(path, entry->path);
}

int unmerged_cmp(const void *a, const void *b)
{
const git_index_entry_unmerged *info_a = *(const git_index_entry_unmerged **)(a);
const git_index_entry_unmerged *info_b = *(const git_index_entry_unmerged **)(b);
const git_index_entry_unmerged *info_a = (const git_index_entry_unmerged *)(a);
const git_index_entry_unmerged *info_b = (const git_index_entry_unmerged *)(b);

return strcmp(info_a->path, info_b->path);
}
Expand Down
4 changes: 2 additions & 2 deletions src/odb.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend

static int backend_sort_cmp(const void *a, const void *b)
{
const backend_internal *backend_a = *(const backend_internal **)(a);
const backend_internal *backend_b = *(const backend_internal **)(b);
const backend_internal *backend_a = (const backend_internal *)(a);
const backend_internal *backend_b = (const backend_internal *)(b);

if (backend_a->is_alternate == backend_b->is_alternate)
return (backend_b->priority - backend_a->priority);
Expand Down
4 changes: 2 additions & 2 deletions src/odb_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,8 @@ static int pack_index_open(struct pack_file *p)

static int packfile_sort__cb(const void *a_, const void *b_)
{
struct pack_file *a = *((struct pack_file **)a_);
struct pack_file *b = *((struct pack_file **)b_);
struct pack_file *a = (struct pack_file *)a_;
struct pack_file *b = (struct pack_file *)b_;
int st;

/*
Expand Down
4 changes: 2 additions & 2 deletions src/refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,8 @@ static int packed_remove_loose(git_repository *repo, git_vector *packing_list)

static int packed_sort(const void *a, const void *b)
{
const git_reference *ref_a = *(const git_reference **)a;
const git_reference *ref_b = *(const git_reference **)b;
const git_reference *ref_a = (const git_reference *)a;
const git_reference *ref_b = (const git_reference *)b;

return strcmp(ref_a->name, ref_b->name);
}
Expand Down
6 changes: 3 additions & 3 deletions src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static int valid_attributes(const int attributes) {
int entry_search_cmp(const void *key, const void *array_member)
{
const char *filename = (const char *)key;
const git_tree_entry *entry = *(const git_tree_entry **)(array_member);
const git_tree_entry *entry = (const git_tree_entry *)(array_member);

return strcmp(filename, entry->filename);
}
Expand All @@ -53,8 +53,8 @@ static int valid_attributes(const int attributes) {

int entry_sort_cmp(const void *a, const void *b)
{
const git_tree_entry *entry_a = *(const git_tree_entry **)(a);
const git_tree_entry *entry_b = *(const git_tree_entry **)(b);
const git_tree_entry *entry_a = (const git_tree_entry *)(a);
const git_tree_entry *entry_b = (const git_tree_entry *)(b);

return git_futils_cmp_path(entry_a->filename, strlen(entry_a->filename),
entry_a->attr & 040000,
Expand Down
Loading

0 comments on commit de18f27

Please sign in to comment.