Code

Merge git://repo.or.cz/git-gui
[git.git] / sha1_file.c
index 445a871db31673af20017d36ff22fd106f77f510..3516777bc7614c23da02dd7a9aa28a48294d56cb 100644 (file)
@@ -15,6 +15,7 @@
 #include "tree.h"
 #include "refs.h"
 #include "pack-revindex.h"
+#include "sha1-lookup.h"
 
 #ifndef O_NOATIME
 #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@ -1675,7 +1676,12 @@ off_t find_pack_entry_one(const unsigned char *sha1,
 {
        const uint32_t *level1_ofs = p->index_data;
        const unsigned char *index = p->index_data;
-       unsigned hi, lo;
+       unsigned hi, lo, stride;
+       static int use_lookup = -1;
+       static int debug_lookup = -1;
+
+       if (debug_lookup < 0)
+               debug_lookup = !!getenv("GIT_DEBUG_LOOKUP");
 
        if (!index) {
                if (open_pack_index(p))
@@ -1690,11 +1696,34 @@ off_t find_pack_entry_one(const unsigned char *sha1,
        index += 4 * 256;
        hi = ntohl(level1_ofs[*sha1]);
        lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
+       if (p->index_version > 1) {
+               stride = 20;
+       } else {
+               stride = 24;
+               index += 4;
+       }
+
+       if (debug_lookup)
+               printf("%02x%02x%02x... lo %u hi %u nr %u\n",
+                      sha1[0], sha1[1], sha1[2], lo, hi, p->num_objects);
+
+       if (use_lookup < 0)
+               use_lookup = !!getenv("GIT_USE_LOOKUP");
+       if (use_lookup) {
+               int pos = sha1_entry_pos(index, stride, 0,
+                                        lo, hi, p->num_objects, sha1);
+               if (pos < 0)
+                       return 0;
+               return nth_packed_object_offset(p, pos);
+       }
 
        do {
                unsigned mi = (lo + hi) / 2;
-               unsigned x = (p->index_version > 1) ? (mi * 20) : (mi * 24 + 4);
-               int cmp = hashcmp(index + x, sha1);
+               int cmp = hashcmp(index + mi * stride, sha1);
+
+               if (debug_lookup)
+                       printf("lo %u hi %u rg %u mi %u\n",
+                              lo, hi, hi - lo, mi);
                if (!cmp)
                        return nth_packed_object_offset(p, mi);
                if (cmp > 0)
@@ -2437,16 +2466,10 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write
 
 int read_pack_header(int fd, struct pack_header *header)
 {
-       char *c = (char*)header;
-       ssize_t remaining = sizeof(struct pack_header);
-       do {
-               ssize_t r = xread(fd, c, remaining);
-               if (r <= 0)
-                       /* "eof before pack header was fully read" */
-                       return PH_ERROR_EOF;
-               remaining -= r;
-               c += r;
-       } while (remaining > 0);
+       if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
+               /* "eof before pack header was fully read" */
+               return PH_ERROR_EOF;
+
        if (header->hdr_signature != htonl(PACK_SIGNATURE))
                /* "protocol error (pack signature mismatch detected)" */
                return PH_ERROR_PACK_SIGNATURE;