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);