4 #include "sha1-lookup.h"
 
   7 static int commit_patch_id(struct commit *commit, struct diff_options *options,
 
  11                 diff_tree_sha1(commit->parents->item->object.sha1,
 
  12                                commit->object.sha1, "", options);
 
  14                 diff_root_tree_sha1(commit->object.sha1, "", options);
 
  15         diffcore_std(options);
 
  16         return diff_flush_patch_id(options, sha1);
 
  19 static const unsigned char *patch_id_access(size_t index, void *table)
 
  21         struct patch_id **id_table = table;
 
  22         return id_table[index]->patch_id;
 
  25 static int patch_pos(struct patch_id **table, int nr, const unsigned char *id)
 
  27         return sha1_pos(id, table, nr, patch_id_access);
 
  30 #define BUCKET_SIZE 190 /* 190 * 21 = 3990, with slop close enough to 4K */
 
  31 struct patch_id_bucket {
 
  32         struct patch_id_bucket *next;
 
  34         struct patch_id bucket[BUCKET_SIZE];
 
  37 int init_patch_ids(struct patch_ids *ids)
 
  39         memset(ids, 0, sizeof(*ids));
 
  40         diff_setup(&ids->diffopts);
 
  41         DIFF_OPT_SET(&ids->diffopts, RECURSIVE);
 
  42         if (diff_setup_done(&ids->diffopts) < 0)
 
  43                 return error("diff_setup_done failed");
 
  47 int free_patch_ids(struct patch_ids *ids)
 
  49         struct patch_id_bucket *next, *patches;
 
  52         for (patches = ids->patches; patches; patches = next) {
 
  59 static struct patch_id *add_commit(struct commit *commit,
 
  60                                    struct patch_ids *ids,
 
  63         struct patch_id_bucket *bucket;
 
  65         unsigned char sha1[20];
 
  68         if (commit_patch_id(commit, &ids->diffopts, sha1))
 
  70         pos = patch_pos(ids->table, ids->nr, sha1);
 
  72                 return ids->table[pos];
 
  78         bucket = ids->patches;
 
  79         if (!bucket || (BUCKET_SIZE <= bucket->nr)) {
 
  80                 bucket = xcalloc(1, sizeof(*bucket));
 
  81                 bucket->next = ids->patches;
 
  82                 ids->patches = bucket;
 
  84         ent = &bucket->bucket[bucket->nr++];
 
  85         hashcpy(ent->patch_id, sha1);
 
  87         if (ids->alloc <= ids->nr) {
 
  88                 ids->alloc = alloc_nr(ids->nr);
 
  89                 ids->table = xrealloc(ids->table, sizeof(ent) * ids->alloc);
 
  92                 memmove(ids->table + pos + 1, ids->table + pos,
 
  93                         sizeof(ent) * (ids->nr - pos));
 
  95         ids->table[pos] = ent;
 
  96         return ids->table[pos];
 
  99 struct patch_id *has_commit_patch_id(struct commit *commit,
 
 100                                      struct patch_ids *ids)
 
 102         return add_commit(commit, ids, 1);
 
 105 struct patch_id *add_commit_patch_id(struct commit *commit,
 
 106                                      struct patch_ids *ids)
 
 108         return add_commit(commit, ids, 0);