diff options
| author | Junio C Hamano <gitster@pobox.com> | 2009-05-25 00:59:07 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2009-05-25 00:59:07 -0700 |
| commit | ee969693c5e77e1b5ebda45bead569806d31b379 (patch) | |
| tree | 25d803cd17cbe891a9937f3e3442a1d7863ae773 /patch-ids.c | |
| parent | 4c8d4c14c6de59bc14d6118724ffee949e8654a7 (diff) | |
| parent | 9619ff14159ab3401636b9883a715b0f20b051df (diff) | |
| download | git-ee969693c5e77e1b5ebda45bead569806d31b379.tar.gz | |
Merge branch 'master' into sb/opt-filename
* master: (654 commits)
http-push.c::remove_locks(): fix use after free
t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C
post-receive-email: hooks.showrev: show how to include both web link and patch
MinGW: Fix compiler warning in merge-recursive
MinGW: Add a simple getpass()
MinGW: use POSIX signature of waitpid()
MinGW: the path separator to split GITPERLLIB is ';' on Win32
MinGW: Scan for \r in addition to \n when reading shbang lines
gitweb: Sanitize title attribute in format_subject_html
Terminate argv with NULL before calling setup_revisions()
doc/git-rebase.txt: remove mention of multiple strategies
git-send-email: Handle quotes when parsing .mailrc files
git-svn: add --authors-prog option
git-svn: Set svn.authorsfile if it is passed to git svn clone
git-svn: Correctly report max revision when following deleted paths
git-svn: Fix for svn paths removed > log-window-size revisions ago
git-svn testsuite: use standard configuration for Subversion tools
grep: fix word-regexp colouring
completion: use git rev-parse to detect bare repos
Cope better with a _lot_ of packs
...
Diffstat (limited to 'patch-ids.c')
| -rw-r--r-- | patch-ids.c | 93 |
1 files changed, 5 insertions, 88 deletions
diff --git a/patch-ids.c b/patch-ids.c index 3be5d3165e..5717257051 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -1,6 +1,7 @@ #include "cache.h" #include "diff.h" #include "commit.h" +#include "sha1-lookup.h" #include "patch-ids.h" static int commit_patch_id(struct commit *commit, struct diff_options *options, @@ -15,99 +16,15 @@ static int commit_patch_id(struct commit *commit, struct diff_options *options, return diff_flush_patch_id(options, sha1); } -static uint32_t take2(const unsigned char *id) +static const unsigned char *patch_id_access(size_t index, void *table) { - return ((id[0] << 8) | id[1]); + struct patch_id **id_table = table; + return id_table[index]->patch_id; } -/* - * Conventional binary search loop looks like this: - * - * do { - * int mi = (lo + hi) / 2; - * int cmp = "entry pointed at by mi" minus "target"; - * if (!cmp) - * return (mi is the wanted one) - * if (cmp > 0) - * hi = mi; "mi is larger than target" - * else - * lo = mi+1; "mi is smaller than target" - * } while (lo < hi); - * - * The invariants are: - * - * - When entering the loop, lo points at a slot that is never - * above the target (it could be at the target), hi points at a - * slot that is guaranteed to be above the target (it can never - * be at the target). - * - * - We find a point 'mi' between lo and hi (mi could be the same - * as lo, but never can be the same as hi), and check if it hits - * the target. There are three cases: - * - * - if it is a hit, we are happy. - * - * - if it is strictly higher than the target, we update hi with - * it. - * - * - if it is strictly lower than the target, we update lo to be - * one slot after it, because we allow lo to be at the target. - * - * When choosing 'mi', we do not have to take the "middle" but - * anywhere in between lo and hi, as long as lo <= mi < hi is - * satisfied. When we somehow know that the distance between the - * target and lo is much shorter than the target and hi, we could - * pick mi that is much closer to lo than the midway. - */ static int patch_pos(struct patch_id **table, int nr, const unsigned char *id) { - int hi = nr; - int lo = 0; - int mi = 0; - - if (!nr) - return -1; - - if (nr != 1) { - unsigned lov, hiv, miv, ofs; - - for (ofs = 0; ofs < 18; ofs += 2) { - lov = take2(table[0]->patch_id + ofs); - hiv = take2(table[nr-1]->patch_id + ofs); - miv = take2(id + ofs); - if (miv < lov) - return -1; - if (hiv < miv) - return -1 - nr; - if (lov != hiv) { - /* - * At this point miv could be equal - * to hiv (but id could still be higher); - * the invariant of (mi < hi) should be - * kept. - */ - mi = (nr-1) * (miv - lov) / (hiv - lov); - if (lo <= mi && mi < hi) - break; - die("oops"); - } - } - if (18 <= ofs) - die("cannot happen -- lo and hi are identical"); - } - - do { - int cmp; - cmp = hashcmp(table[mi]->patch_id, id); - if (!cmp) - return mi; - if (cmp > 0) - hi = mi; - else - lo = mi + 1; - mi = (hi + lo) / 2; - } while (lo < hi); - return -lo-1; + return sha1_pos(id, table, nr, patch_id_access); } #define BUCKET_SIZE 190 /* 190 * 21 = 3990, with slop close enough to 4K */ |
