Merge branch 'sp/pack'
authorJunio C Hamano <junkio@cox.net>
Sat, 2 Jun 2007 19:18:51 +0000 (12:18 -0700)
committerJunio C Hamano <junkio@cox.net>
Sat, 2 Jun 2007 19:18:51 +0000 (12:18 -0700)
* sp/pack:
Style nit - don't put space after function names
Ensure the pack index is opened before access
Simplify index access condition in count-objects, pack-redundant
Test for recent rev-parse $abbrev_sha1 regression
rev-parse: Identify short sha1 sums correctly.
Attempt to delay prepare_alt_odb during get_sha1
Micro-optimize prepare_alt_odb
Lazily open pack index files on demand

1  2 
cache.h
sha1_file.c
diff --combined cache.h
index 0da7070da4a88852995da8e11d4ad5436c328aa8,0f4a05b51ea7aca66e308443eefa1aa11d822a5f..8a9d1f3883150fd40ac1b6c0a44fa896c3133b04
+++ b/cache.h
@@@ -359,8 -359,8 +359,8 @@@ extern void *map_sha1_file(const unsign
  extern int has_pack_file(const unsigned char *sha1);
  extern int has_pack_index(const unsigned char *sha1);
  
 -extern signed char hexval_table[256];
 -static inline unsigned int hexval(unsigned int c)
 +extern const signed char hexval_table[256];
 +static inline unsigned int hexval(unsigned char c)
  {
        return hexval_table[c];
  }
@@@ -467,6 -467,8 +467,6 @@@ struct ref 
  extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags);
  extern int finish_connect(pid_t pid);
  extern int path_match(const char *path, int nr, char **match);
 -extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
 -                    int nr_refspec, char **refspec, int all);
  extern int get_ack(int fd, unsigned char *result_sha1);
  extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
  extern int server_supports(const char *feature);
@@@ -483,10 -485,11 +483,11 @@@ extern struct packed_git *find_sha1_pac
                                         struct packed_git *packs);
  
  extern void pack_report(void);
+ extern int open_pack_index(struct packed_git *);
  extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
  extern void unuse_pack(struct pack_window **);
  extern struct packed_git *add_packed_git(const char *, int, int);
- extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t);
+ extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
  extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
  extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
  extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
diff --combined sha1_file.c
index a1b8fca6c969938d685957af1ff060d5d41ad025,3093ac9f5f0d6cfc76f532a2f6690593410e9d6e..30bcd46ceb761b0f0b17295d532a6ddb5f33387a
@@@ -33,7 -33,7 +33,7 @@@ const unsigned char null_sha1[20]
  
  static unsigned int sha1_file_open_flag = O_NOATIME;
  
 -signed char hexval_table[256] = {
 +const signed char hexval_table[256] = {
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 00-07 */
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 08-0f */
         -1, -1, -1, -1, -1, -1, -1, -1,                /* 10-17 */
@@@ -376,11 -376,12 +376,12 @@@ void prepare_alt_odb(void
  {
        const char *alt;
  
+       if (alt_odb_tail)
+               return;
        alt = getenv(ALTERNATE_DB_ENVIRONMENT);
        if (!alt) alt = "";
  
-       if (alt_odb_tail)
-               return;
        alt_odb_tail = &alt_odb_list;
        link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
  
@@@ -530,6 -531,21 +531,21 @@@ static int check_packed_git_idx(const c
        return 0;
  }
  
+ int open_pack_index(struct packed_git *p)
+ {
+       char *idx_name;
+       int ret;
+       if (p->index_data)
+               return 0;
+       idx_name = xstrdup(p->pack_name);
+       strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
+       ret = check_packed_git_idx(idx_name, p);
+       free(idx_name);
+       return ret;
+ }
  static void scan_windows(struct packed_git *p,
        struct packed_git **lru_p,
        struct pack_window **lru_w,
@@@ -605,6 -621,9 +621,9 @@@ static int open_packed_git_1(struct pac
        unsigned char *idx_sha1;
        long fd_flag;
  
+       if (!p->index_data && open_pack_index(p))
+               return error("packfile %s index unavailable", p->pack_name);
        p->pack_fd = open(p->pack_name, O_RDONLY);
        if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
                return -1;
@@@ -757,8 -776,7 +776,7 @@@ struct packed_git *add_packed_git(cons
                return NULL;
        memcpy(p->pack_name, path, path_len);
        strcpy(p->pack_name + path_len, ".pack");
-       if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) ||
-           check_packed_git_idx(path, p)) {
+       if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
                free(p);
                return NULL;
        }
        /* ok, it looks sane as far as we can check without
         * actually mapping the pack file.
         */
+       p->index_version = 0;
+       p->index_data = NULL;
+       p->index_size = 0;
+       p->num_objects = 0;
        p->pack_size = st.st_size;
        p->next = NULL;
        p->windows = NULL;
@@@ -1572,10 -1594,15 +1594,15 @@@ void *unpack_entry(struct packed_git *p
        return data;
  }
  
- const unsigned char *nth_packed_object_sha1(const struct packed_git *p,
+ const unsigned char *nth_packed_object_sha1(struct packed_git *p,
                                            uint32_t n)
  {
        const unsigned char *index = p->index_data;
+       if (!index) {
+               if (open_pack_index(p))
+                       return NULL;
+               index = p->index_data;
+       }
        if (n >= p->num_objects)
                return NULL;
        index += 4 * 256;
@@@ -1612,6 -1639,12 +1639,12 @@@ off_t find_pack_entry_one(const unsigne
        const unsigned char *index = p->index_data;
        unsigned hi, lo;
  
+       if (!index) {
+               if (open_pack_index(p))
+                       return 0;
+               level1_ofs = p->index_data;
+               index = p->index_data;
+       }
        if (p->index_version > 1) {
                level1_ofs += 2;
                index += 8;
@@@ -1654,25 -1687,20 +1687,25 @@@ static int matches_pack_name(struct pac
  
  static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
  {
 +      static struct packed_git *last_found = (void *)1;
        struct packed_git *p;
        off_t offset;
  
        prepare_packed_git();
 +      if (!packed_git)
 +              return 0;
 +      p = (last_found == (void *)1) ? packed_git : last_found;
  
 -      for (p = packed_git; p; p = p->next) {
 +      do {
                if (ignore_packed) {
                        const char **ig;
                        for (ig = ignore_packed; *ig; ig++)
                                if (!matches_pack_name(p, *ig))
                                        break;
                        if (*ig)
 -                              continue;
 +                              goto next;
                }
 +
                offset = find_pack_entry_one(sha1, p);
                if (offset) {
                        /*
                         */
                        if (p->pack_fd == -1 && open_packed_git(p)) {
                                error("packfile %s cannot be accessed", p->pack_name);
 -                              continue;
 +                              goto next;
                        }
                        e->offset = offset;
                        e->p = p;
                        hashcpy(e->sha1, sha1);
 +                      last_found = p;
                        return 1;
                }
 -      }
 +
 +              next:
 +              if (p == last_found)
 +                      p = packed_git;
 +              else
 +                      p = p->next;
 +              if (p == last_found)
 +                      p = p->next;
 +      } while (p);
        return 0;
  }