struct llist_item {
struct llist_item *next;
- unsigned char *sha1;
+ const unsigned char *sha1;
};
static struct llist {
struct llist_item *front;
{
struct llist *ret;
struct llist_item *new, *old, *prev;
-
+
llist_init(&ret);
if ((ret->size = list->size) == 0)
}
new->next = NULL;
ret->back = new;
-
+
return ret;
}
-static inline struct llist_item * llist_insert(struct llist *list,
- struct llist_item *after,
- unsigned char *sha1)
+static inline struct llist_item *llist_insert(struct llist *list,
+ struct llist_item *after,
+ const unsigned char *sha1)
{
struct llist_item *new = llist_item_get();
new->sha1 = sha1;
return new;
}
-static inline struct llist_item *llist_insert_back(struct llist *list, unsigned char *sha1)
+static inline struct llist_item *llist_insert_back(struct llist *list,
+ const unsigned char *sha1)
{
return llist_insert(list, list->back, sha1);
}
-static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, unsigned char *sha1, struct llist_item *hint)
+static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
+ const unsigned char *sha1, struct llist_item *hint)
{
struct llist_item *prev = NULL, *l;
l = (hint == NULL) ? list->front : hint;
while (l) {
- int cmp = memcmp(l->sha1, sha1, 20);
+ int cmp = hashcmp(l->sha1, sha1);
if (cmp > 0) { /* we insert before this entry */
return llist_insert(list, prev, sha1);
}
l = (hint == NULL) ? list->front : hint;
prev = NULL;
while (l) {
- int cmp = memcmp(l->sha1, sha1, 20);
+ int cmp = hashcmp(l->sha1, sha1);
if (cmp > 0) /* not in list, since sorted */
return prev;
if(!cmp) { /* found */
static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
{
- int p1_off, p2_off;
- unsigned char *p1_base, *p2_base;
+ unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
+ const unsigned char *p1_base, *p2_base;
struct llist_item *p1_hint = NULL, *p2_hint = NULL;
- p1_off = p2_off = 256 * 4 + 4;
- p1_base = (unsigned char *) p1->pack->index_base;
- p2_base = (unsigned char *) p2->pack->index_base;
+ p1_base = p1->pack->index_data;
+ p2_base = p2->pack->index_data;
+ p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8);
+ p2_base += 256 * 4 + ((p2->pack->index_version < 2) ? 4 : 8);
+ p1_step = (p1->pack->index_version < 2) ? 24 : 20;
+ p2_step = (p2->pack->index_version < 2) ? 24 : 20;
- while (p1_off <= p1->pack->index_size - 3 * 20 &&
- p2_off <= p2->pack->index_size - 3 * 20)
+ while (p1_off < p1->pack->num_objects * p1_step &&
+ p2_off < p2->pack->num_objects * p2_step)
{
- int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
/* cmp ~ p1 - p2 */
if (cmp == 0) {
p1_hint = llist_sorted_remove(p1->unique_objects,
p1_base + p1_off, p1_hint);
p2_hint = llist_sorted_remove(p2->unique_objects,
p1_base + p1_off, p2_hint);
- p1_off+=24;
- p2_off+=24;
+ p1_off += p1_step;
+ p2_off += p2_step;
continue;
}
if (cmp < 0) { /* p1 has the object, p2 doesn't */
- p1_off+=24;
+ p1_off += p1_step;
} else { /* p2 has the object, p1 doesn't */
- p2_off+=24;
+ p2_off += p2_step;
}
}
}
static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
{
size_t ret = 0;
- int p1_off, p2_off;
- char *p1_base, *p2_base;
-
- p1_off = p2_off = 256 * 4 + 4;
- p1_base = (char *)p1->index_base;
- p2_base = (char *)p2->index_base;
-
- while (p1_off <= p1->index_size - 3 * 20 &&
- p2_off <= p2->index_size - 3 * 20)
+ unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
+ const unsigned char *p1_base, *p2_base;
+
+ p1_base = p1->index_data;
+ p2_base = p2->index_data;
+ p1_base += 256 * 4 + ((p1->index_version < 2) ? 4 : 8);
+ p2_base += 256 * 4 + ((p2->index_version < 2) ? 4 : 8);
+ p1_step = (p1->index_version < 2) ? 24 : 20;
+ p2_step = (p2->index_version < 2) ? 24 : 20;
+
+ while (p1_off < p1->num_objects * p1_step &&
+ p2_off < p2->num_objects * p2_step)
{
- int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
/* cmp ~ p1 - p2 */
if (cmp == 0) {
ret++;
- p1_off+=24;
- p2_off+=24;
+ p1_off += p1_step;
+ p2_off += p2_step;
continue;
}
if (cmp < 0) { /* p1 has the object, p2 doesn't */
- p1_off+=24;
+ p1_off += p1_step;
} else { /* p2 has the object, p1 doesn't */
- p2_off+=24;
+ p2_off += p2_step;
}
}
return ret;
return ret;
}
-static inline size_t pack_set_bytecount(struct pack_list *pl)
+static inline off_t pack_set_bytecount(struct pack_list *pl)
{
- size_t ret = 0;
+ off_t ret = 0;
while (pl) {
ret += pl->pack->pack_size;
ret += pl->pack->index_size;
*non_unique = NULL, *min_perm = NULL;
struct pll *perm, *perm_all, *perm_ok = NULL, *new_perm;
struct llist *missing;
- size_t min_perm_size = (size_t)-1, perm_size;
+ off_t min_perm_size = 0, perm_size;
int n;
pl = local_packs;
perm = perm_ok;
while (perm) {
perm_size = pack_set_bytecount(perm->pl);
- if (min_perm_size > perm_size) {
+ if (!min_perm_size || min_perm_size > perm_size) {
min_perm_size = perm_size;
min_perm = perm->pl;
}
static struct pack_list * add_pack(struct packed_git *p)
{
struct pack_list l;
- size_t off;
- unsigned char *base;
+ unsigned long off = 0, step;
+ const unsigned char *base;
if (!p->pack_local && !(alt_odb || verbose))
return NULL;
l.pack = p;
llist_init(&l.all_objects);
- off = 256 * 4 + 4;
- base = (unsigned char *)p->index_base;
- while (off <= p->index_size - 3 * 20) {
+ if (open_pack_index(p))
+ return NULL;
+
+ base = p->index_data;
+ base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
+ step = (p->index_version < 2) ? 24 : 20;
+ while (off < p->num_objects * step) {
llist_insert_back(l.all_objects, base + off);
- off += 24;
+ off += step;
}
/* this list will be pruned in cmp_two_packs later */
l.unique_objects = llist_copy(l.all_objects);