diff options
author | Vicent Marti <tanoku@gmail.com> | 2011-07-13 02:49:47 +0200 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-07-13 02:49:47 +0200 |
commit | 761aa2aa35d5427b8b22d342ef2116bc22252648 (patch) | |
tree | cdfdf6a6240466418ccfb84c996ce53728a37a98 /src/commit.c | |
parent | 3dd26d1e36bec9753bee6c8a8f1311d7a0c47972 (diff) | |
download | libgit2-761aa2aa35d5427b8b22d342ef2116bc22252648.tar.gz |
tree: Fix wrong sort order when querying entries
Fixes #127 (that was quite an outstanding issue).
Rationale:
The tree objects on Git are stored and read following a very specific
sorting algorithm that places folders before files. That original sort
was the sort we were storing on memory, but this sort was being queried
with a binary search that used a simple `strcmp` for comparison, so
there were many instances where the search was failing.
Obviously, the most straightforward way to fix this is changing the
binary search CB to use the same comparison method as the sorting CB.
The problem with this is that the binary search callback compares a path
and an entry, so there is no way to know if the given path is a folder
or a standard file.
How do we work around this? Instead of splitting the `entry_byname`
method in two (one for searching directories and one for searching
normal files), we just assume that the path we are searching for is of
the same kind as the path it's being compared at the moment.
return git_futils_cmp_path(
ksearch->filename, ksearch->filename_len, entry->attr & 040000,
entry->filename, entry->filename_len, entry->attr & 040000);
Since there cannot be a folder and a regular file with the same name on
the same tree, the most basic equality check will always fail
for all comparsions, until our path is compared with the actual entry we
are looking for; in this case, the matching will succeed with the file
type of the entry -- whatever it was initially.
I hope that makes sense.
PS: While I was at it, I switched the cmp methods to use cached values
for the length of each filename. That makes searches and sorts
retardedly fast -- I was wondering the reason of the performance hiccups
on massive trees; it's because of 2*strlen for each comparsion call.
Diffstat (limited to 'src/commit.c')
0 files changed, 0 insertions, 0 deletions