object.con commit [PATCH] Do not call fetch() when we have it. (ee4f439)
   1#include "object.h"
   2#include "blob.h"
   3#include "tree.h"
   4#include "commit.h"
   5#include "cache.h"
   6#include "tag.h"
   7#include <stdlib.h>
   8#include <string.h>
   9
  10struct object **objs;
  11int nr_objs;
  12static int obj_allocs;
  13
  14static int find_object(unsigned char *sha1)
  15{
  16        int first = 0, last = nr_objs;
  17
  18        while (first < last) {
  19                int next = (first + last) / 2;
  20                struct object *obj = objs[next];
  21                int cmp;
  22
  23                cmp = memcmp(sha1, obj->sha1, 20);
  24                if (!cmp)
  25                        return next;
  26                if (cmp < 0) {
  27                        last = next;
  28                        continue;
  29                }
  30                first = next+1;
  31        }
  32        return -first-1;
  33}
  34
  35struct object *lookup_object(unsigned char *sha1)
  36{
  37        int pos = find_object(sha1);
  38        if (pos >= 0)
  39                return objs[pos];
  40        return NULL;
  41}
  42
  43void created_object(unsigned char *sha1, struct object *obj)
  44{
  45        int pos = find_object(sha1);
  46
  47        obj->parsed = 0;
  48        memcpy(obj->sha1, sha1, 20);
  49        obj->type = NULL;
  50        obj->refs = NULL;
  51        obj->used = 0;
  52
  53        if (pos >= 0)
  54                die("Inserting %s twice\n", sha1_to_hex(sha1));
  55        pos = -pos-1;
  56
  57        if (obj_allocs == nr_objs) {
  58                obj_allocs = alloc_nr(obj_allocs);
  59                objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
  60        }
  61
  62        /* Insert it into the right place */
  63        memmove(objs + pos + 1, objs + pos, (nr_objs - pos) * 
  64                sizeof(struct object *));
  65
  66        objs[pos] = obj;
  67        nr_objs++;
  68}
  69
  70void add_ref(struct object *refer, struct object *target)
  71{
  72        struct object_list **pp = &refer->refs;
  73        struct object_list *p;
  74        
  75        while ((p = *pp) != NULL) {
  76                if (p->item == target)
  77                        return;
  78                pp = &p->next;
  79        }
  80
  81        target->used = 1;
  82        p = xmalloc(sizeof(*p));
  83        p->item = target;
  84        p->next = NULL;
  85        *pp = p;
  86}
  87
  88void mark_reachable(struct object *obj, unsigned int mask)
  89{
  90        struct object_list *p = obj->refs;
  91
  92        /* If we've been here already, don't bother */
  93        if (obj->flags & mask)
  94                return;
  95        obj->flags |= mask;
  96        while (p) {
  97                mark_reachable(p->item, mask);
  98                p = p->next;
  99        }
 100}
 101
 102struct object *parse_object(unsigned char *sha1)
 103{
 104        unsigned long mapsize;
 105        void *map = map_sha1_file(sha1, &mapsize);
 106        if (map) {
 107                char type[100];
 108                unsigned long size;
 109                void *buffer = unpack_sha1_file(map, mapsize, type, &size);
 110                if (!buffer)
 111                        return NULL;
 112                if (check_sha1_signature(sha1, buffer, size, type) < 0)
 113                        printf("sha1 mismatch %s\n", sha1_to_hex(sha1));
 114                munmap(map, mapsize);
 115                if (!strcmp(type, "blob")) {
 116                        struct blob *ret = lookup_blob(sha1);
 117                        parse_blob(ret);
 118                        return &ret->object;
 119                } else if (!strcmp(type, "tree")) {
 120                        struct tree *ret = lookup_tree(sha1);
 121                        parse_tree(ret);
 122                        return &ret->object;
 123                } else if (!strcmp(type, "commit")) {
 124                        struct commit *ret = lookup_commit(sha1);
 125                        parse_commit(ret);
 126                        return &ret->object;
 127                } else if (!strcmp(type, "tag")) {
 128                        struct tag *ret = lookup_tag(sha1);
 129                        parse_tag(ret);
 130                        return &ret->object;
 131                } else {
 132                        return NULL;
 133                }
 134        }
 135        return NULL;
 136}