Skip to content

Commit 992499d

Browse files
committed
Merge branch 'dm/pack-objects-update' into maint
* dm/pack-objects-update: pack-objects: don't traverse objects unnecessarily pack-objects: rewrite add_descendants_to_write_order() iteratively pack-objects: use unsigned int for counter and offset values pack-objects: mark add_to_write_order() as inline
2 parents fcbebfd + 38d4deb commit 992499d

File tree

1 file changed

+55
-19
lines changed

1 file changed

+55
-19
lines changed

builtin/pack-objects.c

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,8 @@ static int mark_tagged(const char *path, const unsigned char *sha1, int flag,
454454
return 0;
455455
}
456456

457-
static void add_to_write_order(struct object_entry **wo,
458-
int *endp,
457+
static inline void add_to_write_order(struct object_entry **wo,
458+
unsigned int *endp,
459459
struct object_entry *e)
460460
{
461461
if (e->filled)
@@ -465,32 +465,62 @@ static void add_to_write_order(struct object_entry **wo,
465465
}
466466

467467
static void add_descendants_to_write_order(struct object_entry **wo,
468-
int *endp,
468+
unsigned int *endp,
469469
struct object_entry *e)
470470
{
471-
struct object_entry *child;
472-
473-
for (child = e->delta_child; child; child = child->delta_sibling)
474-
add_to_write_order(wo, endp, child);
475-
for (child = e->delta_child; child; child = child->delta_sibling)
476-
add_descendants_to_write_order(wo, endp, child);
471+
int add_to_order = 1;
472+
while (e) {
473+
if (add_to_order) {
474+
struct object_entry *s;
475+
/* add this node... */
476+
add_to_write_order(wo, endp, e);
477+
/* all its siblings... */
478+
for (s = e->delta_sibling; s; s = s->delta_sibling) {
479+
add_to_write_order(wo, endp, s);
480+
}
481+
}
482+
/* drop down a level to add left subtree nodes if possible */
483+
if (e->delta_child) {
484+
add_to_order = 1;
485+
e = e->delta_child;
486+
} else {
487+
add_to_order = 0;
488+
/* our sibling might have some children, it is next */
489+
if (e->delta_sibling) {
490+
e = e->delta_sibling;
491+
continue;
492+
}
493+
/* go back to our parent node */
494+
e = e->delta;
495+
while (e && !e->delta_sibling) {
496+
/* we're on the right side of a subtree, keep
497+
* going up until we can go right again */
498+
e = e->delta;
499+
}
500+
if (!e) {
501+
/* done- we hit our original root node */
502+
return;
503+
}
504+
/* pass it off to sibling at this level */
505+
e = e->delta_sibling;
506+
}
507+
};
477508
}
478509

479510
static void add_family_to_write_order(struct object_entry **wo,
480-
int *endp,
511+
unsigned int *endp,
481512
struct object_entry *e)
482513
{
483514
struct object_entry *root;
484515

485516
for (root = e; root->delta; root = root->delta)
486517
; /* nothing */
487-
add_to_write_order(wo, endp, root);
488518
add_descendants_to_write_order(wo, endp, root);
489519
}
490520

491521
static struct object_entry **compute_write_order(void)
492522
{
493-
int i, wo_end;
523+
unsigned int i, wo_end, last_untagged;
494524

495525
struct object_entry **wo = xmalloc(nr_objects * sizeof(*wo));
496526

@@ -506,8 +536,8 @@ static struct object_entry **compute_write_order(void)
506536
* Make sure delta_sibling is sorted in the original
507537
* recency order.
508538
*/
509-
for (i = nr_objects - 1; 0 <= i; i--) {
510-
struct object_entry *e = &objects[i];
539+
for (i = nr_objects; i > 0;) {
540+
struct object_entry *e = &objects[--i];
511541
if (!e->delta)
512542
continue;
513543
/* Mark me as the first child */
@@ -521,14 +551,15 @@ static struct object_entry **compute_write_order(void)
521551
for_each_tag_ref(mark_tagged, NULL);
522552

523553
/*
524-
* Give the commits in the original recency order until
554+
* Give the objects in the original recency order until
525555
* we see a tagged tip.
526556
*/
527557
for (i = wo_end = 0; i < nr_objects; i++) {
528558
if (objects[i].tagged)
529559
break;
530560
add_to_write_order(wo, &wo_end, &objects[i]);
531561
}
562+
last_untagged = i;
532563

533564
/*
534565
* Then fill all the tagged tips.
@@ -541,7 +572,7 @@ static struct object_entry **compute_write_order(void)
541572
/*
542573
* And then all remaining commits and tags.
543574
*/
544-
for (i = 0; i < nr_objects; i++) {
575+
for (i = last_untagged; i < nr_objects; i++) {
545576
if (objects[i].type != OBJ_COMMIT &&
546577
objects[i].type != OBJ_TAG)
547578
continue;
@@ -551,7 +582,7 @@ static struct object_entry **compute_write_order(void)
551582
/*
552583
* And then all the trees.
553584
*/
554-
for (i = 0; i < nr_objects; i++) {
585+
for (i = last_untagged; i < nr_objects; i++) {
555586
if (objects[i].type != OBJ_TREE)
556587
continue;
557588
add_to_write_order(wo, &wo_end, &objects[i]);
@@ -560,8 +591,13 @@ static struct object_entry **compute_write_order(void)
560591
/*
561592
* Finally all the rest in really tight order
562593
*/
563-
for (i = 0; i < nr_objects; i++)
564-
add_family_to_write_order(wo, &wo_end, &objects[i]);
594+
for (i = last_untagged; i < nr_objects; i++) {
595+
if (!objects[i].filled)
596+
add_family_to_write_order(wo, &wo_end, &objects[i]);
597+
}
598+
599+
if (wo_end != nr_objects)
600+
die("ordered %u objects, expected %"PRIu32, wo_end, nr_objects);
565601

566602
return wo;
567603
}

0 commit comments

Comments
 (0)