@@ -501,34 +501,56 @@ struct commit *pop_commit(struct commit_list **stack)
501
501
return item ;
502
502
}
503
503
504
+ struct commit_slab_piece {
505
+ int buf ;
506
+ };
507
+
504
508
struct commit_slab {
505
- int * buf ;
506
- int alloc ;
509
+ int piece_size ;
510
+ int piece_count ;
511
+ struct commit_slab_piece * * piece ;
507
512
};
508
513
509
514
static void slab_init (struct commit_slab * s )
510
515
{
511
- memset (s , 0 , sizeof (* s ));
516
+ /* allocate ~512kB at once, allowing for malloc overhead */
517
+ int size = (512 * 1024 - 32 ) / sizeof (struct commit_slab_piece );
518
+
519
+ s -> piece_size = size ;
520
+ s -> piece_count = 0 ;
521
+ s -> piece = NULL ;
512
522
}
513
523
514
524
static void slab_clear (struct commit_slab * s )
515
525
{
516
- free (s -> buf );
517
- slab_init (s );
526
+ int i ;
527
+
528
+ for (i = 0 ; i < s -> piece_count ; i ++ )
529
+ free (s -> piece [i ]);
530
+ s -> piece_count = 0 ;
531
+ free (s -> piece );
532
+ s -> piece = NULL ;
518
533
}
519
534
520
- static inline int * slab_at (struct commit_slab * s , const struct commit * c )
535
+ static inline struct commit_slab_piece * slab_at (struct commit_slab * s ,
536
+ const struct commit * c )
521
537
{
522
- if (s -> alloc <= c -> index ) {
523
- int new_alloc = alloc_nr (s -> alloc );
524
- if (new_alloc <= c -> index )
525
- new_alloc = c -> index + 1 ;
526
-
527
- s -> buf = xrealloc (s -> buf , new_alloc * sizeof (* s -> buf ));
528
- memset (s -> buf + s -> alloc , 0 , new_alloc - s -> alloc );
529
- s -> alloc = new_alloc ;
538
+ int nth_piece , nth_slot ;
539
+
540
+ nth_piece = c -> index / s -> piece_size ;
541
+ nth_slot = c -> index % s -> piece_size ;
542
+
543
+ if (s -> piece_count <= nth_piece ) {
544
+ int i ;
545
+
546
+ s -> piece = xrealloc (s -> piece , (nth_piece + 1 ) * sizeof (s -> piece ));
547
+ for (i = s -> piece_count ; i <= nth_piece ; i ++ )
548
+ s -> piece [i ] = NULL ;
549
+ s -> piece_count = nth_piece + 1 ;
530
550
}
531
- return s -> buf + c -> index ;
551
+ if (!s -> piece [nth_piece ])
552
+ s -> piece [nth_piece ] = xcalloc (s -> piece_size , sizeof (* * s -> piece ));
553
+ return & s -> piece [nth_piece ][nth_slot ];
532
554
}
533
555
534
556
/*
@@ -550,15 +572,15 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
550
572
/* Mark them and clear the indegree */
551
573
for (next = orig ; next ; next = next -> next ) {
552
574
struct commit * commit = next -> item ;
553
- * slab_at (& indegree , commit ) = 1 ;
575
+ slab_at (& indegree , commit )-> buf = 1 ;
554
576
}
555
577
556
578
/* update the indegree */
557
579
for (next = orig ; next ; next = next -> next ) {
558
580
struct commit_list * parents = next -> item -> parents ;
559
581
while (parents ) {
560
582
struct commit * parent = parents -> item ;
561
- int * pi = slab_at (& indegree , parent );
583
+ int * pi = & slab_at (& indegree , parent )-> buf ;
562
584
563
585
if (* pi )
564
586
(* pi )++ ;
@@ -578,7 +600,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
578
600
for (next = orig ; next ; next = next -> next ) {
579
601
struct commit * commit = next -> item ;
580
602
581
- if (* slab_at (& indegree , commit ) == 1 )
603
+ if (slab_at (& indegree , commit )-> buf == 1 )
582
604
insert = & commit_list_insert (commit , insert )-> next ;
583
605
}
584
606
@@ -599,7 +621,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
599
621
commit = work_item -> item ;
600
622
for (parents = commit -> parents ; parents ; parents = parents -> next ) {
601
623
struct commit * parent = parents -> item ;
602
- int * pi = slab_at (& indegree , parent );
624
+ int * pi = & slab_at (& indegree , parent )-> buf ;
603
625
604
626
if (!* pi )
605
627
continue ;
@@ -620,7 +642,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
620
642
* work_item is a commit all of whose children
621
643
* have already been emitted. we can emit it now.
622
644
*/
623
- * slab_at (& indegree , commit ) = 0 ;
645
+ slab_at (& indegree , commit )-> buf = 0 ;
624
646
* pptr = work_item ;
625
647
pptr = & work_item -> next ;
626
648
}
0 commit comments